xref: /kvm-unit-tests/x86/tsc_adjust.c (revision d3f3e2151bb3ee3e41f76fd5db5ad182454bf3d7)
15fecf5d8SWill Auld #include "libcflat.h"
25fecf5d8SWill Auld #include "processor.h"
35fecf5d8SWill Auld 
47db17e21SThomas Huth int main(void)
55fecf5d8SWill Auld {
65fecf5d8SWill Auld 	u64 t1, t2, t3, t4, t5;
75fecf5d8SWill Auld 
8badc98caSKrish Sadhukhan 	if (this_cpu_has(X86_FEATURE_TSC_ADJUST)) { // MSR_IA32_TSC_ADJUST Feature is enabled?
9a299895bSThomas Huth 		report(rdmsr(MSR_IA32_TSC_ADJUST) == 0x0,
10a299895bSThomas Huth 		       "MSR_IA32_TSC_ADJUST msr initialization");
115fecf5d8SWill Auld 		t3 = 100000000000ull;
125fecf5d8SWill Auld 		t1 = rdtsc();
132352e986SPaolo Bonzini 		wrmsr(MSR_IA32_TSC_ADJUST, t3);
145fecf5d8SWill Auld 		t2 = rdtsc();
15a299895bSThomas Huth 		report(rdmsr(MSR_IA32_TSC_ADJUST) == t3,
16a299895bSThomas Huth 		       "MSR_IA32_TSC_ADJUST msr read / write");
17a299895bSThomas Huth 		report((t2 - t1) >= t3,
18a299895bSThomas Huth 		       "TSC adjustment for MSR_IA32_TSC_ADJUST value");
195fecf5d8SWill Auld 		t3 = 0x0;
202352e986SPaolo Bonzini 		wrmsr(MSR_IA32_TSC_ADJUST, t3);
21a299895bSThomas Huth 		report(rdmsr(MSR_IA32_TSC_ADJUST) == t3,
22a299895bSThomas Huth 		       "MSR_IA32_TSC_ADJUST msr read / write");
235fecf5d8SWill Auld 		t4 = 100000000000ull;
245fecf5d8SWill Auld 		t1 = rdtsc();
255fecf5d8SWill Auld 		wrtsc(t4);
265fecf5d8SWill Auld 		t2 = rdtsc();
272352e986SPaolo Bonzini 		t5 = rdmsr(MSR_IA32_TSC_ADJUST);
28*d3f3e215SJim Mattson 		report(t1 <= t4 - t5,
29*d3f3e215SJim Mattson 		       "Internal TSC advances across write to IA32_TSC");
30*d3f3e215SJim Mattson 		report(t2 >= t4, "IA32_TSC advances after write to IA32_TSC");
315fecf5d8SWill Auld 	}
325fecf5d8SWill Auld 	else {
335c3582f0SJanis Schoetterl-Glausch 		report_pass("MSR_IA32_TSC_ADJUST feature not enabled");
345fecf5d8SWill Auld 	}
351ce2224dSAndrew Jones 	return report_summary();
365fecf5d8SWill Auld }
37