Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/3] Fix __pkvm_init_vm error path
@ 2026-05-21 14:33 Vincent Donnefort
  2026-05-21 14:33 ` [PATCH v3 1/3] KVM: arm64: Reset page order in pKVM hyp_pool Vincent Donnefort
  2026-05-21 14:44 ` [PATCH v3 0/3] Fix __pkvm_init_vm error path Marc Zyngier
  0 siblings, 2 replies; 3+ messages in thread
From: Vincent Donnefort @ 2026-05-21 14:33 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	Vincent Donnefort

Sashiko reported a potential refcount leak in the unlikely case where
insert_vm_table_entry fails.

While at it, I have added a fail-safe to __pkvm_hyp_donate_host to ensure this
function doesn't allow leaking refcounted pages.

Changes since v3:
 
  * Enforce order-0 for external pages, making the vmemmap ->order field
    completely private to hyp_pool.

Changes since v2 (https://lore.kernel.org/all/20260521102149.804874-1-vdonnefort@google.com/):
  
  * Proactively init hyp_page order field in hyp_pool_init  

v1 (https://lore.kernel.org/all/20260521081250.655226-1-vdonnefort@google.com/)

Vincent Donnefort (3):
  KVM: arm64: Reset page order in pKVM hyp_pool
  KVM: arm64: Fix __pkvm_init_vm error path
  KVM: arm64: Add fail-safe for refcounted pages in
    __pkvm_hyp_donate_host

 arch/arm64/kvm/hyp/include/nvhe/mem_protect.h |  1 +
 arch/arm64/kvm/hyp/nvhe/mem_protect.c         | 35 +++++++++++++------
 arch/arm64/kvm/hyp/nvhe/page_alloc.c          | 21 ++++++++---
 arch/arm64/kvm/hyp/nvhe/pkvm.c                |  4 ++-
 4 files changed, 45 insertions(+), 16 deletions(-)


base-commit: 5200f5f493f79f14bbdc349e402a40dfb32f23c8
-- 
2.54.0.746.g67dd491aae-goog



^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v3 1/3] KVM: arm64: Reset page order in pKVM hyp_pool
  2026-05-21 14:33 [PATCH v3 0/3] Fix __pkvm_init_vm error path Vincent Donnefort
@ 2026-05-21 14:33 ` Vincent Donnefort
  2026-05-21 14:44 ` [PATCH v3 0/3] Fix __pkvm_init_vm error path Marc Zyngier
  1 sibling, 0 replies; 3+ messages in thread
From: Vincent Donnefort @ 2026-05-21 14:33 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	Vincent Donnefort, Sashiko

When a VM fails to initialise after its stage-2 hyp_pool has been
initialised, that stage-2 must be torn down entirely. This requires
resetting both the refcount and the order of its pages back to 0.

Currently, reclaim_pgtable_pages() implicitly resets the page order by
allocating the entire pool with order-0 granularity. However, in the VM
initialisation error path, the addresses of the donated memory (the PGD)
are already known, making it unnecessary to iterate over all pages in
the pool.

Since the vmemmap page order is a hyp_pool-specific field, leaving a
non-zero order on hyp_pool destruction is harmless until another pool
attempts to admit the page. Instead of resetting this field during
destruction, reset it during pool initialization in hyp_pool_init().

For 'external' pages, we can't trust the order either as they bypass
hyp_pool_init(). Since we never coalesce them, enforce order-0 to ensure
safe insertion into the pool.

This leaves no vmemmap order users outside of hyp_pool.

Fixes: 256b4668cd89 ("KVM: arm64: Introduce separate hypercalls for pKVM VM reservation and initialization")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>

diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index 25f04629014e..fa447d400b71 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -217,7 +217,6 @@ static void *guest_s2_zalloc_page(void *mc)
 	memset(addr, 0, PAGE_SIZE);
 	p = hyp_virt_to_page(addr);
 	p->refcount = 1;
-	p->order = 0;
 
 	return addr;
 }
