From: Fuad Tabba <fuad.tabba@linux.dev>
To: Marc Zyngier <maz@kernel.org>, Oliver Upton <oupton@kernel.org>
Cc: "Will Deacon" <will@kernel.org>,
"Catalin Marinas" <catalin.marinas@arm.com>,
"Joey Gouly" <joey.gouly@arm.com>,
"Mark Rutland" <mark.rutland@arm.com>,
"Suzuki K Poulose" <suzuki.poulose@arm.com>,
"Raghavendra Rao Ananta" <rananta@google.com>,
"Sascha Bischoff" <Sascha.Bischoff@arm.com>,
"Thomas Gleixner" <tglx@kernel.org>,
"Sebastian Ene" <sebastianene@google.com>,
"Bartłomiej Grzesik" <bgrzesik@google.com>,
"Mostafa Saleh" <smostafa@google.com>,
"Vincent Donnefort" <vdonnefort@google.com>,
"Vladimir Murzin" <vladimir.murzin@arm.com>,
"Zenghui Yu" <yuzenghui@huawei.com>,
"Zenghui Yu" <zenghui.yu@linux.dev>,
"Steffen Eiden" <seiden@linux.ibm.com>,
"Radu Rendec" <radu@rendec.net>, "Fuad Tabba" <tabba@google.com>,
kvmarm@lists.linux.dev, linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org
Subject: [PATCH v3 02/13] KVM: arm64: Take host-registered MMIO regions at pKVM finalisation
Date: Mon, 2 Nov 2026 13:01:22 +0000 [thread overview]
Message-ID: <20261102130133.3684226-3-fuad.tabba@linux.dev> (raw)
In-Reply-To: <20261102130133.3684226-1-fuad.tabba@linux.dev>
From: Sebastian Ene <sebastianene@google.com>
To mediate a device, the protected KVM hypervisor has to own its
registers, so that a host access to them takes a stage-2 abort rather
than reaching the device.
Let the host register MMIO regions before the hypervisor initialises,
and have __pkvm_init_finalise() donate each one and record where it's
mapped in the hypervisor's private range. The donation runs before
pkvm_check_host_ownership(), which then covers those mappings too. A
failed donation fails the hypervisor's initialisation before the host
stage 2 is installed, so nothing is given back.
Nothing registers a region yet.
Signed-off-by: Sebastian Ene <sebastianene@google.com>
Co-developed-by: Fuad Tabba <fuad.tabba@linux.dev>
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
Notes:
Changes since v2 (v2 patches 02 and 03, merged):
- The trap handling moved to patch 9, which calls the ITS emulation
directly (was a per-region callback)
- Each region records its hypervisor VA
- A failed donation is no longer unwound
arch/arm64/include/asm/kvm_pkvm.h | 12 ++++++++++++
arch/arm64/kvm/hyp/nvhe/mem_protect.c | 3 +++
arch/arm64/kvm/hyp/nvhe/setup.c | 22 ++++++++++++++++++++++
3 files changed, 37 insertions(+)
diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h
index fd042d2b54624..4695c35b31e1a 100644
--- a/arch/arm64/include/asm/kvm_pkvm.h
+++ b/arch/arm64/include/asm/kvm_pkvm.h
@@ -17,6 +17,18 @@
#define HYP_MEMBLOCK_REGIONS 128
+/* MMIO regions the host registers for the hypervisor to take at finalisation. */
+#define PKVM_PROTECTED_REGS_NUM 8
+
+struct pkvm_protected_reg {
+ u64 pfn;
+ u64 nr_pages;
+ void __iomem *hyp_va;
+};
+
+extern struct pkvm_protected_reg kvm_nvhe_sym(pkvm_protected_regs)[];
+extern unsigned int kvm_nvhe_sym(num_protected_reg);
+
int pkvm_init_host_vm(struct kvm *kvm);
int pkvm_create_hyp_vm(struct kvm *kvm);
bool pkvm_hyp_vm_is_created(struct kvm *kvm);
diff --git a/arch/arm64/kvm/hyp/nvhe/mem_protect.c b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
index a6dacaca77610..8d45f45d30e6a 100644
--- a/arch/arm64/kvm/hyp/nvhe/mem_protect.c
+++ b/arch/arm64/kvm/hyp/nvhe/mem_protect.c
@@ -28,6 +28,9 @@ struct host_mmu host_mmu;
static struct hyp_pool host_s2_pool;
+unsigned int num_protected_reg;
+struct pkvm_protected_reg pkvm_protected_regs[PKVM_PROTECTED_REGS_NUM];
+
static DEFINE_PER_CPU(struct pkvm_hyp_vm *, __current_vm);
#define current_vm (*this_cpu_ptr(&__current_vm))
diff --git a/arch/arm64/kvm/hyp/nvhe/setup.c b/arch/arm64/kvm/hyp/nvhe/setup.c
index 7bbc26b28faa5..18f348d1331a8 100644
--- a/arch/arm64/kvm/hyp/nvhe/setup.c
+++ b/arch/arm64/kvm/hyp/nvhe/setup.c
@@ -295,6 +295,24 @@ static int fix_hyp_pgtable_refcnt(void)
&walker);
}
+static int donate_protected_mmio_regions(void)
+{
+ struct pkvm_protected_reg *region;
+ unsigned long haddr;
+ int ret, i;
+
+ for (i = 0; i < num_protected_reg; i++) {
+ region = &pkvm_protected_regs[i];
+ ret = __pkvm_host_donate_hyp_mmio(region->pfn, region->nr_pages, &haddr);
+ if (ret)
+ return ret;
+
+ region->hyp_va = (void __iomem *)haddr;
+ }
+
+ return 0;
+}
+
void __noreturn __pkvm_init_finalise(void)
{
struct kvm_cpu_context *host_ctxt = host_data_ptr(host_ctxt);
@@ -335,6 +353,10 @@ void __noreturn __pkvm_init_finalise(void)
if (ret)
goto out;
+ ret = donate_protected_mmio_regions();
+ if (ret)
+ goto out;
+
ret = pkvm_check_host_ownership();
if (ret)
goto out;
--
2.47.3
next prev parent reply other threads:[~2026-11-02 13:01 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 13:01 [PATCH v3 00/13] KVM: ITS hardening for pKVM Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 01/13] KVM: arm64: Donate MMIO to the hypervisor Fuad Tabba
2026-11-02 13:01 ` Fuad Tabba [this message]
2026-11-02 13:01 ` [PATCH v3 03/13] irqchip/gic-v3: Disable GICv4 features in protected KVM mode Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 04/13] irqchip/gic-v3-its: Page-align ITT allocations under protected KVM Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 05/13] irqchip/gic-v3-its: Compute the wait target under the ITS lock Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 06/13] KVM: arm64: Share the ITS command field accessors with the hypervisor Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 07/13] KVM: arm64: Deprivilege the host under stop_machine() Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 08/13] irqchip/gic-v3-its: Add the protected-KVM takeover entry points Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 09/13] KVM: arm64: Emulate the ITS command queue Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 10/13] KVM: arm64: Take the ITS tables and restrict GITS_BASER<n> Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 11/13] KVM: arm64: Take the ITT for the lifetime of a device mapping Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 12/13] KVM: arm64: Reject ITS commands whose IDs are out of range Fuad Tabba
2026-11-02 13:01 ` [PATCH v3 13/13] Documentation: KVM: arm64: Describe the ITS hardening 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=20261102130133.3684226-3-fuad.tabba@linux.dev \
--to=fuad.tabba@linux.dev \
--cc=Sascha.Bischoff@arm.com \
--cc=bgrzesik@google.com \
--cc=catalin.marinas@arm.com \
--cc=joey.gouly@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=maz@kernel.org \
--cc=oupton@kernel.org \
--cc=radu@rendec.net \
--cc=rananta@google.com \
--cc=sebastianene@google.com \
--cc=seiden@linux.ibm.com \
--cc=smostafa@google.com \
--cc=suzuki.poulose@arm.com \
--cc=tabba@google.com \
--cc=tglx@kernel.org \
--cc=vdonnefort@google.com \
--cc=vladimir.murzin@arm.com \
--cc=will@kernel.org \
--cc=yuzenghui@huawei.com \
--cc=zenghui.yu@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.