On Tue, 2024-05-14 at 17:59 -0700, Rick Edgecombe wrote: > +static void handle_removed_private_spte(struct kvm *kvm, gfn_t gfn, > + u64 old_spte, u64 new_spte, > + int level) > +{ > + bool was_present = is_shadow_present_pte(old_spte); > + bool was_leaf = was_present && is_last_spte(old_spte, level); > + kvm_pfn_t old_pfn = spte_to_pfn(old_spte); > + int ret; > + > + /* > + * Allow only leaf page to be zapped. Reclaim non-leaf page tables > page > + * at destroying VM. > + */ > + if (!was_leaf) > + return; > + > + /* Zapping leaf spte is allowed only when write lock is held. */ > + lockdep_assert_held_write(&kvm->mmu_lock); > + ret = static_call(kvm_x86_zap_private_spte)(kvm, gfn, level); > + /* Because write lock is held, operation should success. */ > + if (KVM_BUG_ON(ret, kvm)) > + return; > + > + ret = static_call(kvm_x86_remove_private_spte)(kvm, gfn, level, > old_pfn); I don't see why these (zap_private_spte and remove_private_spte) can't be a single op. Was it to prepare for huge pages support or something? In the base series they are both only called once. > + KVM_BUG_ON(ret, kvm); > +} > +