[kvm-unit-tests PATCH v2 4/4] x86/access: Try emulation for CR0.WP test as well

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

 



Enhance the CR.WP toggling test to do additional tests via the emulator
as these used to trigger bugs when CR0.WP is guest owned.

Link: https://lore.kernel.org/kvm/ea3a8fbc-2bf8-7442-e498-3e5818384c83@xxxxxxxxxxxxxx/
Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx>
---
 x86/access.c | 46 +++++++++++++++++++++++++++++++---------------
 1 file changed, 31 insertions(+), 15 deletions(-)

diff --git a/x86/access.c b/x86/access.c
index ae5e7d8e8892..21967434bc18 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -1107,27 +1107,43 @@ static int check_write_cr0wp(ac_pt_env_t *pt_env)
 	 * We load CR0.WP with the inverse value of what would be used during
 	 * the access test and toggle EFER.NX to flush and rebuild the current
 	 * MMU context based on that value.
+	 *
+	 * This used to trigger a bug in the emulator we try to test via FEP.
 	 */
+	for (;;) {
+		const char *fep = (at.flags & AC_FEP_MASK) ? "FEP " : "";
 
-	set_cr0_wp(1);
-	set_efer_nx(1);
-	set_efer_nx(0);
+		set_cr0_wp(1);
+		set_efer_nx(1);
+		set_efer_nx(0);
 
-	if (!ac_test_do_access(&at)) {
-		printf("%s: CR0.WP=0 r/o write fail\n", __FUNCTION__);
-		err++;
-	}
+		if (!ac_test_do_access(&at)) {
+			printf("%s: %sCR0.WP=0 r/o write fail\n", __FUNCTION__, fep);
+			err++;
+		}
 
-	at.flags |= AC_CPU_CR0_WP_MASK;
-	__ac_set_expected_status(&at, false);
+		at.flags |= AC_CPU_CR0_WP_MASK;
+		__ac_set_expected_status(&at, false);
 
-	set_cr0_wp(0);
-	set_efer_nx(1);
-	set_efer_nx(0);
+		set_cr0_wp(0);
+		set_efer_nx(1);
+		set_efer_nx(0);
 
-	if (!ac_test_do_access(&at)) {
-		printf("%s: CR0.WP=1 r/o write deny fail\n", __FUNCTION__);
-		err++;
+		if (!ac_test_do_access(&at)) {
+			printf("%s: %sCR0.WP=1 r/o write deny fail\n", __FUNCTION__, fep);
+			err++;
+		}
+
+		if (!fep_available)
+			break;
+
+		if (at.flags & AC_FEP_MASK)
+			break;
+
+		/* Re-test via the emulator */
+		at.flags |= AC_FEP_MASK;
+		at.flags ^= AC_CPU_CR0_WP_MASK;
+		__ac_set_expected_status(&at, false);
 	}
 
 	return err == 0;
-- 
2.39.2




[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