]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: x86/mmu: pass PFERR_GUEST_PAGE/FINAL_MASK to kvm_translate_gpa
authorPaolo Bonzini <pbonzini@redhat.com>
Wed, 8 Apr 2026 15:42:00 +0000 (11:42 -0400)
committerPaolo Bonzini <pbonzini@redhat.com>
Sun, 10 May 2026 12:52:57 +0000 (14:52 +0200)
The XS/XU bit for EPT are only applied to final accesses, and use the
U bit from the page walk itself.  While strictly speaking not necessary
(any value of PFERR_USER_MASK would be the same for page table accesses,
because they're reads and writes only), it is clearer and less hackish
to only apply MBEC to PFERR_GUEST_FINAL_MASK.  Allow kvm-intel.ko to
distinguish the two cases.

Tested-by: David Riley <d.riley@proxmox.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/kvm/hyperv.c
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/mmu/paging_tmpl.h
arch/x86/kvm/x86.c

index 9b140bbdc1d83b8a124c5e2bcebfc437e6ee1540..cf9dd565b8946b052060668ca8bf71f9c909e69e 100644 (file)
@@ -2041,7 +2041,8 @@ static u64 kvm_hv_flush_tlb(struct kvm_vcpu *vcpu, struct kvm_hv_hcall *hc)
         * read with kvm_read_guest().
         */
        if (!hc->fast && is_guest_mode(vcpu)) {
-               hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa, 0, NULL);
+               hc->ingpa = translate_nested_gpa(vcpu, hc->ingpa,
+                                       PFERR_GUEST_FINAL_MASK, NULL);
                if (unlikely(hc->ingpa == INVALID_GPA))
                        return HV_STATUS_INVALID_HYPERCALL_INPUT;
        }
index c617837a50384ccac2cc094a2c01770065b980e2..6ac9f760d28cc3e02e8667bde2f6a802c1b05a3e 100644 (file)
@@ -4348,7 +4348,8 @@ static gpa_t nonpaging_gva_to_gpa(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
 {
        if (exception)
                exception->error_code = 0;
-       return kvm_translate_gpa(vcpu, mmu, vaddr, access, exception);
+       return kvm_translate_gpa(vcpu, mmu, vaddr, access | PFERR_GUEST_FINAL_MASK,
+                                exception);
 }
 
 static bool mmio_info_in_cache(struct kvm_vcpu *vcpu, u64 addr, bool direct)
index fb1b5d8b23e5cb4a473ee5ee0e82018f843e6753..567f8b77ffe05752d2e7bbac39a9d2b342d36b05 100644 (file)
@@ -376,7 +376,8 @@ retry_walk:
                walker->pte_gpa[walker->level - 1] = pte_gpa;
 
                real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(table_gfn),
-                                            nested_access, &walker->fault);
+                                            nested_access | PFERR_GUEST_PAGE_MASK,
+                                            &walker->fault);
 
                /*
                 * FIXME: This can happen if emulation (for of an INS/OUTS
@@ -444,7 +445,9 @@ retry_walk:
                gfn += pse36_gfn_delta(pte);
 #endif
 
-       real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn), access, &walker->fault);
+       real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(gfn),
+                                    access | PFERR_GUEST_FINAL_MASK,
+                                    &walker->fault);
        if (real_gpa == INVALID_GPA)
                return 0;
 
index 0a1b63c63d1a9cdf6c2f1748ebf8c1e5f28f8bb6..ef1e3ae13887f62a82b65dcd05d047742a788f49 100644 (file)
@@ -1072,7 +1072,8 @@ int load_pdptrs(struct kvm_vcpu *vcpu, unsigned long cr3)
         * to an L1 GPA.
         */
        real_gpa = kvm_translate_gpa(vcpu, mmu, gfn_to_gpa(pdpt_gfn),
-                                    PFERR_USER_MASK | PFERR_WRITE_MASK, NULL);
+                                    PFERR_USER_MASK | PFERR_WRITE_MASK |
+                                    PFERR_GUEST_PAGE_MASK, NULL);
        if (real_gpa == INVALID_GPA)
                return 0;