xref: /kvm-unit-tests/x86/tsc.c (revision 10631a5bebd8bafe87646b73afd24125cb77abef)
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 
10*10631a5bSPaolo Bonzini #define CPUID_7_0_ECX_RDPID		    (1 << 22)
11*10631a5bSPaolo Bonzini int check_cpuid_7_0_ecx(unsigned int bit)
12*10631a5bSPaolo Bonzini {
13*10631a5bSPaolo Bonzini     return (cpuid_indexed(7, 0).c & bit) != 0;
14*10631a5bSPaolo Bonzini }
15867f820dSPaolo Bonzini 
167d36db35SAvi Kivity void test_wrtsc(u64 t1)
177d36db35SAvi Kivity {
187d36db35SAvi Kivity 	u64 t2;
197d36db35SAvi Kivity 
207d36db35SAvi Kivity 	wrtsc(t1);
217d36db35SAvi Kivity 	t2 = rdtsc();
22b006d7ebSAndrew Jones 	printf("rdtsc after wrtsc(%" PRId64 "): %" PRId64 "\n", t1, t2);
237d36db35SAvi Kivity }
247d36db35SAvi Kivity 
25867f820dSPaolo Bonzini void test_rdtscp(u64 aux)
26867f820dSPaolo Bonzini {
27867f820dSPaolo Bonzini        u32 ecx;
28867f820dSPaolo Bonzini 
29867f820dSPaolo Bonzini        wrmsr(MSR_TSC_AUX, aux);
30867f820dSPaolo Bonzini        rdtscp(&ecx);
312ce7a6c7SRadim Krčmář        report("Test RDTSCP %" PRIu64, ecx == aux, aux);
32867f820dSPaolo Bonzini }
33867f820dSPaolo Bonzini 
34*10631a5bSPaolo Bonzini void test_rdpid(u64 aux)
35*10631a5bSPaolo Bonzini {
36*10631a5bSPaolo Bonzini        u32 eax;
37*10631a5bSPaolo Bonzini 
38*10631a5bSPaolo Bonzini        wrmsr(MSR_TSC_AUX, aux);
39*10631a5bSPaolo Bonzini        asm (".byte 0xf3, 0x0f, 0xc7, 0xf8" : "=a" (eax));
40*10631a5bSPaolo Bonzini        report("Test rdpid %%eax %d", eax == aux, aux);
41*10631a5bSPaolo Bonzini }
42*10631a5bSPaolo Bonzini 
437d36db35SAvi Kivity int main()
447d36db35SAvi Kivity {
457d36db35SAvi Kivity 	u64 t1, t2;
467d36db35SAvi Kivity 
477d36db35SAvi Kivity 	t1 = rdtsc();
487d36db35SAvi Kivity 	t2 = rdtsc();
49b006d7ebSAndrew Jones 	printf("rdtsc latency %u\n", (unsigned)(t2 - t1));
507d36db35SAvi Kivity 
517d36db35SAvi Kivity 	test_wrtsc(0);
527d36db35SAvi Kivity 	test_wrtsc(100000000000ull);
53867f820dSPaolo Bonzini 
54867f820dSPaolo Bonzini 	if (check_cpuid_80000001_edx(CPUID_80000001_EDX_RDTSCP)) {
55867f820dSPaolo Bonzini 		test_rdtscp(0);
56867f820dSPaolo Bonzini 		test_rdtscp(10);
57867f820dSPaolo Bonzini 		test_rdtscp(0x100);
58867f820dSPaolo Bonzini 	} else
59867f820dSPaolo Bonzini 		printf("rdtscp not supported\n");
60*10631a5bSPaolo Bonzini 
61*10631a5bSPaolo Bonzini 	if (check_cpuid_7_0_ecx(CPUID_7_0_ECX_RDPID)) {
62*10631a5bSPaolo Bonzini 		test_rdpid(0);
63*10631a5bSPaolo Bonzini 		test_rdpid(10);
64*10631a5bSPaolo Bonzini 		test_rdpid(0x100);
65*10631a5bSPaolo Bonzini 	} else
66*10631a5bSPaolo Bonzini 		printf("rdpid not supported\n");
6732b9603cSRadim Krčmář 	return report_summary();
687d36db35SAvi Kivity }
69