Re: [kvm-unit-test 1/2] nVMX x86: APIC virtual controls must be unset if "Use TPR shadow" is unset

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

 



It becomes difficult to create the inner loop as the other three controls need to be tested individually, in pairs and then all together. But the outer loop makes sense. In fact, after your feedback, I realized that I hadn't run all the tests with "use TPR shadow" set. So I have created an outer loop (sort of) that runs twice - once with "use TPR shadow" unset and then with "use TPR shadow" set.

I will send out the revised version.

Thanks,
Krish

On 07/09/2018 10:31 AM, Jim Mattson wrote:
Hi Krish,

I think this would be more succint as two loops: an outer loop that
tested "use TPR shadow" values and an inner loop that tested
combinations of the other three controls. But this looks fine to me as
it is.

Reviewed-by: Jim Mattson <jmattson@xxxxxxxxxx>

On Fri, Jun 29, 2018 at 12:07 PM, Krish Sadhukhan
<krish.sadhukhan@xxxxxxxxxx> 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 "use TPR shadow" VM-execution control is 0, the following
     VM-execution controls must also be 0: "virtualize x2APIC mode",
     "APIC-register virtualization" and "virtual-interrupt delivery".

This unit-test validates the above vmentry check.

Signed-off-by: Krish Sadhukhan <krish.sadhukhan@xxxxxxxxxx>
Reviewed-by: Karl Heubaum <karl.heubaum@xxxxxxxxxx>
---
  x86/vmx_tests.c | 108
++++++++++++++++++++++++++++++++++++++++++++++++++++++--
  1 file changed, 106 insertions(+), 2 deletions(-)

