xref: /kvm-unit-tests/x86/tsc.c (revision 2ce7a6c75a338e672efe14ee968742184e19759c)
17d36db35SAvi Kivity #include "libcflat.h"
20d7251beSJason Wang #include "processor.h"
37d36db35SAvi Kivity 
4867f820dSPaolo Bonzini #define CPUID_80000001_EDX_RDTSCP	    (1 << 27)
5867f820dSPaolo Bonzini int check_cpuid_80000001_edx(unsigned int bit)
6867f820dSPaolo Bonzini {
7867f820dSPaolo Bonzini     return (cpuid(0x80000001).d & bit) != 0;
8867f820dSPaolo Bonzini }
9867f820dSPaolo Bonzini 
10867f820dSPaolo Bonzini 
117d36db35SAvi Kivity void test_wrtsc(u64 t1)
127d36db35SAvi Kivity {
137d36db35SAvi Kivity 	u64 t2;
147d36db35SAvi Kivity 
157d36db35SAvi Kivity 	wrtsc(t1);
167d36db35SAvi Kivity 	t2 = rdtsc();
17b006d7ebSAndrew Jones 	printf("rdtsc after wrtsc(%" PRId64 "): %" PRId64 "\n", t1, t2);
187d36db35SAvi Kivity }
197d36db35SAvi Kivity 
20867f820dSPaolo Bonzini void test_rdtscp(u64 aux)
21867f820dSPaolo Bonzini {
22867f820dSPaolo Bonzini        u32 ecx;
23867f820dSPaolo Bonzini 
24867f820dSPaolo Bonzini        wrmsr(MSR_TSC_AUX, aux);
25867f820dSPaolo Bonzini        rdtscp(&ecx);
26*2ce7a6c7SRadim Krčmář        report("Test RDTSCP %" PRIu64, ecx == aux, aux);
27867f820dSPaolo Bonzini }
28867f820dSPaolo Bonzini 
297d36db35SAvi Kivity int main()
307d36db35SAvi Kivity {
317d36db35SAvi Kivity 	u64 t1, t2;
327d36db35SAvi Kivity 
337d36db35SAvi Kivity 	t1 = rdtsc();
347d36db35SAvi Kivity 	t2 = rdtsc();
35b006d7ebSAndrew Jones 	printf("rdtsc latency %u\n", (unsigned)(t2 - t1));
367d36db35SAvi Kivity 
377d36db35SAvi Kivity 	test_wrtsc(0);
387d36db35SAvi Kivity 	test_wrtsc(100000000000ull);
39867f820dSPaolo Bonzini 
40867f820dSPaolo Bonzini 	if (check_cpuid_80000001_edx(CPUID_80000001_EDX_RDTSCP)) {
41867f820dSPaolo Bonzini 		test_rdtscp(0);
42867f820dSPaolo Bonzini 		test_rdtscp(10);
43867f820dSPaolo Bonzini 		test_rdtscp(0x100);
44867f820dSPaolo Bonzini 	} else
45867f820dSPaolo Bonzini 		printf("rdtscp not supported\n");
4632b9603cSRadim Krčmář 	return report_summary();
477d36db35SAvi Kivity }
48