Re: [PATCH 2/2] [kvm-unit-test] nVMX x86: check posted-interrupt control on vmentry of L2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Ping...


On 08/23/2018 05:03 PM, Krish Sadhukhan wrote:
According to section "Checks on VMX Controls" in Intel SDM vol 3C,
the following check needs to be enforced on vmentry of L2 guests:

     If the “process posted interrupts” VM-execution control is 1, the
     following must be true:

       - The “virtual-interrupt delivery” VM-execution control is 1.
       - The “acknowledge interrupt on exit” VM-exit control is 1.
       - The posted-interrupt notification vector has a value in the
       - range 0–255 (bits 15:8 are all 0).
       - Bits 5:0 of the posted-interrupt descriptor address are all 0.
       - The posted-interrupt descriptor address does not set any bits
         beyond the processor's physical-address width.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
Reviewed-by: Darren Kenny <darren.kenny@xxxxxxxxxx>
Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx>
---
  x86/vmx.h       |   1 +
  x86/vmx_tests.c | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2 files changed, 129 insertions(+)

diff --git a/x86/vmx.h b/x86/vmx.h
index 54646f5..22b2892 100644
--- a/x86/vmx.h
+++ b/x86/vmx.h
@@ -144,6 +144,7 @@ enum Encoding {
  	TSC_OFFSET_HI		= 0x2011ul,
  	APIC_VIRT_ADDR		= 0x2012ul,
  	APIC_ACCS_ADDR		= 0x2014ul,
+	POSTED_INTR_DESC_ADDR	= 0x2016ul,
  	EPTP			= 0x201aul,
  	EPTP_HI			= 0x201bul,
  	VMREAD_BITMAP           = 0x2026ul,
diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index caa1834..8b2efd8 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3912,12 +3912,140 @@ static void test_virtual_intr_ctls(void)
  	vmcs_write(PIN_CONTROLS, pin_saved);
  }
+static void test_pi_desc_addr(u64 addr, bool ctrl)
+{
+	vmcs_write(POSTED_INTR_DESC_ADDR, addr);
+	report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-descriptor-address 0x%lx", addr);
+	test_vmx_controls(ctrl, false);
+	report_prefix_pop();
+}
+
+/*
+ * If the “process posted interrupts” VM-execution control is 1, the
+ * following must be true:
+ *
+ *	- The “virtual-interrupt delivery” VM-execution control is 1.
+ *	- The “acknowledge interrupt on exit” VM-exit control is 1.
+ *	- The posted-interrupt notification vector has a value in the
+ *	- range 0–255 (bits 15:8 are all 0).
+ *	- Bits 5:0 of the posted-interrupt descriptor address are all 0.
+ *	- The posted-interrupt descriptor address does not set any bits
+ *	  beyond the processor's physical-address width.
+ * [Intel SDM]
+ */
+static void test_posted_intr(void)
+{
+	u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0);
+	u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1);
+	u32 saved_pin = vmcs_read(PIN_CONTROLS);
+	u32 exit_ctl_saved = vmcs_read(EXI_CONTROLS);
+	u32 primary = saved_primary;
+	u32 secondary = saved_secondary;
+	u32 pin = saved_pin;
+	u32 exit_ctl = exit_ctl_saved;
+	u16 vec;
+	int i;
+
+	if (!((ctrl_pin_rev.clr & PIN_POST_INTR) &&
+	    (ctrl_cpu_rev[1].clr & CPU_VINTD) &&
+	    (ctrl_exit_rev.clr & EXI_INTA)))
+		return;
+
+	vmcs_write(CPU_EXEC_CTRL0, primary | CPU_SECONDARY | CPU_TPR_SHADOW);
+
+	/*
+	 * Test virtual-interrupt-delivery and acknowledge-interrupt-on-exit
+	 */
+	pin |= PIN_POST_INTR;
+	vmcs_write(PIN_CONTROLS, pin);
+	secondary &= ~CPU_VINTD;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery disabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	secondary |= CPU_VINTD;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	exit_ctl &= ~EXI_INTA;
+	vmcs_write(EXI_CONTROLS, exit_ctl);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit disabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	exit_ctl |= EXI_INTA;
+	vmcs_write(EXI_CONTROLS, exit_ctl);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit enabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	secondary &= ~CPU_VINTD;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery disabled; acknowledge-interrupt-on-exit enabled");
+	test_vmx_controls(false, false);
+	report_prefix_pop();
+
+	secondary |= CPU_VINTD;
+	vmcs_write(CPU_EXEC_CTRL1, secondary);
+	report_prefix_pushf("Process-posted-interrupts enabled; virtual-interrupt-delivery enabled; acknowledge-interrupt-on-exit enabled");
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	/*
+	 * Test posted-interrupt notification vector
+	 */
+	for (i = 0; i < 8; i++) {
+		vec = (1ul << i);
+		vmcs_write(PINV, vec);
+		report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
+		test_vmx_controls(true, false);
+		report_prefix_pop();
+	}
+	for (i = 8; i < 16; i++) {
+		vec = (1ul << i);
+		vmcs_write(PINV, vec);
+		report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
+		test_vmx_controls(false, false);
+		report_prefix_pop();
+	}
+
+	vec &= ~(0xff << 8);
+	vmcs_write(PINV, vec);
+	report_prefix_pushf("Process-posted-interrupts enabled; posted-interrupt-notification-vector %u", vec);
+	test_vmx_controls(true, false);
+	report_prefix_pop();
+
+	/*
+	 * Test posted-interrupt descriptor addresss
+	 */
+	for (i = 0; i < 6; i++) {
+		test_pi_desc_addr(1ul << i, false);
+	}
+
+	test_pi_desc_addr(0xf0, false);
+	test_pi_desc_addr(0xff, false);
+	test_pi_desc_addr(0x0f, false);
+	test_pi_desc_addr(0x8000, true);
+	test_pi_desc_addr(0x00, true);
+	test_pi_desc_addr(0xc000, true);
+
+	test_vmcs_page_values("process-posted interrupts", POSTED_INTR_DESC_ADDR, false, false);
+
+	vmcs_write(CPU_EXEC_CTRL0, saved_primary);
+	vmcs_write(CPU_EXEC_CTRL1, saved_secondary);
+	vmcs_write(PIN_CONTROLS, saved_pin);
+}
+
  static void test_apic_ctls(void)
  {
  	test_apic_virt_addr();
  	test_apic_access_addr();
  	test_apic_virtual_ctls();
  	test_virtual_intr_ctls();
+	test_posted_intr();
  }
static void set_vtpr(unsigned vtpr)




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux