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