]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: nVMX: Decouple EPT RWX bits from EPT Violation protection bits
authorSean Christopherson <seanjc@google.com>
Thu, 27 Feb 2025 00:07:05 +0000 (16:07 -0800)
committerSean Christopherson <seanjc@google.com>
Fri, 28 Feb 2025 17:14:05 +0000 (09:14 -0800)
Define independent macros for the RWX protection bits that are enumerated
via EXIT_QUALIFICATION for EPT Violations, and tie them to the RWX bits in
EPT entries via compile-time asserts.  Piggybacking the EPTE defines works
for now, but it creates holes in the EPT_VIOLATION_xxx macros and will
cause headaches if/when KVM emulates Mode-Based Execution (MBEC), or any
other features that introduces additional protection information.

Opportunistically rename EPT_VIOLATION_RWX_MASK to EPT_VIOLATION_PROT_MASK
so that it doesn't become stale if/when MBEC support is added.

No functional change intended.

Cc: Jon Kohler <jon@nutanix.com>
Cc: Nikolay Borisov <nik.borisov@suse.com>
Reviewed-by: Nikolay Borisov <nik.borisov@suse.com>
Link: https://lore.kernel.org/r/20250227000705.3199706-3-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/include/asm/vmx.h
arch/x86/kvm/mmu/paging_tmpl.h
arch/x86/kvm/vmx/vmx.c

index aabc223c649878064a3c7788c80385ed526e663c..8707361b24daa0c69703d4a688b1556a709296b8 100644 (file)
@@ -580,14 +580,23 @@ enum vm_entry_failure_code {
 /*
  * Exit Qualifications for EPT Violations
  */
-#define EPT_VIOLATION_RWX_SHIFT                3
 #define EPT_VIOLATION_ACC_READ         BIT(0)
 #define EPT_VIOLATION_ACC_WRITE                BIT(1)
 #define EPT_VIOLATION_ACC_INSTR                BIT(2)
-#define EPT_VIOLATION_RWX_MASK         (VMX_EPT_RWX_MASK << EPT_VIOLATION_RWX_SHIFT)
+#define EPT_VIOLATION_PROT_READ                BIT(3)
+#define EPT_VIOLATION_PROT_WRITE       BIT(4)
+#define EPT_VIOLATION_PROT_EXEC                BIT(5)
+#define EPT_VIOLATION_PROT_MASK                (EPT_VIOLATION_PROT_READ  | \
+                                        EPT_VIOLATION_PROT_WRITE | \
+                                        EPT_VIOLATION_PROT_EXEC)
 #define EPT_VIOLATION_GVA_IS_VALID     BIT(7)
 #define EPT_VIOLATION_GVA_TRANSLATED   BIT(8)
 
+#define EPT_VIOLATION_RWX_TO_PROT(__epte) (((__epte) & VMX_EPT_RWX_MASK) << 3)
+
+static_assert(EPT_VIOLATION_RWX_TO_PROT(VMX_EPT_RWX_MASK) ==
+             (EPT_VIOLATION_PROT_READ | EPT_VIOLATION_PROT_WRITE | EPT_VIOLATION_PROT_EXEC));
+
 /*
  * Exit Qualifications for NOTIFY VM EXIT
  */
index f4711674c47bd04125b5a9c11886985da24a2e1e..68e323568e95e65d4dae0e00c53e8f00330b4ec9 100644 (file)
@@ -510,8 +510,7 @@ error:
                 * Note, pte_access holds the raw RWX bits from the EPTE, not
                 * ACC_*_MASK flags!
                 */
-               walker->fault.exit_qualification |= (pte_access & VMX_EPT_RWX_MASK) <<
-                                                    EPT_VIOLATION_RWX_SHIFT;
+               walker->fault.exit_qualification |= EPT_VIOLATION_RWX_TO_PROT(pte_access);
        }
 #endif
        walker->fault.address = addr;
index ec4527e7fdf9c6313e4a06d52fb27935506e3c6e..9bbcdbfc7f2c01537b163672ed6637e0b556abb4 100644 (file)
@@ -5822,7 +5822,7 @@ static int handle_ept_violation(struct kvm_vcpu *vcpu)
        error_code |= (exit_qualification & EPT_VIOLATION_ACC_INSTR)
                      ? PFERR_FETCH_MASK : 0;
        /* ept page table entry is present? */
-       error_code |= (exit_qualification & EPT_VIOLATION_RWX_MASK)
+       error_code |= (exit_qualification & EPT_VIOLATION_PROT_MASK)
                      ? PFERR_PRESENT_MASK : 0;
 
        if (error_code & EPT_VIOLATION_GVA_IS_VALID)