public inbox for linux-arm-kernel@lists.infradead.org 
 help / color / mirror / Atom feed
From: Vincent Donnefort <vdonnefort@google•com>
To: maz@kernel•org, oliver.upton@linux•dev, joey.gouly@arm•com,
	 suzuki.poulose@arm•com, yuzenghui@huawei•com,
	catalin.marinas@arm•com,  will@kernel•org
Cc: linux-arm-kernel@lists•infradead.org, kvmarm@lists•linux.dev,
	 kernel-team@android•com, qperret@google•com, tabba@google•com,
	 Vincent Donnefort <vdonnefort@google•com>
Subject: [PATCH v2 3/3] KVM: arm64: Add fail-safe for refcounted pages in __pkvm_hyp_donate_host
Date: Thu, 21 May 2026 11:21:49 +0100	[thread overview]
Message-ID: <20260521102149.804874-4-vdonnefort@google.com> (raw)
In-Reply-To: <20260521102149.804874-1-vdonnefort@google.com>

A previous bug in __pkvm_init_vm error path showed that the hypervisor
could leak refcounted pages, (i.e. losing access to a page while its
refcount is still elevated). This poses a threat to the pKVM state
machine.

Address this by introducing a fail-safe in n __pkvm_hyp_donate_host.
Transitions are not a hot path so added security is worth the extra
check.

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 42b0b648f32f..bb97d05b9b25 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -855,6 +855,16 @@ static int __hyp_check_page_state_range(phys_addr_t phys, u64 size, enum pkvm_pa
 	return 0;
 }
 
+static int __hyp_check_page_count_range(phys_addr_t phys, u64 size)
+{
+	for_each_hyp_page(page, phys, size) {
+		if (page->refcount)
+			return -EBUSY;
+	}
+
+	return 0;
+}
+
 static bool guest_pte_is_poisoned(kvm_pte_t pte)
 {
 	if (kvm_pte_valid(pte))
@@ -1053,7 +1063,6 @@ int __pkvm_guest_unshare_host(struct pkvm_hyp_vcpu *vcpu, u64 gfn)
 int __pkvm_host_unshare_hyp(u64 pfn)
 {
 	u64 phys = hyp_pfn_to_phys(pfn);
-	u64 virt = (u64)__hyp_va(phys);
 	u64 size = PAGE_SIZE;
 	int ret;
 
@@ -1066,10 +1075,9 @@ int __pkvm_host_unshare_hyp(u64 pfn)
 	ret = __hyp_check_page_state_range(phys, size, PKVM_PAGE_SHARED_BORROWED);
 	if (ret)
 		goto unlock;
-	if (hyp_page_count((void *)virt)) {
-		ret = -EBUSY;
+	ret = __hyp_check_page_count_range(phys, size);
+	if (ret)
 		goto unlock;
-	}
 
 	__hyp_set_page_state_range(phys, size, PKVM_NOPAGE);
 	WARN_ON(__host_set_page_state_range(phys, size, PKVM_PAGE_OWNED));
@@ -1132,6 +1140,10 @@ int __pkvm_hyp_donate_host(u64 pfn, u64 nr_pages)
 	if (ret)
 		goto unlock;
 
+	ret = __hyp_check_page_count_range(phys, size);
+	if (ret)
+		goto unlock;
+
 	__hyp_set_page_state_range(phys, size, PKVM_NOPAGE);
 	WARN_ON(kvm_pgtable_hyp_unmap(&pkvm_pgtable, virt, size) != size);
 	WARN_ON(host_stage2_set_owner_locked(phys, size, PKVM_ID_HOST));
-- 
2.54.0.746.g67dd491aae-goog



  parent reply	other threads:[~2026-05-21 10:22 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-21 10:21 [PATCH v2 0/3] Fix __pkvm_init_vm error path Vincent Donnefort
2026-05-21 10:21 ` [PATCH v2 1/3] KVM: arm64: Reset page order in pKVM hyp_pool_init Vincent Donnefort
2026-05-21 13:07   ` Fuad Tabba
2026-05-21 13:21     ` Vincent Donnefort
2026-05-21 13:30       ` Fuad Tabba
2026-05-21 10:21 ` [PATCH v2 2/3] KVM: arm64: Fix __pkvm_init_vm error path Vincent Donnefort
2026-05-21 13:07   ` Fuad Tabba
2026-05-21 10:21 ` Vincent Donnefort [this message]
2026-05-21 13:07   ` [PATCH v2 3/3] KVM: arm64: Add fail-safe for refcounted pages in __pkvm_hyp_donate_host Fuad Tabba
2026-05-21 13:07 ` [PATCH v2 0/3] Fix __pkvm_init_vm error path Fuad Tabba

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260521102149.804874-4-vdonnefort@google.com \
    --to=vdonnefort@google$(echo .)com \
    --cc=catalin.marinas@arm$(echo .)com \
    --cc=joey.gouly@arm$(echo .)com \
    --cc=kernel-team@android$(echo .)com \
    --cc=kvmarm@lists$(echo .)linux.dev \
    --cc=linux-arm-kernel@lists$(echo .)infradead.org \
    --cc=maz@kernel$(echo .)org \
    --cc=oliver.upton@linux$(echo .)dev \
    --cc=qperret@google$(echo .)com \
    --cc=suzuki.poulose@arm$(echo .)com \
    --cc=tabba@google$(echo .)com \
    --cc=will@kernel$(echo .)org \
    --cc=yuzenghui@huawei$(echo .)com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox