From: "Marc Orr (Google)" <marc.orr@xxxxxxxxx> Extend the VMX "virtual-interrupt delivery test", vmx_basic_vid_test, to verify that virtual-interrupt delivery is triggered by a self-IPI in L2. Signed-off-by: Marc Orr (Google) <marc.orr@xxxxxxxxx> Co-developed-by: Jim Mattson <jmattson@xxxxxxxxxx> Signed-off-by: Jim Mattson <jmattson@xxxxxxxxxx> --- x86/vmx_tests.c | 35 +++++++++++++++++++++++++---------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c index ce480431bf58..a26f77e92f72 100644 --- a/x86/vmx_tests.c +++ b/x86/vmx_tests.c @@ -10720,6 +10720,7 @@ enum Vid_op { VID_OP_SET_ISR, VID_OP_NOP, VID_OP_SET_CR8, + VID_OP_SELF_IPI, VID_OP_TERMINATE, }; @@ -10779,6 +10780,9 @@ static void vmx_basic_vid_test_guest(void) case VID_OP_SET_CR8: write_cr8(nr); break; + case VID_OP_SELF_IPI: + vmx_x2apic_write(APIC_SELF_IPI, nr); + break; default: break; } @@ -10817,7 +10821,7 @@ static void set_isrs_for_vmx_basic_vid_test(void) * tpr_virt: If true, then test VID during TPR virtualization. Otherwise, * test VID during VM-entry. */ -static void test_basic_vid(u8 nr, u8 tpr, bool tpr_virt, u32 isr_exec_cnt_want, +static void test_basic_vid(u8 nr, u8 tpr, enum Vid_op op, u32 isr_exec_cnt_want, bool eoi_exit_induced) { volatile struct vmx_basic_vid_test_guest_args *args = @@ -10838,15 +10842,23 @@ static void test_basic_vid(u8 nr, u8 tpr, bool tpr_virt, u32 isr_exec_cnt_want, * However, PPR virtualization, which occurs before virtual interrupt * delivery, sets VPPR to VTPR, when SVI is 0. */ - vmcs_write(GUEST_INT_STATUS, nr); args->isr_exec_cnt = 0; - if (tpr_virt) { - args->op = VID_OP_SET_CR8; + args->op = op; + switch (op) { + case VID_OP_SELF_IPI: + vmcs_write(GUEST_INT_STATUS, 0); + args->nr = nr; + set_vtpr(0); + break; + case VID_OP_SET_CR8: + vmcs_write(GUEST_INT_STATUS, nr); args->nr = task_priority_class(tpr); set_vtpr(0xff); - } else { - args->op = VID_OP_NOP; + break; + default: + vmcs_write(GUEST_INT_STATUS, nr); set_vtpr(tpr); + break; } enter_guest(); @@ -10903,15 +10915,18 @@ static void vmx_basic_vid_test(void) if (nr == 0x20) continue; + test_basic_vid(nr, /*tpr=*/0, VID_OP_SELF_IPI, + /*isr_exec_cnt_want=*/1, + /*eoi_exit_induced=*/false); for (tpr = 0; tpr < 256; tpr++) { u32 isr_exec_cnt_want = task_priority_class(nr) > task_priority_class(tpr) ? 1 : 0; - test_basic_vid(nr, tpr, /*tpr_virt=*/false, + test_basic_vid(nr, tpr, VID_OP_NOP, isr_exec_cnt_want, /*eoi_exit_induced=*/false); - test_basic_vid(nr, tpr, /*tpr_virt=*/true, + test_basic_vid(nr, tpr, VID_OP_SET_CR8, isr_exec_cnt_want, /*eoi_exit_induced=*/false); } @@ -10930,8 +10945,8 @@ static void test_eoi_virt(u8 nr, u8 lo_pri_nr, bool eoi_exit_induced) u32 *virtual_apic_page = get_vapic_page(); set_virr_bit(virtual_apic_page, lo_pri_nr); - test_basic_vid(nr, /*tpr=*/0, /*tpr_virt=*/false, - /*isr_exec_cnt_want=*/2, eoi_exit_induced); + test_basic_vid(nr, /*tpr=*/0, VID_OP_NOP, /*isr_exec_cnt_want=*/2, + eoi_exit_induced); TEST_ASSERT(!get_virr_bit(virtual_apic_page, lo_pri_nr)); TEST_ASSERT(!get_virr_bit(virtual_apic_page, nr)); } -- 2.43.0.472.g3155946c3a-goog