@@ -322,7 +321,6 @@ void reclaim_pgtable_pages(struct pkvm_hyp_vm *vm, struct kvm_hyp_memcache *mc)
 	while (addr) {
 		page = hyp_virt_to_page(addr);
 		page->refcount = 0;
-		page->order = 0;
 		push_hyp_memcache(mc, addr, hyp_virt_to_phys);
 		WARN_ON(__pkvm_hyp_donate_host(hyp_virt_to_pfn(addr), 1));
 		addr = hyp_alloc_pages(&vm->pool, 0);
diff --git a/arch/arm64/kvm/hyp/nvhe/page_alloc.c b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
index a1eb27a1a747..57f86aa0f82f 100644
--- a/arch/arm64/kvm/hyp/nvhe/page_alloc.c
+++ b/arch/arm64/kvm/hyp/nvhe/page_alloc.c
@@ -94,13 +94,22 @@ static void __hyp_attach_page(struct hyp_pool *pool,
 			      struct hyp_page *p)
 {
 	phys_addr_t phys = hyp_page_to_phys(p);
-	u8 order = p->order;
 	struct hyp_page *buddy;
+	bool coalesce = true;
+	u8 order = p->order;
 
-	memset(hyp_page_to_virt(p), 0, PAGE_SIZE << p->order);
+	/*
+	 * 'external' pages are never coalesced and their ->order field
+	 * untrusted as they bypass hyp_pool_init(). Enforce order-0.
+	 */
+	if (phys < pool->range_start || phys >= pool->range_end) {
+		order = 0;
+		coalesce = false;
+	}
+
+	memset(hyp_page_to_virt(p), 0, PAGE_SIZE << order);
 
-	/* Skip coalescing for 'external' pages being freed into the pool. */
-	if (phys < pool->range_start || phys >= pool->range_end)
+	if (!coalesce)
 		goto insert;
 
 	/*
@@ -237,8 +246,10 @@ int hyp_pool_init(struct hyp_pool *pool, u64 pfn, unsigned int nr_pages,
 
 	/* Init the vmemmap portion */
 	p = hyp_phys_to_page(phys);
-	for (i = 0; i < nr_pages; i++)
+	for (i = 0; i < nr_pages; i++) {
 		hyp_set_page_refcounted(&p[i]);
+		p[i].order = 0;
+	}
 
 	/* Attach the unused pages to the buddy tree */
 	for (i = reserved_pages; i < nr_pages; i++)
-- 
2.54.0.746.g67dd491aae-goog



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v3 0/3] Fix __pkvm_init_vm error path
  2026-05-21 14:33 [PATCH v3 0/3] Fix __pkvm_init_vm error path Vincent Donnefort
  2026-05-21 14:33 ` [PATCH v3 1/3] KVM: arm64: Reset page order in pKVM hyp_pool Vincent Donnefort
@ 2026-05-21 14:44 ` Marc Zyngier
  1 sibling, 0 replies; 3+ messages in thread
From: Marc Zyngier @ 2026-05-21 14:44 UTC (permalink / raw)
  To: Vincent Donnefort
  Cc: oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, linux-arm-kernel, kvmarm, kernel-team,
	qperret, tabba

On Thu, 21 May 2026 15:33:15 +0100,
Vincent Donnefort <vdonnefort@google.com> wrote:
> 
> Sashiko reported a potential refcount leak in the unlikely case where
> insert_vm_table_entry fails.
> 
> While at it, I have added a fail-safe to __pkvm_hyp_donate_host to ensure this
> function doesn't allow leaking refcounted pages.
> 
> Changes since v3:
>  
>   * Enforce order-0 for external pages, making the vmemmap ->order field
>     completely private to hyp_pool.

You send 3 versions of a single series in a matter of hours. How about
taking a step back and working out the problems before posting?

Please? It's not like my inbox is not overflowing already...

	M.

-- 
Without deviation from the norm, progress is not possible.


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-05-21 14:45 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-21 14:33 [PATCH v3 0/3] Fix __pkvm_init_vm error path Vincent Donnefort
2026-05-21 14:33 ` [PATCH v3 1/3] KVM: arm64: Reset page order in pKVM hyp_pool Vincent Donnefort
2026-05-21 14:44 ` [PATCH v3 0/3] Fix __pkvm_init_vm error path Marc Zyngier

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox