summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2026-03-10 08:54:33 +0000
committerMarc Zyngier <maz@kernel.org>2026-03-10 09:48:45 +0000
commita79f7b4aeb8e7562cd6dbf9c223e2c2a04b1a85f (patch)
treee8663def3333c048eeb32ce1dce04f8d517116dc /arch
parent6da5e537f5afe091658e846da1949d7e557d2ade (diff)
KVM: arm64: pkvm: Don't reprobe for ICH_VTR_EL2.TDS on CPU hotplug
Hotplugging a CPU off and back on fails with pKVM, as we try to probe for ICH_VTR_EL2.TDS. In a non-VHE setup, this is achieved by using an EL2 stub helper. However, the stubs are out of reach once pKVM has deprivileged the kernel. The CPU never boots. Since pKVM doesn't allow late onlining of CPUs, we can detect that protected mode is enforced early on, and return the current state of the capability. Fixes: 2a28810cbb8b2 ("KVM: arm64: GICv3: Detect and work around the lack of ICV_DIR_EL1 trapping") Reported-by: Vincent Donnefort <vdonnefort@google.com> Tested-by: Vincent Donnefort <vdonnefort@google.com> Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Link: https://patch.msgid.link/20260310085433.3936742-1-maz@kernel.org Cc: stable@vger.kernel.org
Diffstat (limited to 'arch')
-rw-r--r--arch/arm64/kernel/cpufeature.c9
1 files changed, 9 insertions, 0 deletions
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index c31f8e17732a..32c2dbcc0c64 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -2345,6 +2345,15 @@ static bool can_trap_icv_dir_el1(const struct arm64_cpu_capabilities *entry,
!is_midr_in_range_list(has_vgic_v3))
return false;
+ /*
+ * pKVM prevents late onlining of CPUs. This means that whatever
+ * state the capability is in after deprivilege cannot be affected
+ * by a new CPU booting -- this is garanteed to be a CPU we have
+ * already seen, and the cap is therefore unchanged.
+ */
+ if (system_capabilities_finalized() && is_protected_kvm_enabled())
+ return cpus_have_final_cap(ARM64_HAS_ICH_HCR_EL2_TDIR);
+
if (is_kernel_in_hyp_mode())
res.a1 = read_sysreg_s(SYS_ICH_VTR_EL2);
else