Skip to content

Commit 68c3202

Browse files
yanzhao56sean-jc
authored andcommitted
KVM: x86/mmu: Zap KVM TDP when noncoherent DMA assignment starts/stops
Zap KVM TDP when noncoherent DMA assignment starts (noncoherent dma count transitions from 0 to 1) or stops (noncoherent dma count transitions from 1 to 0). Before the zap, test if guest MTRR is to be honored after the assignment starts or was honored before the assignment stops. When there's no noncoherent DMA device, EPT memory type is ((MTRR_TYPE_WRBACK << VMX_EPT_MT_EPTE_SHIFT) | VMX_EPT_IPAT_BIT) When there're noncoherent DMA devices, EPT memory type needs to honor guest CR0.CD and MTRR settings. So, if noncoherent DMA count transitions between 0 and 1, EPT leaf entries need to be zapped to clear stale memory type. This issue might be hidden when the device is statically assigned with VFIO adding/removing MMIO regions of the noncoherent DMA devices for several times during guest boot, and current KVM MMU will call kvm_mmu_zap_all_fast() on the memslot removal. But if the device is hot-plugged, or if the guest has mmio_always_on for the device, the MMIO regions of it may only be added for once, then there's no path to do the EPT entries zapping to clear stale memory type. Therefore do the EPT zapping when noncoherent assignment starts/stops to ensure stale entries cleaned away. Signed-off-by: Yan Zhao <yan.y.zhao@intel.com> Link: https://lore.kernel.org/r/20230714065223.20432-1-yan.y.zhao@intel.com [sean: fix misspelled words in comment and changelog] Signed-off-by: Sean Christopherson <seanjc@google.com>
1 parent 9a37681 commit 68c3202

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

arch/x86/kvm/x86.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13188,15 +13188,31 @@ bool noinstr kvm_arch_has_assigned_device(struct kvm *kvm)
1318813188
}
1318913189
EXPORT_SYMBOL_GPL(kvm_arch_has_assigned_device);
1319013190

13191+
static void kvm_noncoherent_dma_assignment_start_or_stop(struct kvm *kvm)
13192+
{
13193+
/*
13194+
* Non-coherent DMA assignment and de-assignment will affect
13195+
* whether KVM honors guest MTRRs and cause changes in memtypes
13196+
* in TDP.
13197+
* So, specify the second parameter as true here to indicate
13198+
* non-coherent DMAs are/were involved and TDP zap might be
13199+
* necessary.
13200+
*/
13201+
if (__kvm_mmu_honors_guest_mtrrs(true))
13202+
kvm_zap_gfn_range(kvm, gpa_to_gfn(0), gpa_to_gfn(~0ULL));
13203+
}
13204+
1319113205
void kvm_arch_register_noncoherent_dma(struct kvm *kvm)
1319213206
{
13193-
atomic_inc(&kvm->arch.noncoherent_dma_count);
13207+
if (atomic_inc_return(&kvm->arch.noncoherent_dma_count) == 1)
13208+
kvm_noncoherent_dma_assignment_start_or_stop(kvm);
1319413209
}
1319513210
EXPORT_SYMBOL_GPL(kvm_arch_register_noncoherent_dma);
1319613211

1319713212
void kvm_arch_unregister_noncoherent_dma(struct kvm *kvm)
1319813213
{
13199-
atomic_dec(&kvm->arch.noncoherent_dma_count);
13214+
if (!atomic_dec_return(&kvm->arch.noncoherent_dma_count))
13215+
kvm_noncoherent_dma_assignment_start_or_stop(kvm);
1320013216
}
1320113217
EXPORT_SYMBOL_GPL(kvm_arch_unregister_noncoherent_dma);
1320213218

0 commit comments

Comments
 (0)