aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm/vmx.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/kvm/vmx.c')
-rw-r--r--arch/x86/kvm/vmx.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 59b080c262e8..e8a5649f9c15 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -3581,11 +3581,26 @@ static u64 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
3581{ 3581{
3582 u64 ret; 3582 u64 ret;
3583 3583
3584 /* For VT-d and EPT combination
3585 * 1. MMIO: always map as UC
3586 * 2. EPT with VT-d:
3587 * a. VT-d without snooping control feature: can't guarantee the
3588 * result, try to trust guest.
3589 * b. VT-d with snooping control feature: snooping control feature of
3590 * VT-d engine can guarantee the cache correctness. Just set it
3591 * to WB to keep consistent with host. So the same as item 3.
3592 * 3. EPT without VT-d: always map as WB and set IGMT=1 to keep
3593 * consistent with host MTRR
3594 */
3584 if (is_mmio) 3595 if (is_mmio)
3585 ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; 3596 ret = MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT;
3597 else if (vcpu->kvm->arch.iommu_domain &&
3598 !(vcpu->kvm->arch.iommu_flags & KVM_IOMMU_CACHE_COHERENCY))
3599 ret = kvm_get_guest_memory_type(vcpu, gfn) <<
3600 VMX_EPT_MT_EPTE_SHIFT;
3586 else 3601 else
3587 ret = (kvm_get_guest_memory_type(vcpu, gfn) << 3602 ret = (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT)
3588 VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IGMT_BIT; 3603 | VMX_EPT_IGMT_BIT;
3589 3604
3590 return ret; 3605 return ret;
3591} 3606}