15fecf5d8SWill Auld #include "libcflat.h" 25fecf5d8SWill Auld #include "processor.h" 35fecf5d8SWill Auld 45fecf5d8SWill Auld int main() 55fecf5d8SWill Auld { 65fecf5d8SWill Auld u64 t1, t2, t3, t4, t5; 75fecf5d8SWill Auld u64 est_delta_time; 85fecf5d8SWill Auld 9*2352e986SPaolo Bonzini if (cpuid(7).b & (1 << 1)) { // MSR_IA32_TSC_ADJUST Feature is enabled? 10*2352e986SPaolo Bonzini report("MSR_IA32_TSC_ADJUST msr initialization", 11*2352e986SPaolo Bonzini rdmsr(MSR_IA32_TSC_ADJUST) == 0x0); 125fecf5d8SWill Auld t3 = 100000000000ull; 135fecf5d8SWill Auld t1 = rdtsc(); 14*2352e986SPaolo Bonzini wrmsr(MSR_IA32_TSC_ADJUST, t3); 155fecf5d8SWill Auld t2 = rdtsc(); 16*2352e986SPaolo Bonzini report("MSR_IA32_TSC_ADJUST msr read / write", 17*2352e986SPaolo Bonzini rdmsr(MSR_IA32_TSC_ADJUST) == t3); 18*2352e986SPaolo Bonzini report("TSC adjustment for MSR_IA32_TSC_ADJUST value", 191ce2224dSAndrew Jones (t2 - t1) >= t3); 205fecf5d8SWill Auld t3 = 0x0; 21*2352e986SPaolo Bonzini wrmsr(MSR_IA32_TSC_ADJUST, t3); 22*2352e986SPaolo Bonzini report("MSR_IA32_TSC_ADJUST msr read / write", 23*2352e986SPaolo Bonzini rdmsr(MSR_IA32_TSC_ADJUST) == t3); 245fecf5d8SWill Auld t4 = 100000000000ull; 255fecf5d8SWill Auld t1 = rdtsc(); 265fecf5d8SWill Auld wrtsc(t4); 275fecf5d8SWill Auld t2 = rdtsc(); 28*2352e986SPaolo Bonzini t5 = rdmsr(MSR_IA32_TSC_ADJUST); 295fecf5d8SWill Auld // est of time between reading tsc and writing tsc, 30*2352e986SPaolo Bonzini // (based on MSR_IA32_TSC_ADJUST msr value) should be small 315fecf5d8SWill Auld est_delta_time = t4 - t5 - t1; 325fecf5d8SWill Auld // arbitray 2x latency (wrtsc->rdtsc) threshold 33*2352e986SPaolo Bonzini report("MSR_IA32_TSC_ADJUST msr adjustment on tsc write", 341ce2224dSAndrew Jones est_delta_time <= (2 * (t2 - t4))); 355fecf5d8SWill Auld } 365fecf5d8SWill Auld else { 37*2352e986SPaolo Bonzini report("MSR_IA32_TSC_ADJUST feature not enabled", true); 385fecf5d8SWill Auld } 391ce2224dSAndrew Jones return report_summary(); 405fecf5d8SWill Auld } 41