mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM
@ 2026-09-14  6:51 Fuad Tabba
  0 siblings, 0 replies; only message in thread
From: Fuad Tabba @ 2026-09-14  6:51 UTC (permalink / raw)
  To: maz, oupton, kvmarm, linux-arm-kernel, linux-kernel
  Cc: catalin.marinas, will, joey.gouly, seiden, suzuki.poulose,
	yuzenghui, mark.rutland, vdonnefort, qperret, tabba

Under pKVM, a page the host shares with EL2 is mapped at EL2 only while
it's pinned, and the host vCPU and its VM are pinned at the vCPU's
first KVM_RUN. KVM_SET_VCPU_EVENTS with ext_dabt_pending reaches
__kvm_adjust_pc() at EL2 before that, and dereferencing the unmapped
host vCPU panics the hypervisor. Any process holding /dev/kvm on a
pKVM host can trigger it.

Pin the host vCPU around the adjustment when no hyp vCPU is loaded for
it, and its VM too, for the MTE flag the exception entry reads. A
loaded hyp vCPU implies both are pinned. A pin fails only for memory
the host never shared, and the request is then dropped like any other
bad host pointer.

Fixes: efa1368ba9f4b ("KVM: arm64: Commit exceptions from KVM_SET_VCPU_EVENTS immediately")
Cc: stable@vger.kernel.org
Signed-off-by: Fuad Tabba <fuad.tabba@linux.dev>
---
 arch/arm64/kvm/hyp/nvhe/hyp-main.c | 30 +++++++++++++++++++++++++++++-
 1 file changed, 29 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index 9a3b92e626adb..e41b4c181eb62 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -539,11 +539,39 @@ static void handle___pkvm_host_mkyoung_guest(struct kvm_cpu_context *host_ctxt)
 	cpu_reg(host_ctxt, 1) =  ret;
 }
 
+/*
+ * With no hyp vCPU loaded for it, the host vCPU and its VM may be unpinned,
+ * and so unmapped at EL2: both are pinned from the vCPU's first run, and
+ * KVM_SET_VCPU_EVENTS can reach here before that.
+ */
+static void adjust_pc_unloaded(struct kvm_vcpu *host_vcpu)
+{
+	struct kvm *host_kvm;
+
+	if (hyp_pin_shared_mem(host_vcpu, host_vcpu + 1))
+		return;
+
+	/* The exception entry reads the VM's MTE flag. */
+	host_kvm = kern_hyp_va(host_vcpu->kvm);
+	if (!hyp_pin_shared_mem(host_kvm, host_kvm + 1)) {
+		__kvm_adjust_pc(host_vcpu);
+		hyp_unpin_shared_mem(host_kvm, host_kvm + 1);
+	}
+
+	hyp_unpin_shared_mem(host_vcpu, host_vcpu + 1);
+}
+
 static void handle___kvm_adjust_pc(struct kvm_cpu_context *host_ctxt)
 {
 	DECLARE_REG(struct kvm_vcpu *, vcpu, host_ctxt, 1);
+	struct pkvm_hyp_vcpu *hyp_vcpu;
+	struct kvm_vcpu *host_vcpu;
 
-	__kvm_adjust_pc(kern_hyp_va(vcpu));
+	host_vcpu = __get_host_hyp_vcpus(vcpu, &hyp_vcpu);
+	if (host_vcpu)
+		__kvm_adjust_pc(host_vcpu);
+	else
+		adjust_pc_unloaded(kern_hyp_va(vcpu));
 }
 
 static void handle___kvm_flush_vm_context(struct kvm_cpu_context *host_ctxt)

base-commit: fd73f4a6659897191fa0d40695fe370925dd3780
-- 
2.39.5


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-09-14  6:51 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-14  6:51 [PATCH] KVM: arm64: Pin the host vCPU before adjusting its PC under pKVM Fuad Tabba

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

all inboxes | Powered by JetHome®