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

Oliver Upton oupton at kernel.org
Tue Nov 3 08:47:31 PST 2026


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



More information about the linux-arm-kernel mailing list