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> --- Instead of testing 'invalid_mask', I simply added yet another call to is_fep_available(). It's cleaner, IMO, as it's easier to grasp than '!(invalid_mask & AC_FEP_MASK)'. The additional exception doesn't influence the tests, as all preparation is done in do_cr0_wp_access(). x86/access.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/x86/access.c b/x86/access.c index 674077297978..eab3959bc871 100644 --- a/x86/access.c +++ b/x86/access.c @@ -1107,14 +1107,17 @@ static int do_cr0_wp_access(ac_test_t *at, int flags) * Load CR0.WP with the inverse value of what will be used during * the access test and toggle EFER.NX to coerce KVM into rebuilding * the current MMU context based on the soon-to-be-stale CR0.WP. + * + * This used to trigger a bug in the emulator, testable via FEP. */ set_cr0_wp(!cr0_wp); set_efer_nx(1); set_efer_nx(0); if (!ac_test_do_access(at)) { - printf("%s: supervisor write with CR0.WP=%d did not %s\n", - __FUNCTION__, cr0_wp, cr0_wp ? "FAULT" : "SUCCEED"); + printf("%s: %ssupervisor write with CR0.WP=%d did not %s\n", + __FUNCTION__, (flags & AC_FEP_MASK) ? "emulated " : "", + cr0_wp, cr0_wp ? "FAULT" : "SUCCEED"); return 1; } @@ -1133,6 +1136,10 @@ static int check_toggle_cr0_wp(ac_pt_env_t *pt_env) err += do_cr0_wp_access(&at, 0); err += do_cr0_wp_access(&at, AC_CPU_CR0_WP_MASK); + if (is_fep_available()) { + err += do_cr0_wp_access(&at, AC_FEP_MASK); + err += do_cr0_wp_access(&at, AC_FEP_MASK | AC_CPU_CR0_WP_MASK); + } return err == 0; } -- 2.39.2