On Fri, Nov 19, 2021 at 8:51 PM Sean Christopherson <seanjc@xxxxxxxxxx> wrote: > > When yielding in the TDP MMU iterator, service any pending TLB flush > before dropping RCU protections in anticipation of using the callers RCU > "lock" as a proxy for vCPUs in the guest. > > Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx> Reviewed-by: Ben Gardon <bgardon@xxxxxxxxxx> > --- > arch/x86/kvm/mmu/tdp_mmu.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c > index 79a52717916c..55c16680b927 100644 > --- a/arch/x86/kvm/mmu/tdp_mmu.c > +++ b/arch/x86/kvm/mmu/tdp_mmu.c > @@ -732,11 +732,11 @@ static inline bool tdp_mmu_iter_cond_resched(struct kvm *kvm, > return false; > > if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { > - rcu_read_unlock(); > - > if (flush) > kvm_flush_remote_tlbs(kvm); > > + rcu_read_unlock(); > + Just to check my understanding: Theoretically PT memory could be freed as soon as we release the RCU lock, if this is the only thread in a read critical section. In order to ensure that we can use RCU as a proxy for TLB flushes we need to flush the TLBs while still holding the RCU read lock. Without this change (and with the next one) we could wind up in a situation where we drop the RCU read lock, then the RCU callback runs and frees the memory, and then the guest does a lookup through the paging structure caches and we get a use-after-free bug. By flushing in an RCU critical section, we ensure that the TLBs will have been flushed by the time the RCU callback runs to free the memory. Clever! > if (shared) > cond_resched_rwlock_read(&kvm->mmu_lock); > else > -- > 2.34.0.rc2.393.gf8c9666880-goog >