Skip to content

Commit e1231aa

Browse files
committed
arm64: Enable IMP DEF PMUv3 traps on Apple M*
Apple M1 and M2 CPUs support IMPDEF traps of the PMUv3 sysregs, allowing a hypervisor to virtualize an architectural PMU for a VM. Flip the appropriate bit in HACR_EL2 on supporting hardware. Tested-by: Janne Grunau <j@jannau.net> Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250305203040.428448-1-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
1 parent 1b92e65 commit e1231aa

File tree

1 file changed

+44
-0
lines changed

1 file changed

+44
-0
lines changed

arch/arm64/kernel/cpu_errata.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,43 @@ has_neoverse_n1_erratum_1542419(const struct arm64_cpu_capabilities *entry,
194194
return is_midr_in_range(midr, &range) && has_dic;
195195
}
196196

197+
static const struct midr_range impdef_pmuv3_cpus[] = {
198+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM),
199+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM),
200+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_PRO),
201+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_PRO),
202+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_ICESTORM_MAX),
203+
MIDR_ALL_VERSIONS(MIDR_APPLE_M1_FIRESTORM_MAX),
204+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD),
205+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE),
206+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_PRO),
207+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_PRO),
208+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_BLIZZARD_MAX),
209+
MIDR_ALL_VERSIONS(MIDR_APPLE_M2_AVALANCHE_MAX),
210+
{},
211+
};
212+
213+
static bool has_impdef_pmuv3(const struct arm64_cpu_capabilities *entry, int scope)
214+
{
215+
u64 dfr0 = read_sanitised_ftr_reg(SYS_ID_AA64DFR0_EL1);
216+
unsigned int pmuver;
217+
218+
if (!is_kernel_in_hyp_mode())
219+
return false;
220+
221+
pmuver = cpuid_feature_extract_unsigned_field(dfr0,
222+
ID_AA64DFR0_EL1_PMUVer_SHIFT);
223+
if (pmuver != ID_AA64DFR0_EL1_PMUVer_IMP_DEF)
224+
return false;
225+
226+
return is_midr_in_range_list(read_cpuid_id(), impdef_pmuv3_cpus);
227+
}
228+
229+
static void cpu_enable_impdef_pmuv3_traps(const struct arm64_cpu_capabilities *__unused)
230+
{
231+
sysreg_clear_set_s(SYS_HACR_EL2, 0, BIT(56));
232+
}
233+
197234
#ifdef CONFIG_ARM64_WORKAROUND_REPEAT_TLBI
198235
static const struct arm64_cpu_capabilities arm64_repeat_tlbi_list[] = {
199236
#ifdef CONFIG_QCOM_FALKOR_ERRATUM_1009
@@ -794,6 +831,13 @@ const struct arm64_cpu_capabilities arm64_errata[] = {
794831
{}
795832
})),
796833
},
834+
{
835+
.desc = "Apple IMPDEF PMUv3 Traps",
836+
.capability = ARM64_WORKAROUND_PMUV3_IMPDEF_TRAPS,
837+
.type = ARM64_CPUCAP_LOCAL_CPU_ERRATUM,
838+
.matches = has_impdef_pmuv3,
839+
.cpu_enable = cpu_enable_impdef_pmuv3_traps,
840+
},
797841
{
798842
}
799843
};

0 commit comments

Comments
 (0)