xref: /kvm-unit-tests/x86/tsc_adjust.c (revision 164c04b4742fab042a086050c269f00aefeba17e)
15fecf5d8SWill Auld #include "libcflat.h"
25fecf5d8SWill Auld #include "processor.h"
35fecf5d8SWill Auld 
main(void)47db17e21SThomas Huth int main(void)
55fecf5d8SWill Auld {
65fecf5d8SWill Auld 	u64 t1, t2, t3, t4, t5;
75fecf5d8SWill Auld 
8*164c04b4SJim Mattson 	if (!this_cpu_has(X86_FEATURE_TSC_ADJUST)) {
9*164c04b4SJim Mattson 		report_skip("MSR_IA32_TSC_ADJUST feature not enabled");
10*164c04b4SJim Mattson 		return report_summary();
11*164c04b4SJim Mattson 	}
12*164c04b4SJim Mattson 
13a299895bSThomas Huth 	report(rdmsr(MSR_IA32_TSC_ADJUST) == 0x0,
14a299895bSThomas Huth 	       "MSR_IA32_TSC_ADJUST msr initialization");
155fecf5d8SWill Auld 	t3 = 100000000000ull;
165fecf5d8SWill Auld 	t1 = rdtsc();
172352e986SPaolo Bonzini 	wrmsr(MSR_IA32_TSC_ADJUST, t3);
185fecf5d8SWill Auld 	t2 = rdtsc();
19a299895bSThomas Huth 	report(rdmsr(MSR_IA32_TSC_ADJUST) == t3,
20a299895bSThomas Huth 	       "MSR_IA32_TSC_ADJUST msr read / write");
21a299895bSThomas Huth 	report((t2 - t1) >= t3,
22a299895bSThomas Huth 	       "TSC adjustment for MSR_IA32_TSC_ADJUST value");
235fecf5d8SWill Auld 	t3 = 0x0;
242352e986SPaolo Bonzini 	wrmsr(MSR_IA32_TSC_ADJUST, t3);
25a299895bSThomas Huth 	report(rdmsr(MSR_IA32_TSC_ADJUST) == t3,
26a299895bSThomas Huth 	       "MSR_IA32_TSC_ADJUST msr read / write");
275fecf5d8SWill Auld 	t4 = 100000000000ull;
285fecf5d8SWill Auld 	t1 = rdtsc();
295fecf5d8SWill Auld 	wrtsc(t4);
305fecf5d8SWill Auld 	t2 = rdtsc();
312352e986SPaolo Bonzini 	t5 = rdmsr(MSR_IA32_TSC_ADJUST);
32*164c04b4SJim Mattson 	report(t1 <= t4 - t5, "Internal TSC advances across write to IA32_TSC");
33d3f3e215SJim Mattson 	report(t2 >= t4, "IA32_TSC advances after write to IA32_TSC");
34*164c04b4SJim Mattson 
351ce2224dSAndrew Jones 	return report_summary();
365fecf5d8SWill Auld }
37