This test aims to verify that when entering a guest in HLT activity state but with a pending interrupt in RVI, the guest is in fact not halted and an interrupt is indeed injected. For more information, see commit message of kernel patch "KVM: nVMX: Wake blocked vCPU in guest-mode if pending interrupt in virtual APICv". Reviewed-by: Nikita Leshenko <nikita.leshchenko@xxxxxxxxxx> Reviewed-by: Darren Kenny <darren.kenny@xxxxxxxxxx> Signed-off-by: Liran Alon <liran.alon@xxxxxxxxxx> --- x86/unittests.cfg | 7 +++++++ x86/vmx_tests.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/x86/unittests.cfg b/x86/unittests.cfg index 17733154eeec..40a8423d997f 100644 --- a/x86/unittests.cfg +++ b/x86/unittests.cfg @@ -579,6 +579,13 @@ extra_params = -cpu host,+vmx -m 2048 -append vmx_eoi_bitmap_ioapic_scan_test arch = x86_64 groups = vmx +[vmx_hlt_with_rvi_test] +file = vmx.flat +extra_params = -cpu host,+vmx -m 2048 -append vmx_hlt_with_rvi_test +arch = x86_64 +groups = vmx +timeout = 10 + [vmx_apic_passthrough] file = vmx.flat smp = 2 diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index 835ae1e1e8b4..9296a8a7143a 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -4683,6 +4683,47 @@ static void vmx_eoi_bitmap_ioapic_scan_test(void) report(__func__, 1); } +#define HLT_WITH_RVI_VECTOR (0xf1) + +bool vmx_hlt_with_rvi_guest_isr_fired; +static void vmx_hlt_with_rvi_guest_isr(isr_regs_t *regs) +{ + vmx_hlt_with_rvi_guest_isr_fired = true; + eoi(); +} + +static void vmx_hlt_with_rvi_guest(void) +{ + handle_irq(HLT_WITH_RVI_VECTOR, vmx_hlt_with_rvi_guest_isr); + + irq_enable(); + asm volatile ("nop"); + + vmcall(); +} + +static void vmx_hlt_with_rvi_test(void) +{ + if (!cpu_has_apicv()) { + report_skip(__func__); + return; + } + + enable_vid(); + + vmx_hlt_with_rvi_guest_isr_fired = false; + test_set_guest(vmx_hlt_with_rvi_guest); + + enter_guest(); + skip_exit_vmcall(); + + vmcs_write(GUEST_ACTV_STATE, ACTV_HLT); + vmcs_write(GUEST_INT_STATUS, HLT_WITH_RVI_VECTOR); + enter_guest(); + + report("Interrupt raised in guest", vmx_hlt_with_rvi_guest_isr_fired); +} + static void set_irq_line_thread(void *data) { /* Wait until other CPU entered L2 */ @@ -5130,6 +5171,7 @@ struct vmx_test vmx_tests[] = { TEST(vmentry_movss_shadow_test), /* APICv tests */ TEST(vmx_eoi_bitmap_ioapic_scan_test), + TEST(vmx_hlt_with_rvi_test), /* APIC pass-through tests */ TEST(vmx_apic_passthrough_test), TEST(vmx_apic_passthrough_thread_test), -- 2.16.1