Skip to content

Commit c35dd83

Browse files
mukeshojha-linuxMarc Zyngier
authored andcommitted
KVM: arm64: Guard PMSCR_EL1 initialization with SPE presence check
Commit efad60e ("KVM: arm64: Initialize PMSCR_EL1 when in VHE") does not perform sufficient check before initializing PMSCR_EL1 to 0 when running in VHE mode. On some platforms, this causes the system to hang during boot, as EL3 has not delegated access to the Profiling Buffer to the Non-secure world, nor does it reinject an UNDEF on sysreg trap. To avoid this issue, restrict the PMSCR_EL1 initialization to CPUs that support Statistical Profiling Extension (FEAT_SPE) and have the Profiling Buffer accessible in Non-secure EL1. This is determined via a new helper `cpu_has_spe()` which checks both PMSVer and PMBIDR_EL1.P. This ensures the initialization only affects CPUs where SPE is implemented and usable, preventing boot failures on platforms where SPE is not properly configured. Fixes: efad60e ("KVM: arm64: Initialize PMSCR_EL1 when in VHE") Signed-off-by: Mukesh Ojha <mukesh.ojha@oss.qualcomm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent 9a7f87e commit c35dd83

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

arch/arm64/kvm/debug.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@
1515
#include <asm/kvm_arm.h>
1616
#include <asm/kvm_emulate.h>
1717

18+
static int cpu_has_spe(u64 dfr0)
19+
{
20+
return cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) &&
21+
!(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P);
22+
}
23+
1824
/**
1925
* kvm_arm_setup_mdcr_el2 - configure vcpu mdcr_el2 value
2026
*
@@ -77,13 +83,12 @@ void kvm_init_host_debug_data(void)
7783
*host_data_ptr(debug_brps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, BRPs, dfr0);
7884
*host_data_ptr(debug_wrps) = SYS_FIELD_GET(ID_AA64DFR0_EL1, WRPs, dfr0);
7985

86+
if (cpu_has_spe(dfr0))
87+
host_data_set_flag(HAS_SPE);
88+
8089
if (has_vhe())
8190
return;
8291

83-
if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_PMSVer_SHIFT) &&
84-
!(read_sysreg_s(SYS_PMBIDR_EL1) & PMBIDR_EL1_P))
85-
host_data_set_flag(HAS_SPE);
86-
8792
/* Check if we have BRBE implemented and available at the host */
8893
if (cpuid_feature_extract_unsigned_field(dfr0, ID_AA64DFR0_EL1_BRBE_SHIFT))
8994
host_data_set_flag(HAS_BRBE);
@@ -102,7 +107,7 @@ void kvm_init_host_debug_data(void)
102107
void kvm_debug_init_vhe(void)
103108
{
104109
/* Clear PMSCR_EL1.E{0,1}SPE which reset to UNKNOWN values. */
105-
if (SYS_FIELD_GET(ID_AA64DFR0_EL1, PMSVer, read_sysreg(id_aa64dfr0_el1)))
110+
if (host_data_test_flag(HAS_SPE))
106111
write_sysreg_el1(0, SYS_PMSCR);
107112
}
108113

0 commit comments

Comments
 (0)