xref: /kvm-unit-tests/x86/tsc_adjust.c (revision 39ac3f8494beb048a121f44bf626275b18c66da5)
1 #include "libcflat.h"
2 #include "processor.h"
3 
4 #define IA32_TSC_ADJUST 0x3b
5 
6 int main()
7 {
8 	u64 t1, t2, t3, t4, t5;
9 	u64 est_delta_time;
10 
11 	if (cpuid(7).b & (1 << 1)) { // IA32_TSC_ADJUST Feature is enabled?
12 		report("IA32_TSC_ADJUST msr initialization",
13 				rdmsr(IA32_TSC_ADJUST) == 0x0);
14 		t3 = 100000000000ull;
15 		t1 = rdtsc();
16 		wrmsr(IA32_TSC_ADJUST, t3);
17 		t2 = rdtsc();
18 		report("IA32_TSC_ADJUST msr read / write",
19 				rdmsr(IA32_TSC_ADJUST) == t3);
20 		report("TSC adjustment for IA32_TSC_ADJUST value",
21 				(t2 - t1) >= t3);
22 		t3 = 0x0;
23 		wrmsr(IA32_TSC_ADJUST, t3);
24 		report("IA32_TSC_ADJUST msr read / write",
25 				rdmsr(IA32_TSC_ADJUST) == t3);
26 		t4 = 100000000000ull;
27 		t1 = rdtsc();
28 		wrtsc(t4);
29 		t2 = rdtsc();
30 		t5 = rdmsr(IA32_TSC_ADJUST);
31 		// est of time between reading tsc and writing tsc,
32 		// (based on IA32_TSC_ADJUST msr value) should be small
33 		est_delta_time = t4 - t5 - t1;
34 		// arbitray 2x latency (wrtsc->rdtsc) threshold
35 		report("IA32_TSC_ADJUST msr adjustment on tsc write",
36 				est_delta_time <= (2 * (t2 - t4)));
37 	}
38 	else {
39 		report("IA32_TSC_ADJUST feature not enabled", true);
40 	}
41 	return report_summary();
42 }
43