Honor guest PATs in the range of memslots of flag KVM_MEM_NON_COHERENT_DMA set no matter the value of noncoherent dma count. Just honoring guest PATs (without honoring guest MTRRs) for memslots of flag KVM_MEM_NON_COHERENT_DMA is because - guest OS will ensure no page aliasing issue in guest side by honoring guest MTRRs in guest page table. Combinations like guest MTRR=WC or UC, guest PAT = WB is not allowed. (at least in Linux, see pat_x_mtrr_type()). - guest device driver programs device hardware according to guest PATs in modern platforms. Besides, we don't break down an EPT huge page if guest MTRRs in its range are not consistent, because - guest should have chosen correct guest PATs according to guest MTRRs. - in normal platforms, small guest pages with different PATs must correspond to different TLBs though they are mapped in a huge page in EPT. However, one condition may not be supported well by honoring guest PAT alone -- when guest MTRR=WC, guest PAT=UC-. By honoring guest MTRRs+PATs, the effective memory type is WC; while by honoring guest PATs alone, the effective memory type is UC. But it's arguable to support such a usage. Suggested-by: Sean Christopherson <seanjc@xxxxxxxxxx> Cc: Kevin Tian <kevin.tian@xxxxxxxxx> Cc: Zhenyu Wang <zhenyuw@xxxxxxxxxxxxxxx> Tested-by: Yongwei Ma <yongwei.ma@xxxxxxxxx> Signed-off-by: Yan Zhao <yan.y.zhao@xxxxxxxxx> --- arch/x86/kvm/vmx/vmx.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 85a23765e506..99f22589fa6d 100644 --- a/arch/x86/kvm/vmx/vmx.c +++ b/arch/x86/kvm/vmx/vmx.c @@ -7600,6 +7600,9 @@ static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio, if (is_mmio) return MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT; + if (slot->flags & KVM_MEM_NON_COHERENT_DMA) + return MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT; + if (!kvm_arch_has_noncoherent_dma(vcpu->kvm)) return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT; -- 2.17.1