[PATCH v2 3/3] KVM: arm64: Don't replace a valid hyp block mapping with a table

From: Xuheng Li via B4 Relay

Date: Thu Nov 05 2026 - 18:00:09 EST


From: Xuheng Li <xuheng@xxxxxxxxxxxxxxx>

When kvm_pgtable_hyp_map() is asked to map part of a range that a valid
block mapping already covers, hyp_map_walker_try_leaf() declines, as the
request cannot be a leaf at the block's level. hyp_map_walker() then
allocates a zeroed table and stores it over the valid block entry. The
walk descends into the new table and maps the requested pages, but the
rest of the block is now unmapped, and the valid block was replaced
without break-before-make.

No in-tree caller maps into an existing hyp block mapping today, so this
cannot be triggered in mainline. Fail such a request with -EEXIST
instead, so that a future caller gets an error rather than silently
losing the rest of the block.

Signed-off-by: Xuheng Li <xuheng@xxxxxxxxxxxxxxx>
---
arch/arm64/kvm/hyp/pgtable.c | 7 +++++++
1 file changed, 7 insertions(+)

diff --git a/arch/arm64/kvm/hyp/pgtable.c b/arch/arm64/kvm/hyp/pgtable.c
index 9c83837b1..4c731b101 100644
--- a/arch/arm64/kvm/hyp/pgtable.c
+++ b/arch/arm64/kvm/hyp/pgtable.c
@@ -434,6 +434,13 @@ static int hyp_map_walker(const struct kvm_pgtable_visit_ctx *ctx,
if (WARN_ON(ctx->level == KVM_PGTABLE_LAST_LEVEL))
return -EINVAL;

+ /*
+ * Replacing a valid block with a table would need break-before-make,
+ * and the new table would leave the rest of the block unmapped.
+ */
+ if (WARN_ON(kvm_pte_valid(ctx->old)))
+ return -EEXIST;
+
childp = (kvm_pte_t *)mm_ops->zalloc_page(NULL);
if (!childp)
return -ENOMEM;

--
2.53.0