]> Git Repo - J-linux.git/commitdiff
KVM: VMX: Always honor guest PAT on CPUs that support self-snoop
authorSean Christopherson <[email protected]>
Sat, 9 Mar 2024 01:09:29 +0000 (17:09 -0800)
committerSean Christopherson <[email protected]>
Fri, 7 Jun 2024 14:18:03 +0000 (07:18 -0700)
Unconditionally honor guest PAT on CPUs that support self-snoop, as
Intel has confirmed that CPUs that support self-snoop always snoop caches
and store buffers.  I.e. CPUs with self-snoop maintain cache coherency
even in the presence of aliased memtypes, thus there is no need to trust
the guest behaves and only honor PAT as a last resort, as KVM does today.

Honoring guest PAT is desirable for use cases where the guest has access
to non-coherent DMA _without_ bouncing through VFIO, e.g. when a virtual
(mediated, for all intents and purposes) GPU is exposed to the guest, along
with buffers that are consumed directly by the physical GPU, i.e. which
can't be proxied by the host to ensure writes from the guest are performed
with the correct memory type for the GPU.

Cc: Yiwei Zhang <[email protected]>
Suggested-by: Yan Zhao <[email protected]>
Suggested-by: Kevin Tian <[email protected]>
Tested-by: Xiangfei Ma <[email protected]>
Tested-by: Yongwei Ma <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Sean Christopherson <[email protected]>
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/vmx/vmx.c

index 561e7c29cf9e98e4e115170d5ea3d90d2bed459a..77ca81e13722d48757649ae23595bbd00a7a7729 100644 (file)
@@ -4616,14 +4616,16 @@ out_unlock:
 bool kvm_mmu_may_ignore_guest_pat(void)
 {
        /*
-        * When EPT is enabled (shadow_memtype_mask is non-zero), and the VM
+        * When EPT is enabled (shadow_memtype_mask is non-zero), the CPU does
+        * not support self-snoop (or is affected by an erratum), and the VM
         * has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is to
         * honor the memtype from the guest's PAT so that guest accesses to
         * memory that is DMA'd aren't cached against the guest's wishes.  As a
         * result, KVM _may_ ignore guest PAT, whereas without non-coherent DMA,
-        * KVM _always_ ignores guest PAT (when EPT is enabled).
+        * KVM _always_ ignores or honors guest PAT, i.e. doesn't toggle SPTE
+        * bits in response to non-coherent device (un)registration.
         */
-       return shadow_memtype_mask;
+       return !static_cpu_has(X86_FEATURE_SELFSNOOP) && shadow_memtype_mask;
 }
 
 int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
index a3cc0bc30540b9773288d61ab3dc1cf445686ff5..e97e1ad79bf4a2e3f5885c23dd10ee13d9b860d2 100644 (file)
@@ -7667,11 +7667,13 @@ u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 
        /*
         * Force WB and ignore guest PAT if the VM does NOT have a non-coherent
-        * device attached.  Letting the guest control memory types on Intel
-        * CPUs may result in unexpected behavior, and so KVM's ABI is to trust
-        * the guest to behave only as a last resort.
+        * device attached and the CPU doesn't support self-snoop.  Letting the
+        * guest control memory types on Intel CPUs without self-snoop may
+        * result in unexpected behavior, and so KVM's (historical) ABI is to
+        * trust the guest to behave only as a last resort.
         */
-       if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
+       if (!static_cpu_has(X86_FEATURE_SELFSNOOP) &&
+           !kvm_arch_has_noncoherent_dma(vcpu->kvm))
                return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
 
        return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT);
This page took 0.074026 seconds and 4 git commands to generate.