@@ -4721,6 +4721,55 @@ static void test_pml(void)
vmcs_write(CPU_EXEC_CTRL1, secondary_saved);
}
+enum vmcs_access {
+ ACCESS_VMREAD,
+ ACCESS_VMWRITE,
+ ACCESS_NONE,
+};
+
+/*
+ * If the "VMCS shadowing" VM-execution control is 1, the VMREAD-bitmap
+ * and VMWRITE-bitmap addresses must each satisfy the following checks:
+ *
+ * - Bits 11:0 of the address must be 0.
+ * - The address must not set any bits beyond the processor’s
+ * physical-address width.
+ *
+ * [Intel SDM]
+ */
+static void test_vmread_vmwrite_bitmap(void)
+{
+ u8 *bitmap[2];
+ u32 primary_saved = vmcs_read(CPU_EXEC_CTRL0);
+ u32 secondary_saved = vmcs_read(CPU_EXEC_CTRL1);
+ u32 primary = primary_saved;
+ u32 secondary = secondary_saved;
+
+ if (!((ctrl_cpu_rev[0].clr & CPU_SECONDARY) &&
+ (ctrl_cpu_rev[1].clr & CPU_SHADOW_VMCS))) {
+ test_skip("\"Secondary execution\" control and/or \"VMCS shadowing\" control is not supported !");
+ return;
+ }
+
+ primary |= CPU_SECONDARY;
+ vmcs_write(CPU_EXEC_CTRL0, primary);
+ secondary |= CPU_SHADOW_VMCS;
+ vmcs_write(CPU_EXEC_CTRL1, secondary);
+
+ bitmap[ACCESS_VMREAD] = alloc_page();
+ bitmap[ACCESS_VMWRITE] = alloc_page();
+ vmcs_write(VMREAD_BITMAP, virt_to_phys(bitmap[ACCESS_VMREAD]));
+ vmcs_write(VMWRITE_BITMAP, virt_to_phys(bitmap[ACCESS_VMWRITE]));
+
+ test_vmcs_page_reference(CPU_SHADOW_VMCS, VMREAD_BITMAP,
+ "VMREAD bitmap", "VMCS shadowing", false, false);
+ test_vmcs_page_reference(CPU_SHADOW_VMCS, VMWRITE_BITMAP,
+ "VMWRITE bitmap", "VMCS shadowing", false, false);
+
+ vmcs_write(CPU_EXEC_CTRL0, primary_saved);
+ vmcs_write(CPU_EXEC_CTRL1, secondary_saved);
+}
+
/*
* Check that the virtual CPU checks all of the VMX controls as
* documented in the Intel SDM.
@@ -4747,6 +4796,7 @@ static void vmx_controls_test(void)
test_invalid_event_injection();
test_vpid();
test_eptp();
+ test_vmread_vmwrite_bitmap();
}
static bool valid_vmcs_for_vmentry(void)
@@ -5468,12 +5518,6 @@ static void vmx_apic_passthrough_thread_test(void)
vmx_apic_passthrough(true);
}
-enum vmcs_access {
- ACCESS_VMREAD,
- ACCESS_VMWRITE,
- ACCESS_NONE,
-};
-
struct vmcs_shadow_test_common {
enum vmcs_access op;
enum Reason reason;