Re: [PATCH 17/22] kvm: mmu: Support dirty logging for the TDP MMU

From: Ben Gardon
Date: Thu Oct 08 2020 - 14:27:52 EST


On Fri, Sep 25, 2020 at 6:04 PM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
>
> On 25/09/20 23:22, Ben Gardon wrote:
> > start_level, KVM_MAX_HUGEPAGE_LEVEL, false);
> > + if (kvm->arch.tdp_mmu_enabled)
> > + flush = kvm_tdp_mmu_wrprot_slot(kvm, memslot, false) || flush;
> > spin_unlock(&kvm->mmu_lock);
> >
>
> In fact you can just pass down the end-level KVM_MAX_HUGEPAGE_LEVEL or
> PGLEVEL_4K here to kvm_tdp_mmu_wrprot_slot and from there to
> wrprot_gfn_range.

That makes sense. My only worry there is the added complexity of error
handling values besides PG_LEVEL_2M and PG_LEVEL_4K. Since there are
only two callers, I don't think that will be too much of a problem
though. I don't think KVM_MAX_HUGEPAGE_LEVEL would actually be a good
value to pass in as I don't think that would write protect 2M
mappings. KVM_MAX_HUGEPAGE_LEVEL is defined as PG_LEVEL_1G, or 3.

>
> >
> > + /*
> > + * Take a reference on the root so that it cannot be freed if
> > + * this thread releases the MMU lock and yields in this loop.
> > + */
> > + get_tdp_mmu_root(kvm, root);
> > +
> > + spte_set = wrprot_gfn_range(kvm, root, slot->base_gfn,
> > + slot->base_gfn + slot->npages, skip_4k) ||
> > + spte_set;
> > +
> > + put_tdp_mmu_root(kvm, root);
>
>
> Generalyl using "|=" is the more common idiom in mmu.c.

I changed to this in response to some feedback on the RFC, about
mixing bitwise ops and bools, but I like the |= syntax more as well.

>
> > +static bool clear_dirty_gfn_range(struct kvm *kvm, struct kvm_mmu_page *root,
> > + gfn_t start, gfn_t end)
> > ...
> > + __handle_changed_spte(kvm, as_id, iter.gfn, iter.old_spte,
> > + new_spte, iter.level);
> > + handle_changed_spte_acc_track(iter.old_spte, new_spte,
> > + iter.level);
>
> Is it worth not calling handle_changed_spte? handle_changed_spte_dlog
> obviously will never fire but duplicating the code is a bit ugly.
>
> I guess this patch is the first one that really gives the "feeling" of
> what the data structures look like. The main difference with the shadow
> MMU is that you have the tdp_iter instead of the callback-based code of
> slot_handle_level_range, but otherwise it's not hard to follow one if
> you know the other. Reorganizing the code so that mmu.c is little more
> than a wrapper around the two will help as well in this respect.
>
> Paolo
>