Skip to content

Commit e154808

Browse files
committed
KVM: VMX: Drop support for forcing UC memory when guest CR0.CD=1
Drop KVM's emulation of CR0.CD=1 on Intel CPUs now that KVM no longer honors guest MTRR memtypes, as forcing UC memory for VMs with non-coherent DMA only makes sense if the guest is using something other than PAT to configure the memtype for the DMA region. Furthermore, KVM has forced WB memory for CR0.CD=1 since commit fb27995 ("KVM: vmx: obey KVM_QUIRK_CD_NW_CLEARED"), and no known VMM in existence disables KVM_X86_QUIRK_CD_NW_CLEARED, let alone does so with non-coherent DMA. Lastly, commit fb27995 ("KVM: vmx: obey KVM_QUIRK_CD_NW_CLEARED") was from the same author as commit b18d543 ("KVM: x86: fix CR0.CD virtualization"), and followed by a mere month. I.e. forcing UC memory was likely the result of code inspection or perhaps misdiagnosed failures, and not the necessitate by a concrete use case. Update KVM's documentation to note that KVM_X86_QUIRK_CD_NW_CLEARED is now AMD-only, and to take an erratum for lack of CR0.CD virtualization on Intel. 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 0a7b735 commit e154808

File tree

4 files changed

+20
-15
lines changed

4 files changed

+20
-15
lines changed

Documentation/virt/kvm/api.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7953,7 +7953,11 @@ The valid bits in cap.args[0] are:
79537953
When this quirk is disabled, the reset value
79547954
is 0x10000 (APIC_LVT_MASKED).
79557955

7956-
KVM_X86_QUIRK_CD_NW_CLEARED By default, KVM clears CR0.CD and CR0.NW.
7956+
KVM_X86_QUIRK_CD_NW_CLEARED By default, KVM clears CR0.CD and CR0.NW on
7957+
AMD CPUs to workaround buggy guest firmware
7958+
that runs in perpetuity with CR0.CD, i.e.
7959+
with caches in "no fill" mode.
7960+
79577961
When this quirk is disabled, KVM does not
79587962
change the value of CR0.CD and CR0.NW.
79597963

Documentation/virt/kvm/x86/errata.rst

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,18 @@ matching the target APIC ID receive the interrupt).
5151

5252
MTRRs
5353
-----
54-
KVM does not virtualization guest MTRR memory types. KVM emulates accesses to
55-
MTRR MSRs, i.e. {RD,WR}MSR in the guest will behave as expected, but KVM does
56-
not honor guest MTRRs when determining the effective memory type, and instead
57-
treats all of guest memory as having Writeback (WB) MTRRs.
54+
KVM does not virtualize guest MTRR memory types. KVM emulates accesses to MTRR
55+
MSRs, i.e. {RD,WR}MSR in the guest will behave as expected, but KVM does not
56+
honor guest MTRRs when determining the effective memory type, and instead
57+
treats all of guest memory as having Writeback (WB) MTRRs.
58+
59+
CR0.CD
60+
------
61+
KVM does not virtualize CR0.CD on Intel CPUs. Similar to MTRR MSRs, KVM
62+
emulates CR0.CD accesses so that loads and stores from/to CR0 behave as
63+
expected, but setting CR0.CD=1 has no impact on the cachaeability of guest
64+
memory.
65+
66+
Note, this erratum does not affect AMD CPUs, which fully virtualize CR0.CD in
67+
hardware, i.e. put the CPU caches into "no fill" mode when CR0.CD=1, even when
68+
running in the guest.

arch/x86/kvm/vmx/vmx.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7674,10 +7674,6 @@ u8 vmx_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
76747674
if (!kvm_arch_has_noncoherent_dma(vcpu->kvm))
76757675
return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
76767676

7677-
if (kvm_read_cr0_bits(vcpu, X86_CR0_CD) &&
7678-
!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
7679-
return (MTRR_TYPE_UNCACHABLE << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT;
7680-
76817677
return (MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT);
76827678
}
76837679

arch/x86/kvm/x86.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -963,12 +963,6 @@ void kvm_post_set_cr0(struct kvm_vcpu *vcpu, unsigned long old_cr0, unsigned lon
963963

964964
if ((cr0 ^ old_cr0) & KVM_MMU_CR0_ROLE_BITS)
965965
kvm_mmu_reset_context(vcpu);
966-
967-
if (((cr0 ^ old_cr0) & X86_CR0_CD) &&
968-
kvm_mmu_may_ignore_guest_pat() &&
969-
kvm_arch_has_noncoherent_dma(vcpu->kvm) &&
970-
!kvm_check_has_quirk(vcpu->kvm, KVM_X86_QUIRK_CD_NW_CLEARED))
971-
kvm_zap_gfn_range(vcpu->kvm, 0, ~0ULL);
972966
}
973967
EXPORT_SYMBOL_GPL(kvm_post_set_cr0);
974968

0 commit comments

Comments
 (0)