xref: /kvm-unit-tests/x86/tsc.c (revision db4898e8f67c57369499ea16c605aa3390da367a)
17d36db35SAvi Kivity #include "libcflat.h"
20d7251beSJason Wang #include "processor.h"
37d36db35SAvi Kivity 
4867f820dSPaolo Bonzini #define CPUID_80000001_EDX_RDTSCP	    (1 << 27)
5*db4898e8SThomas Huth static int check_cpuid_80000001_edx(unsigned int bit)
6867f820dSPaolo Bonzini {
7867f820dSPaolo Bonzini 	return (cpuid(0x80000001).d & bit) != 0;
8867f820dSPaolo Bonzini }
9867f820dSPaolo Bonzini 
1010631a5bSPaolo Bonzini #define CPUID_7_0_ECX_RDPID		    (1 << 22)
1110631a5bSPaolo Bonzini int check_cpuid_7_0_ecx(unsigned int bit)
1210631a5bSPaolo Bonzini {
1310631a5bSPaolo Bonzini     return (cpuid_indexed(7, 0).c & bit) != 0;
1410631a5bSPaolo Bonzini }
15867f820dSPaolo Bonzini 
16*db4898e8SThomas Huth static 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 
25*db4898e8SThomas Huth static 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 
3410631a5bSPaolo Bonzini void test_rdpid(u64 aux)
3510631a5bSPaolo Bonzini {
3610631a5bSPaolo Bonzini        u32 eax;
3710631a5bSPaolo Bonzini 
3810631a5bSPaolo Bonzini        wrmsr(MSR_TSC_AUX, aux);
3910631a5bSPaolo Bonzini        asm (".byte 0xf3, 0x0f, 0xc7, 0xf8" : "=a" (eax));
4010631a5bSPaolo Bonzini        report("Test rdpid %%eax %d", eax == aux, aux);
4110631a5bSPaolo Bonzini }
4210631a5bSPaolo Bonzini 
437db17e21SThomas Huth int main(void)
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");
6010631a5bSPaolo Bonzini 
6110631a5bSPaolo Bonzini 	if (check_cpuid_7_0_ecx(CPUID_7_0_ECX_RDPID)) {
6210631a5bSPaolo Bonzini 		test_rdpid(0);
6310631a5bSPaolo Bonzini 		test_rdpid(10);
6410631a5bSPaolo Bonzini 		test_rdpid(0x100);
6510631a5bSPaolo Bonzini 	} else
6610631a5bSPaolo Bonzini 		printf("rdpid not supported\n");
6732b9603cSRadim Krčmář 	return report_summary();
687d36db35SAvi Kivity }
69