Skip to content

Commit c9f65a3

Browse files
yanzhao56sean-jc
authored andcommitted
KVM: VMX: drop IPAT in memtype when CD=1 for KVM_X86_QUIRK_CD_NW_CLEARED
For KVM_X86_QUIRK_CD_NW_CLEARED is on, remove the IPAT (ignore PAT) bit in EPT memory types when cache is disabled and non-coherent DMA are present. To correctly emulate CR0.CD=1, UC + IPAT are required as memtype in EPT. However, as with commit fb27995 ("KVM: vmx: obey KVM_QUIRK_CD_NW_CLEARED"), WB + IPAT are now returned to workaround a BIOS issue that guest MTRRs are enabled too late. Without this workaround, a super slow guest boot-up is expected during the pre-guest-MTRR-enabled period due to UC as the effective memory type for all guest memory. Absent emulating CR0.CD=1 with UC, it makes no sense to set IPAT when KVM is honoring the guest memtype. Removing the IPAT bit in this patch allows effective memory type to honor PAT values as well, as WB is the weakest memtype. It means if a guest explicitly claims UC as the memtype in PAT, the effective memory is UC instead of previous WB. If, for some unknown reason, a guest meets a slow boot-up issue with the removal of IPAT, it's desired to fix the blamed PAT in the guest. Returning guest MTRR type as if CR0.CD=0 is also not preferred because KVMs ABI for the quirk also requires KVM to force WB memtype regardless of guest MTRRs to workaround the slow guest boot-up issue. In the future, honoring guest PAT will also allow KVM to more precisely zap SPTEs when the effective memtype changes. E.g. by not forcing WB when CR0.CD=1, instead of zapping SPTEs when guest MTRRs change, KVM can skip MTRR-induced zaps if CR0.CD=1 and zap SPTEs for non-WB MTRR ranges when CR0.CD is toggled (WB MTRR SPTEs can be kept because they're WB regardless of CR0.CD). The change of removing IPAT has been verified with normal boot-up time on old OVMF of commit c9e5618f84b0cb54a9ac2d7604f7b7e7859b45a7 as well, dated back to Apr 14 2015. Suggested-by: Sean Christopherson <[email protected]> Signed-off-by: Yan Zhao <[email protected]> Link: https://lore.kernel.org/r/[email protected] [sean: massage changelog to apply patch without full series] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 362ff6d commit c9f65a3

File tree

1 file changed

+3
-6
lines changed

1 file changed

+3
-6
lines changed

arch/x86/kvm/vmx/vmx.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7579,8 +7579,6 @@ static int vmx_vm_init(struct kvm *kvm)
75797579

75807580
static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
75817581
{
7582-
u8 cache;
7583-
75847582
/* We wanted to honor guest CD/MTRR/PAT, but doing so could result in
75857583
* memory aliases with conflicting memory types and sometimes MCEs.
75867584
* We have to be careful as to what are honored and when.
@@ -7607,11 +7605,10 @@ static u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
76077605

76087606
if (kvm_read_cr0_bits(vcpu, X86_CR0_CD)) {
76097607
if (kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
7610-
cache = MTRR_TYPE_WRBACK;
7608+
return MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT;
76117609
else
7612-
cache = MTRR_TYPE_UNCACHABLE;
7613-
7614-
return (cache << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
7610+
return (MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT) |
7611+
VMX_EPT_IPAT_BIT;
76157612
}
76167613

76177614
return kvm_mtrr_get_guest_memory_type(vcpu, gfn) << VMX_EPT_MT_EPTE_SHIFT;

0 commit comments

Comments
 (0)