[PATCH v22 10/23] KVM: arm64: Consolidate stage2 unmap range into kvm_stage2_unmap_range

From: Suzuki K Poulose

Date: Mon Oct 05 2026 - 05:15:29 EST


In preparation for adding VM specific backends for stage2 operations,
nuke __unmap_stage2_range() and fold the logic into
kvm_stage2_unmap_range(). Also, make kvm_unmap_gfn_range(), the only other
user of the __unmap_stage2_range() call the kvm_stage2_unmap_range(). Also,
while at it fix the comment to make it clear that mmu_lock must always be
held while unmapping. The code already mandates that and the two call paths
do have the write mmu_lock held.

Later we would replace the logic in kvm_stage2_unmap_range() with VM
specific backends.

No functional changes intended.

Signed-off-by: Suzuki K Poulose <suzuki.poulose@xxxxxxx>
---
Change since v21:
- Nuke __unmap_stage2_range and consolidate the stage2_unmap_range logic
into kvm_stage2_unmap_range(), in preparation for removing the KVM_PGT_FN()
for stage2_unmap
---
arch/arm64/kvm/mmu.c | 38 ++++++++++++++++----------------------
1 file changed, 16 insertions(+), 22 deletions(-)

diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c
index 0f4e8b71fa85d..4ae3bb6baef1a 100644
--- a/arch/arm64/kvm/mmu.c
+++ b/arch/arm64/kvm/mmu.c
@@ -314,36 +314,30 @@ static void invalidate_icache_guest_page(void *va, size_t size)
* does.
*/
/**
- * __unmap_stage2_range -- Clear stage2 page table entries to unmap a range
+ * kvm_stage2_unmap_range -- Clear stage2 page table entries to unmap a range
* @mmu: The KVM stage-2 MMU pointer
* @start: The intermediate physical base address of the range to unmap
* @size: The size of the area to unmap
* @may_block: Whether or not we are permitted to block
*
* Clear a range of stage-2 mappings, lowering the various ref-counts. Must
- * be called while holding mmu_lock (unless for freeing the stage2 pgd before
- * destroying the VM), otherwise another faulting VCPU may come in and mess
- * with things behind our backs.
+ * be called while holding mmu_lock otherwise another faulting VCPU may
+ * come in and mess with things behind our backs.
*/
-static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size,
- bool may_block)
-{
- struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
- phys_addr_t end = start + size;
-
- lockdep_assert_held_write(&kvm->mmu_lock);
- WARN_ON(size & ~PAGE_MASK);
- WARN_ON(stage2_apply_range(mmu, start, end, KVM_PGT_FN(kvm_pgtable_stage2_unmap),
- may_block));
-}
-
void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start,
u64 size, bool may_block)
{
- if (kvm_vm_is_protected(kvm_s2_mmu_to_kvm(mmu)))
+ struct kvm *kvm = kvm_s2_mmu_to_kvm(mmu);
+
+ if (kvm_vm_is_protected(kvm))
return;

- __unmap_stage2_range(mmu, start, size, may_block);
+ lockdep_assert_held_write(&kvm->mmu_lock);
+ WARN_ON(size & ~PAGE_MASK);
+
+ WARN_ON(stage2_apply_range(mmu, start, start + size,
+ KVM_PGT_FN(kvm_pgtable_stage2_unmap),
+ may_block));
}

void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end)
@@ -2436,12 +2430,12 @@ int kvm_handle_guest_abort(struct kvm_vcpu *vcpu)

bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range)
{
- if (!kvm->arch.mmu.pgt || kvm_vm_is_protected(kvm))
+ if (!kvm->arch.mmu.pgt)
return false;

- __unmap_stage2_range(&kvm->arch.mmu, range->start << PAGE_SHIFT,
- (range->end - range->start) << PAGE_SHIFT,
- range->may_block);
+ kvm_stage2_unmap_range(&kvm->arch.mmu, range->start << PAGE_SHIFT,
+ (range->end - range->start) << PAGE_SHIFT,
+ range->may_block);

kvm_nested_s2_unmap(kvm, range->may_block);
return false;
--
2.43.0