Re: [PATCH 1/3] KVM: arm64: Don't walk the whole IPA space when destroying a pKVM stage-2

From: Oliver Upton

Date: Tue Nov 03 2026 - 11:53:55 EST


On Tue, Nov 03, 2026 at 04:37:54PM +0000, Vincent Donnefort wrote:
> > @@ -513,10 +514,18 @@ void pkvm_pgtable_stage2_destroy_range(struct kvm_pgtable *pgt,
> > kvm->arch.pkvm.is_dying = true;
> > }
> >
> > - if (kvm_vm_is_protected(kvm))
> > - __pkvm_pgtable_stage2_reclaim(pgt, addr, addr + size);
> > - else
> > - __pkvm_pgtable_stage2_unshare(pgt, addr, addr + size);
> > + /* Called once for the whole IPA space, so reschedule between mappings */
> > + for_each_mapping_in_range_safe(pgt, addr, addr + size, mapping) {
> > + u64 start = __pkvm_mapping_start(mapping);
> > + u64 end = __pkvm_mapping_end(mapping) + 1;
> > +
> > + if (kvm_vm_is_protected(kvm))
> > + __pkvm_pgtable_stage2_reclaim(pgt, start, end);
> > + else
> > + __pkvm_pgtable_stage2_unshare(pgt, start, end);
> > +
> > + cond_resched();
> > + }
> > }
>
> Just thought that it is a bit weird that pkvm_pgtable_stage2_destroy_range()
> does cond_resched() while kvm_pgtable_stage2_destroy_range() does not.
>
> How about instead kvm_stage2_destroy() refines start/end with some accessors
> calling in pkvm.c pkvm_mapping_iter_first() / pkvm_mapping_iter_last()?

Yeah, I'd rather we tackle this as a general problem than doing some
pKVM specific hacks.

Seems to me that we do a lot of wasted work even in the non-pKVM case
where the outer loop will continue to iterate KVM_PGTABLE_MIN_BLOCK_LEVEL
worth of IPA even if the underlying table is empty.

What we'd want is for the kvm_pgtable_stage2_destroy_range()
implementation to report back how much of the IPA space it actually
iterated over. We wouldn't want to keep re-visiting the same invalid PGD
entry only because it's larger than our max block size.

Thanks,
Oliver