]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: x86/mmu: Exempt nested EPT page tables from !USER, CR0.WP=0 logic
authorSean Christopherson <seanjc@google.com>
Mon, 2 Jun 2025 23:48:51 +0000 (16:48 -0700)
committerSean Christopherson <seanjc@google.com>
Fri, 20 Jun 2025 20:08:22 +0000 (13:08 -0700)
Exempt nested EPT shadow pages tables from the CR0.WP=0 handling of
supervisor writes, as EPT doesn't have a U/S bit and isn't affected by
CR0.WP (or CR4.SMEP in the exception to the exception).

Opportunistically refresh the comment to explain what KVM is doing, as
the only record of why KVM shoves in WRITE and drops USER is buried in
years-old changelogs.

Cc: Jon Kohler <jon@nutanix.com>
Cc: Sergey Dyasli <sergey.dyasli@nutanix.com>
Reviewed-by: Jon Kohler <jon@nutanix.com>
Reviewed-by: Sergey Dyasli <sergey.dyasli@nutanix.com>
Link: https://lore.kernel.org/r/20250602234851.54573-1-seanjc@google.com
Signed-off-by: Sean Christopherson <seanjc@google.com>
arch/x86/kvm/mmu/paging_tmpl.h

index 68e323568e95e65d4dae0e00c53e8f00330b4ec9..ed762bb4b007b9236727f338d8cfb5fe4131521f 100644 (file)
@@ -804,9 +804,12 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
        if (r != RET_PF_CONTINUE)
                return r;
 
+#if PTTYPE != PTTYPE_EPT
        /*
-        * Do not change pte_access if the pfn is a mmio page, otherwise
-        * we will cache the incorrect access into mmio spte.
+        * Treat the guest PTE protections as writable, supervisor-only if this
+        * is a supervisor write fault and CR0.WP=0 (supervisor accesses ignore
+        * PTE.W if CR0.WP=0).  Don't change the access type for emulated MMIO,
+        * otherwise KVM will cache incorrect access information in the SPTE.
         */
        if (fault->write && !(walker.pte_access & ACC_WRITE_MASK) &&
            !is_cr0_wp(vcpu->arch.mmu) && !fault->user && fault->slot) {
@@ -822,6 +825,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault
                if (is_cr4_smep(vcpu->arch.mmu))
                        walker.pte_access &= ~ACC_EXEC_MASK;
        }
+#endif
 
        r = RET_PF_RETRY;
        write_lock(&vcpu->kvm->mmu_lock);