diff mbox series

[kvm-unit-tests,4/5] nVMX: add self-IPI tests to vmx_basic_vid_test

Message ID 20231211185552.3856862-5-jmattson@google.com (mailing list archive)
State New, archived
Headers show
Series nVMX: Simple posted interrupts test | expand

Commit Message

Jim Mattson Dec. 11, 2023, 6:55 p.m. UTC
From: "Marc Orr (Google)" <marc.orr@gmail.com>

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@gmail.com>
Co-developed-by: Jim Mattson <jmattson@google.com>
Signed-off-by: Jim Mattson <jmattson@google.com>
---
 x86/vmx_tests.c | 35 +++++++++++++++++++++++++----------
 1 file changed, 25 insertions(+), 10 deletions(-)
diff mbox series

Patch

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));
 }