Re: [PATCH v3 02/21] KVM: arm64: Add stand-alone page-table walker infrastructure

Will Deacon
2020-09-02T10:51:31Z

On Fri, Aug 28, 2020 at 04:51:02PM +0100, Alexandru Elisei wrote:
> On 8/25/20 10:39 AM, Will Deacon wrote:
> > [..]
> > +static void kvm_set_table_pte(kvm_pte_t *ptep, kvm_pte_t *childp)
> > +{
> > + kvm_pte_t old = *ptep, pte = kvm_phys_to_pte(__pa(childp));
> > +
> > + pte |= FIELD_PREP(KVM_PTE_TYPE, KVM_PTE_TYPE_TABLE);
> > + pte |= KVM_PTE_VALID;
> > +
> > + WARN_ON(kvm_pte_valid(old));
> > + smp_store_release(ptep, pte);
> > +}
> > +
> > +static bool kvm_set_valid_leaf_pte(kvm_pte_t *ptep, u64 pa, kvm_pte_t attr,
> > + u32 level)
> > +{
> > + kvm_pte_t old = *ptep, pte = kvm_phys_to_pte(pa);
> > + u64 type = (level == KVM_PGTABLE_MAX_LEVELS - 1) ? KVM_PTE_TYPE_PAGE :
> > + KVM_PTE_TYPE_BLOCK;
> > +
> > + pte |= attr & (KVM_PTE_LEAF_ATTR_LO | KVM_PTE_LEAF_ATTR_HI);
> > + pte |= FIELD_PREP(KVM_PTE_TYPE, type);
> > + pte |= KVM_PTE_VALID;
> > +
> > + /* Tolerate KVM recreating the exact same mapping. */
> > + if (kvm_pte_valid(old))
> > + return old == pte;
> > +
> > + smp_store_release(ptep, pte);
> > + return true;
> > +}
>
> These two functions look inconsistent to me - we refuse to update a valid leaf
> entry with a new value, but we allow updating a valid table. Is there something
> that I'm not taking into account?

Well, the table code will WARN() so it's not like we do it quietly. I could
try to propagate the error, but I don't see what the gains us other than
complexity and code that likely won't get tested.

The leaf case is different, because some callers will handle the failure
and perform break-before-make; TLBI (e.g. because of an MMU notifier
changing the PTE).

Take a look at how stage2_map_walker_try_leaf() ends up being called from
kvm_set_spte_handler().

Will