diff --git a/x86/vmx_tests.c b/x86/vmx_tests.c
index 38f10f4..64be48f 100644
--- a/x86/vmx_tests.c
+++ b/x86/vmx_tests.c
@@ -3580,6 +3580,111 @@ static void test_apic_access_addr(void)
                                  "virtualize APIC-accesses", true, false);
  }
  +/*
+ * If the "use TPR shadow" VM-execution control is 0, the following
+ * VM-execution controls must also be 0:
+ *     - virtualize x2APIC mode
+ *     - APIC-register virtualization
+ *     - virtual-interrupt delivery
+ */
+static void test_apic_virtual_ctls(void)
+{
+       u32 saved_primary = vmcs_read(CPU_EXEC_CTRL0);
+       u32 saved_secondary = vmcs_read(CPU_EXEC_CTRL1);
+       u32 primary = saved_primary;
+       u32 secondary = saved_secondary;
+       bool cpu_has_virt_x2apic = 0;
+       bool cpu_has_apic_reg_virt = 0;
+       bool cpu_has_vintd = 0;
+
+       if (!((ctrl_cpu_rev[0].clr & (CPU_SECONDARY | CPU_TPR_SHADOW)) ==
+           (CPU_SECONDARY | CPU_TPR_SHADOW)))
+               return;
+
+       if ((ctrl_cpu_rev[1].clr & CPU_VIRT_X2APIC) == CPU_VIRT_X2APIC)
+               cpu_has_virt_x2apic = 1;
+       if ((ctrl_cpu_rev[1].clr & CPU_APIC_REG_VIRT) == CPU_APIC_REG_VIRT)
+               cpu_has_apic_reg_virt = 1;
+       if ((ctrl_cpu_rev[1].clr & CPU_VINTD) == CPU_VINTD)
+               cpu_has_vintd = 1;
+
+       primary |= CPU_SECONDARY;
+       vmcs_write(CPU_EXEC_CTRL0, primary & ~CPU_TPR_SHADOW);
+
+       if (cpu_has_virt_x2apic) {
+               secondary &= ~(CPU_APIC_REG_VIRT | CPU_VINTD);
+               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VIRT_X2APIC);
+               report_prefix_pushf("Use TPR shadow disabled; virtualize
x2APIC mode enabled");
+               test_vmx_controls(false, false);
+               report_prefix_pop();
+
+               if (cpu_has_apic_reg_virt) {
+                       vmcs_write(CPU_EXEC_CTRL1, secondary |
+                           CPU_APIC_REG_VIRT);
+                       report_prefix_pushf("Use TPR shadow disabled;
virtualize x2APIC mode enabled; APIC-register virtualization enabled");
+                       test_vmx_controls(false, false);
+                       report_prefix_pop();
+               }
+
+               if (cpu_has_vintd) {
+                       secondary &= ~CPU_APIC_REG_VIRT;
+                       vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
+                       report_prefix_pushf("Use TPR shadow disabled;
virtualize x2APIC mode enabled; virtual-interrupt delivery enabled");
+                       test_vmx_controls(false, false);
+                       report_prefix_pop();
+               }
+       }
+
+       if (cpu_has_apic_reg_virt) {
+               secondary &= ~(~CPU_VIRT_X2APIC | CPU_VINTD);
+               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_APIC_REG_VIRT);
+               report_prefix_pushf("Use TPR shadow disabled; APIC-register
virtualization enabled");
+               test_vmx_controls(false, false);
+               report_prefix_pop();
+
+               if (cpu_has_vintd) {
+                       secondary &= ~CPU_VIRT_X2APIC;
+                       vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
+                       report_prefix_pushf("Use TPR shadow disabled;
APIC-register virtualization enabled; virtual-interrupt delivery enabled");
+                       test_vmx_controls(false, false);
+                       report_prefix_pop();
+               }
+       }
+
+       if (cpu_has_vintd) {
+               secondary &= ~(~CPU_VIRT_X2APIC | CPU_APIC_REG_VIRT);
+               vmcs_write(CPU_EXEC_CTRL1, secondary | CPU_VINTD);
+               report_prefix_pushf("Use TPR shadow disabled;
virtual-interrupt delivery enabled");
+               test_vmx_controls(false, false);
+               report_prefix_pop();
+       }
+
+       if (cpu_has_virt_x2apic && cpu_has_apic_reg_virt &&
+           cpu_has_vintd) {
+
+               vmcs_write(CPU_EXEC_CTRL1, secondary | (CPU_VIRT_X2APIC |
+                   CPU_APIC_REG_VIRT | CPU_VINTD));
+               report_prefix_pushf("Use TPR shadow disabled; virtualize
x2APIC mode enabled; APIC-register virtualization enabled; virtual-interrupt
delivery enabled");
+               test_vmx_controls(false, false);
+               report_prefix_pop();
+
+               vmcs_write(CPU_EXEC_CTRL0, primary | CPU_TPR_SHADOW);
+               report_prefix_pushf("Use TPR shadow enabled; virtualize
x2APIC mode enabled; APIC-register virtualization enabled; virtual-interrupt
delivery enabled");
+               test_vmx_controls(true, false);
+               report_prefix_pop();
+       }
+
+       vmcs_write(CPU_EXEC_CTRL0, saved_primary);
+       vmcs_write(CPU_EXEC_CTRL1, saved_secondary);
+}
+
+static void test_apic_ctls(void)
+{
+       test_apic_virt_addr();
+       test_apic_access_addr();
+       test_apic_virtual_ctls();
+}
+
  static void set_vtpr(unsigned vtpr)
  {
         *(u32 *)phys_to_virt(vmcs_read(APIC_VIRT_ADDR) + APIC_TASKPRI) =
vtpr;
@@ -3846,8 +3951,7 @@ static void vmx_controls_test(void)
         test_cr3_targets();
         test_io_bitmaps();
         test_msr_bitmap();
-       test_apic_virt_addr();
-       test_apic_access_addr();
+       test_apic_ctls();
         test_tpr_threshold();
         test_nmi_ctrls();
  }
--
2.9.5





[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