1d482c497SMarcelo Tosatti /* 2d482c497SMarcelo Tosatti * qemu command line | grep latency | cut -f 2 -d ":" > latency 3d482c497SMarcelo Tosatti * 4d482c497SMarcelo Tosatti * In octave: 5d482c497SMarcelo Tosatti * load latency 66d7f1387SMarcelo Tosatti * min(latency) 76d7f1387SMarcelo Tosatti * max(latency) 86d7f1387SMarcelo Tosatti * mean(latency) 9d482c497SMarcelo Tosatti * hist(latency, 50) 10d482c497SMarcelo Tosatti */ 11d482c497SMarcelo Tosatti 1224ce2536SMarcelo Tosatti /* 1324ce2536SMarcelo Tosatti * for host tracing of breakmax option: 1424ce2536SMarcelo Tosatti * 1524ce2536SMarcelo Tosatti * # cd /sys/kernel/debug/tracing/ 1624ce2536SMarcelo Tosatti * # echo x86-tsc > trace_clock 1724ce2536SMarcelo Tosatti * # echo "kvm_exit kvm_entry kvm_msr" > set_event 1824ce2536SMarcelo Tosatti * # echo "sched_switch $extratracepoints" >> set_event 1924ce2536SMarcelo Tosatti * # echo apic_timer_fn > set_ftrace_filter 2024ce2536SMarcelo Tosatti * # echo "function" > current_tracer 2124ce2536SMarcelo Tosatti */ 2224ce2536SMarcelo Tosatti 23d482c497SMarcelo Tosatti #include "libcflat.h" 24d482c497SMarcelo Tosatti #include "apic.h" 25d482c497SMarcelo Tosatti #include "vm.h" 26d482c497SMarcelo Tosatti #include "smp.h" 27d482c497SMarcelo Tosatti #include "desc.h" 28d482c497SMarcelo Tosatti #include "isr.h" 29d482c497SMarcelo Tosatti #include "msr.h" 30d482c497SMarcelo Tosatti 31d482c497SMarcelo Tosatti static void test_lapic_existence(void) 32d482c497SMarcelo Tosatti { 33d482c497SMarcelo Tosatti u32 lvr; 34d482c497SMarcelo Tosatti 35d482c497SMarcelo Tosatti lvr = apic_read(APIC_LVR); 36d482c497SMarcelo Tosatti printf("apic version: %x\n", lvr); 37*a299895bSThomas Huth report((u16)lvr == 0x14, "apic existence"); 38d482c497SMarcelo Tosatti } 39d482c497SMarcelo Tosatti 40d482c497SMarcelo Tosatti #define TSC_DEADLINE_TIMER_VECTOR 0xef 41d482c497SMarcelo Tosatti 42d482c497SMarcelo Tosatti static int tdt_count; 43d482c497SMarcelo Tosatti u64 exptime; 44d482c497SMarcelo Tosatti int delta; 45d482c497SMarcelo Tosatti #define TABLE_SIZE 10000 46d482c497SMarcelo Tosatti u64 table[TABLE_SIZE]; 47d482c497SMarcelo Tosatti volatile int table_idx; 4824ce2536SMarcelo Tosatti volatile int hitmax = 0; 4924ce2536SMarcelo Tosatti int breakmax = 0; 50d482c497SMarcelo Tosatti 51d482c497SMarcelo Tosatti static void tsc_deadline_timer_isr(isr_regs_t *regs) 52d482c497SMarcelo Tosatti { 53d482c497SMarcelo Tosatti u64 now = rdtsc(); 54d482c497SMarcelo Tosatti ++tdt_count; 55d482c497SMarcelo Tosatti 56d482c497SMarcelo Tosatti if (table_idx < TABLE_SIZE && tdt_count > 1) 57d482c497SMarcelo Tosatti table[table_idx++] = now - exptime; 58d482c497SMarcelo Tosatti 5924ce2536SMarcelo Tosatti if (breakmax && tdt_count > 1 && (now - exptime) > breakmax) { 6024ce2536SMarcelo Tosatti hitmax = 1; 6124ce2536SMarcelo Tosatti apic_write(APIC_EOI, 0); 6224ce2536SMarcelo Tosatti return; 6324ce2536SMarcelo Tosatti } 6424ce2536SMarcelo Tosatti 65d482c497SMarcelo Tosatti exptime = now+delta; 66d482c497SMarcelo Tosatti wrmsr(MSR_IA32_TSCDEADLINE, now+delta); 67d482c497SMarcelo Tosatti apic_write(APIC_EOI, 0); 68d482c497SMarcelo Tosatti } 69d482c497SMarcelo Tosatti 70d482c497SMarcelo Tosatti static void start_tsc_deadline_timer(void) 71d482c497SMarcelo Tosatti { 72d482c497SMarcelo Tosatti handle_irq(TSC_DEADLINE_TIMER_VECTOR, tsc_deadline_timer_isr); 73d482c497SMarcelo Tosatti irq_enable(); 74d482c497SMarcelo Tosatti 75d482c497SMarcelo Tosatti wrmsr(MSR_IA32_TSCDEADLINE, rdmsr(MSR_IA32_TSC)+delta); 76d482c497SMarcelo Tosatti asm volatile ("nop"); 77d482c497SMarcelo Tosatti } 78d482c497SMarcelo Tosatti 79d482c497SMarcelo Tosatti static int enable_tsc_deadline_timer(void) 80d482c497SMarcelo Tosatti { 81d482c497SMarcelo Tosatti uint32_t lvtt; 82d482c497SMarcelo Tosatti 83badc98caSKrish Sadhukhan if (this_cpu_has(X86_FEATURE_TSC_DEADLINE_TIMER)) { 849111ccabSRadim Krčmář lvtt = APIC_LVT_TIMER_TSCDEADLINE | TSC_DEADLINE_TIMER_VECTOR; 85d482c497SMarcelo Tosatti apic_write(APIC_LVTT, lvtt); 86d482c497SMarcelo Tosatti start_tsc_deadline_timer(); 87d482c497SMarcelo Tosatti return 1; 88d482c497SMarcelo Tosatti } else { 89d482c497SMarcelo Tosatti return 0; 90d482c497SMarcelo Tosatti } 91d482c497SMarcelo Tosatti } 92d482c497SMarcelo Tosatti 93d482c497SMarcelo Tosatti static void test_tsc_deadline_timer(void) 94d482c497SMarcelo Tosatti { 95d482c497SMarcelo Tosatti if(enable_tsc_deadline_timer()) { 96d482c497SMarcelo Tosatti printf("tsc deadline timer enabled\n"); 97d482c497SMarcelo Tosatti } else { 98a2b7c499SAndrew Jones printf("tsc deadline timer not detected, aborting\n"); 99a2b7c499SAndrew Jones abort(); 100d482c497SMarcelo Tosatti } 101d482c497SMarcelo Tosatti } 102d482c497SMarcelo Tosatti 1033dea272fSPaolo Bonzini int main(int argc, char **argv) 104d482c497SMarcelo Tosatti { 1053dea272fSPaolo Bonzini int i, size; 106d482c497SMarcelo Tosatti 107d482c497SMarcelo Tosatti setup_vm(); 108d482c497SMarcelo Tosatti smp_init(); 109d482c497SMarcelo Tosatti 110d482c497SMarcelo Tosatti test_lapic_existence(); 111d482c497SMarcelo Tosatti 112d482c497SMarcelo Tosatti mask_pic_interrupts(); 113d482c497SMarcelo Tosatti 1143dea272fSPaolo Bonzini delta = argc <= 1 ? 200000 : atol(argv[1]); 11524ce2536SMarcelo Tosatti size = argc <= 2 ? TABLE_SIZE : atol(argv[2]); 11624ce2536SMarcelo Tosatti breakmax = argc <= 3 ? 0 : atol(argv[3]); 11724ce2536SMarcelo Tosatti printf("breakmax=%d\n", breakmax); 118d482c497SMarcelo Tosatti test_tsc_deadline_timer(); 119d482c497SMarcelo Tosatti irq_enable(); 120d482c497SMarcelo Tosatti 1212130fd41SPeter Xu /* The condition might have triggered already, so check before HLT. */ 1222130fd41SPeter Xu while (!hitmax && table_idx < size) 123d482c497SMarcelo Tosatti asm volatile("hlt"); 124d482c497SMarcelo Tosatti 12524ce2536SMarcelo Tosatti for (i = 0; i < table_idx; i++) { 12624ce2536SMarcelo Tosatti if (hitmax && i == table_idx-1) 12724ce2536SMarcelo Tosatti printf("hit max: %d < ", breakmax); 128b006d7ebSAndrew Jones printf("latency: %" PRId64 "\n", table[i]); 12924ce2536SMarcelo Tosatti } 130d482c497SMarcelo Tosatti 131d482c497SMarcelo Tosatti return report_summary(); 132d482c497SMarcelo Tosatti } 133