Skip to content

Commit 1affe45

Browse files
yanzhao56sean-jc
authored andcommitted
KVM: x86/mmu: Add helpers to return if KVM honors guest MTRRs
Add helpers to check if KVM honors guest MTRRs instead of open coding the logic in kvm_tdp_page_fault(). Future fixes and cleanups will also need to determine if KVM should honor guest MTRRs, e.g. for CR0.CD toggling and and non-coherent DMA transitions. Provide an inner helper, __kvm_mmu_honors_guest_mtrrs(), so that KVM can check if guest MTRRs were honored when stopping non-coherent DMA. Note, there is no need to explicitly check that TDP is enabled, KVM clears shadow_memtype_mask when TDP is disabled, i.e. it's non-zero if and only if EPT is enabled. Suggested-by: Sean Christopherson <[email protected]> Signed-off-by: Yan Zhao <[email protected]> Link: https://lore.kernel.org/r/[email protected] Link: https://lore.kernel.org/r/[email protected] [sean: squash into a one patch, drop explicit TDP check massage changelog] Signed-off-by: Sean Christopherson <[email protected]>
1 parent 5804c19 commit 1affe45

File tree

2 files changed

+23
-9
lines changed

2 files changed

+23
-9
lines changed

arch/x86/kvm/mmu.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,13 @@ static inline u8 permission_fault(struct kvm_vcpu *vcpu, struct kvm_mmu *mmu,
237237
return -(u32)fault & errcode;
238238
}
239239

240+
bool __kvm_mmu_honors_guest_mtrrs(bool vm_has_noncoherent_dma);
241+
242+
static inline bool kvm_mmu_honors_guest_mtrrs(struct kvm *kvm)
243+
{
244+
return __kvm_mmu_honors_guest_mtrrs(kvm_arch_has_noncoherent_dma(kvm));
245+
}
246+
240247
void kvm_zap_gfn_range(struct kvm *kvm, gfn_t gfn_start, gfn_t gfn_end);
241248

242249
int kvm_arch_write_log_dirty(struct kvm_vcpu *vcpu);

arch/x86/kvm/mmu/mmu.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4479,21 +4479,28 @@ static int kvm_tdp_mmu_page_fault(struct kvm_vcpu *vcpu,
44794479
}
44804480
#endif
44814481

4482-
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
4482+
bool __kvm_mmu_honors_guest_mtrrs(bool vm_has_noncoherent_dma)
44834483
{
44844484
/*
4485-
* If the guest's MTRRs may be used to compute the "real" memtype,
4486-
* restrict the mapping level to ensure KVM uses a consistent memtype
4487-
* across the entire mapping. If the host MTRRs are ignored by TDP
4488-
* (shadow_memtype_mask is non-zero), and the VM has non-coherent DMA
4489-
* (DMA doesn't snoop CPU caches), KVM's ABI is to honor the memtype
4490-
* from the guest's MTRRs so that guest accesses to memory that is
4491-
* DMA'd aren't cached against the guest's wishes.
4485+
* If host MTRRs are ignored (shadow_memtype_mask is non-zero), and the
4486+
* VM has non-coherent DMA (DMA doesn't snoop CPU caches), KVM's ABI is
4487+
* to honor the memtype from the guest's MTRRs so that guest accesses
4488+
* to memory that is DMA'd aren't cached against the guest's wishes.
44924489
*
44934490
* Note, KVM may still ultimately ignore guest MTRRs for certain PFNs,
44944491
* e.g. KVM will force UC memtype for host MMIO.
44954492
*/
4496-
if (shadow_memtype_mask && kvm_arch_has_noncoherent_dma(vcpu->kvm)) {
4493+
return vm_has_noncoherent_dma && shadow_memtype_mask;
4494+
}
4495+
4496+
int kvm_tdp_page_fault(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault)
4497+
{
4498+
/*
4499+
* If the guest's MTRRs may be used to compute the "real" memtype,
4500+
* restrict the mapping level to ensure KVM uses a consistent memtype
4501+
* across the entire mapping.
4502+
*/
4503+
if (kvm_mmu_honors_guest_mtrrs(vcpu->kvm)) {
44974504
for ( ; fault->max_level > PG_LEVEL_4K; --fault->max_level) {
44984505
int page_num = KVM_PAGES_PER_HPAGE(fault->max_level);
44994506
gfn_t base = gfn_round_for_level(fault->gfn,

0 commit comments

Comments
 (0)