From 0fa4e506a054702d03d46aac9272a37f820fc2e5 Mon Sep 17 00:00:00 2001 From: Vincent Donnefort Date: Mon, 19 Oct 2026 10:42:58 +0100 Subject: [PATCH] KVM: arm64: Move pkvm_selftests() after all CPUs have initialized EL2 init_subsystems() installs the hyp vector on all CPUs. By running pkvm_selftests() in init_hyp_mode(), there's a risk for a migration to a CPU where the hyp stub is still in place which would fail to run one of the HVCs necessary for the selftest. While init_subsystems() is the earliest we can call pkvm_selftests(), move it to finalize_pkvm() to avoid having to export the selftest function out of pkvm.c. Fixes: bd93068340e9 ("KVM: arm64: Add selftests for the pKVM heap allocator") Reported-by: Fuad Tabba Signed-off-by: Vincent Donnefort Reviewed-by: Fuad Tabba Tested-by: Fuad Tabba Link: https://patch.msgid.link/20261019094258.1582756-1-vdonnefort@google.com Signed-off-by: Marc Zyngier --- arch/arm64/include/asm/kvm_pkvm.h | 1 - arch/arm64/kvm/arm.c | 2 -- arch/arm64/kvm/pkvm.c | 4 +++- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm64/include/asm/kvm_pkvm.h b/arch/arm64/include/asm/kvm_pkvm.h index e7562770e7cb..fd042d2b5462 100644 --- a/arch/arm64/include/asm/kvm_pkvm.h +++ b/arch/arm64/include/asm/kvm_pkvm.h @@ -17,7 +17,6 @@ #define HYP_MEMBLOCK_REGIONS 128 -void pkvm_selftests(void); 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/arm.c b/arch/arm64/kvm/arm.c index 775d11f96813..57332bbba9d5 100644 --- a/arch/arm64/kvm/arm.c +++ b/arch/arm64/kvm/arm.c @@ -3109,8 +3109,6 @@ static int __init init_hyp_mode(void) kvm_err("Failed to init hyp memory protection\n"); goto out_err; } - - pkvm_selftests(); } return 0; diff --git a/arch/arm64/kvm/pkvm.c b/arch/arm64/kvm/pkvm.c index 380dfb1db0be..016997288fd2 100644 --- a/arch/arm64/kvm/pkvm.c +++ b/arch/arm64/kvm/pkvm.c @@ -333,7 +333,7 @@ static int __init pkvm_drop_host_privileges(void) return ret; } -void __init pkvm_selftests(void) +static void __init pkvm_selftests(void) { #ifdef CONFIG_NVHE_EL2_DEBUG int ret = pkvm_call_hyp_req(__pkvm_hyp_alloc_selftest); @@ -387,6 +387,8 @@ static int __init finalize_pkvm(void) if (!is_protected_kvm_enabled() || !is_kvm_arm_initialised()) return 0; + pkvm_selftests(); + /* * Exclude HYP sections from kmemleak so that they don't get peeked * at, which would end badly once inaccessible.