Skip to content

Commit 377b2f3

Browse files
committed
KVM: VMX: Always honor guest PAT on CPUs that support self-snoop
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]>
1 parent 65a4de0 commit 377b2f3

File tree

2 files changed

+11
-7
lines changed

2 files changed

+11
-7
lines changed

arch/x86/kvm/mmu/mmu.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4616,14 +4616,16 @@ static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vcpu,
46164616
bool kvm_mmu_may_ignore_guest_pat(void)
46174617
{
46184618
/*
4619-
* When EPT is enabled (shadow_memtype_mask is non-zero), and the VM
4619+
* When EPT is enabled (shadow_memtype_mask is non-zero), the CPU does
4620+
* not support self-snoop (or is affected by an erratum), and the VM
46204621
* has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is to
46214622
* honor the memtype from the guest's PAT so that guest accesses to
46224623
* memory that is DMA'd aren't cached against the guest's wishes. As a
46234624
* result, KVM _may_ ignore guest PAT, whereas without non-coherent DMA,
4624-
* KVM _always_ ignores guest PAT (when EPT is enabled).
4625+
* KVM _always_ ignores or honors guest PAT, i.e. doesn't toggle SPTE
4626+
* bits in response to non-coherent device (un)registration.
46254627
*/
4626-
return shadow_memtype_mask;
4628+
return !static_cpu_has(X86_FEATURE_SELFSNOOP) && shadow_memtype_mask;
46274629
}
46284630

46294631
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)

arch/x86/kvm/vmx/vmx.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7667,11 +7667,13 @@ u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
76677667

76687668
/*
76697669
* Force WB and ignore guest PAT if the VM does NOT have a non-coherent
7670-
* device attached. Letting the guest control memory types on Intel
7671-
* CPUs may result in unexpected behavior, and so KVM's ABI is to trust
7672-
* the guest to behave only as a last resort.
7670+
* device attached and the CPU doesn't support self-snoop. Letting the
7671+
* guest control memory types on Intel CPUs without self-snoop may
7672+
* result in unexpected behavior, and so KVM's (historical) ABI is to
7673+
* trust the guest to behave only as a last resort.
76737674
*/
7674-
if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
7675+
if (!static_cpu_has(X86_FEATURE_SELFSNOOP) &&
7676+
!kvm_arch_has_noncoherent_dma(vcpu->kvm))
76757677
return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
76767678

76777679
return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT);

0 commit comments

Comments
 (0)