On Wed, Jun 19, 2024 at 03:36:10PM -0700, Rick Edgecombe wrote: > diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c > index e9c1783a8743..287dcc2685e4 100644 > --- a/arch/x86/kvm/mmu/mmu.c > +++ b/arch/x86/kvm/mmu/mmu.c > @@ -3701,7 +3701,9 @@ static int mmu_alloc_direct_roots(struct kvm_vcpu *vcpu) > int r; > > if (tdp_mmu_enabled) { > - kvm_tdp_mmu_alloc_root(vcpu); > + if (kvm_has_mirrored_tdp(vcpu->kvm)) > + kvm_tdp_mmu_alloc_root(vcpu, true); > + kvm_tdp_mmu_alloc_root(vcpu, false); > return 0; > } mmu_alloc_direct_roots() is called when vcpu->arch.mmu->root.hpa is INVALID_PAGE in kvm_mmu_reload(), which could happen after direct root is invalidated. > -void kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu) > +void kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu, bool mirror) > { > struct kvm_mmu *mmu = vcpu->arch.mmu; > union kvm_mmu_page_role role = mmu->root_role; > @@ -241,6 +246,9 @@ void kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu) > struct kvm *kvm = vcpu->kvm; > struct kvm_mmu_page *root; > > + if (mirror) > + role.is_mirror = 1; > + Could we add a validity check of mirror_root_hpa to prevent an incorrect ref count increment of the mirror root? + if (mirror) { + if (mmu->mirror_root_hpa != INVALID_PAGE) + return; + role.is_mirror = true; + } > /* > * Check for an existing root before acquiring the pages lock to avoid > * unnecessary serialization if multiple vCPUs are loading a new root. > @@ -292,8 +300,12 @@ void kvm_tdp_mmu_alloc_root(struct kvm_vcpu *vcpu) > * and actually consuming the root if it's invalidated after dropping > * mmu_lock, and the root can't be freed as this vCPU holds a reference. > */ > - mmu->root.hpa = __pa(root->spt); > - mmu->root.pgd = 0; > + if (mirror) { > + mmu->mirror_root_hpa = __pa(root->spt); > + } else { > + mmu->root.hpa = __pa(root->spt); > + mmu->root.pgd = 0; > + } > }