This places the preemption timer optimization at ~1200 clock cycles compared to hrtimers (5600 vs. 6800 clock cycles) on a Haswell Xeon processor. Avoiding the preemption timer vmexit for immediate LAPIC timer expiration ("tscdeadline_immed") also saves ~1200 clock cycles (2500 vs. 3700). Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- x86/unittests.cfg | 6 ++++++ x86/vmexit.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 6455ee5..bdc0080 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -98,6 +98,12 @@ file = vmexit.flat extra_params = -append 'ple_round_robin' groups = vmexit +[vmexit_tscdeadline] +file = vmexit.flat +extra_params = -append 'tscdeadline' +groups = vmexit +extra_params = -cpu qemu64,+x2apic,+tsc-deadline + [access] file = access.flat arch = x86_64 diff --git a/x86/vmexit.c b/x86/vmexit.c index 543c477..42ab7db 100644 --- a/x86/vmexit.c +++ b/x86/vmexit.c @@ -387,6 +387,32 @@ static bool pci_io_next(struct test *test) return ret; } +static int has_tscdeadline(void) +{ + uint32_t lvtt; + + if (cpuid(1).c & (1 << 24)) { + lvtt = APIC_LVT_TIMER_TSCDEADLINE | IPI_TEST_VECTOR; + apic_write(APIC_LVTT, lvtt); + return 1; + } else { + return 0; + } +} + +static void tscdeadline_immed(void) +{ + wrmsr(MSR_IA32_TSCDEADLINE, rdtsc()); + asm volatile("nop"); +} + +static void tscdeadline(void) +{ + x = 0; + wrmsr(MSR_IA32_TSCDEADLINE, rdtsc()+3000); + while (x == 0) barrier(); +} + static struct test tests[] = { { cpuid_test, "cpuid", .parallel = 1, }, { vmcall, "vmcall", .parallel = 1, }, @@ -399,6 +425,8 @@ static struct test tests[] = { { inl_nop_kernel, "inl_from_kernel", .parallel = 1 }, { outl_elcr_kernel, "outl_to_kernel", .parallel = 1 }, { mov_dr, "mov_dr", .parallel = 1 }, + { tscdeadline_immed, "tscdeadline_immed", has_tscdeadline, .parallel = 1, }, + { tscdeadline, "tscdeadline", has_tscdeadline, .parallel = 1, }, { self_ipi_sti_nop, "self_ipi_sti_nop", .parallel = 0, }, { self_ipi_sti_hlt, "self_ipi_sti_hlt", .parallel = 0, }, { self_ipi_tpr, "self_ipi_tpr", .parallel = 0, }, -- 1.8.3.1