Skip to content

Commit 55bb888

Browse files
author
Gavin Shan
committed
arm64: Add override for MPAM
JIRA: https://issues.redhat.com/browse/RHEL-93666 As the message of the commit 09e6b30 ("arm64: cpufeature: discover CPU support for MPAM") already states, if a buggy firmware fails to either enable MPAM or emulate the trap as if it were disabled, the kernel will just fail to boot. While upgrading the firmware should be the best solution, we have some hardware of which the vendor have made no response 2 months after we requested a firmware update. Allow overriding it so our devices don't become some e-waste. Cc: James Morse <james.morse@arm.com> Cc: Marc Zyngier <maz@kernel.org> Cc: Will Deacon <will@kernel.org> Cc: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com> Cc: Mingcong Bai <jeffbai@aosc.io> Cc: Shaopeng Tan <tan.shaopeng@fujitsu.com> Cc: Ben Horgan <ben.horgan@arm.com> Signed-off-by: Xi Ruoyao <xry111@xry111.site> Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250602043723.216338-1-xry111@xry111.site Signed-off-by: Will Deacon <will@kernel.org> (cherry picked from commit 10f885d) Signed-off-by: Gavin Shan <gshan@redhat.com> Conflicts: Documentation/admin-guide/kernel-parameters.txt Contextual conflict due to missed upstream commit eb38cc8 ("Docs: kernel-parameters: sort arm64 entries"). arch/arm64/include/asm/el2_setup.h Contextual conflict due to missed upstream commit ff5181d ("arm64/gcs: Provide basic EL2 setup to allow GCS usage at EL0 and EL1").
1 parent 8a60aab commit 55bb888

File tree

5 files changed

+26
-18
lines changed

5 files changed

+26
-18
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,9 @@
442442
arm64.nopauth [ARM64] Unconditionally disable Pointer Authentication
443443
support
444444

445+
arm64.nompam [ARM64] Unconditionally disable Memory Partitioning And
446+
Monitoring support
447+
445448
arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension
446449
support
447450

arch/arm64/include/asm/el2_setup.h

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -230,19 +230,6 @@
230230
.Lskip_fgt_\@:
231231
.endm
232232

233-
.macro __init_el2_mpam
234-
/* Memory Partitioning And Monitoring: disable EL2 traps */
235-
mrs x1, id_aa64pfr0_el1
236-
ubfx x0, x1, #ID_AA64PFR0_EL1_MPAM_SHIFT, #4
237-
cbz x0, .Lskip_mpam_\@ // skip if no MPAM
238-
msr_s SYS_MPAM2_EL2, xzr // use the default partition
239-
// and disable lower traps
240-
mrs_s x0, SYS_MPAMIDR_EL1
241-
tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg
242-
msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2
243-
.Lskip_mpam_\@:
244-
.endm
245-
246233
/**
247234
* Initialize EL2 registers to sane values. This should be called early on all
248235
* cores that were booted in EL2. Note that everything gets initialised as
@@ -260,7 +247,6 @@
260247
__init_el2_stage2
261248
__init_el2_gicv3
262249
__init_el2_hstr
263-
__init_el2_mpam
264250
__init_el2_nvhe_idregs
265251
__init_el2_cptr
266252
__init_el2_fgt
@@ -305,6 +291,16 @@
305291
#endif
306292

307293
.macro finalise_el2_state
294+
check_override id_aa64pfr0, ID_AA64PFR0_EL1_MPAM_SHIFT, .Linit_mpam_\@, .Lskip_mpam_\@, x1, x2
295+
296+
.Linit_mpam_\@:
297+
msr_s SYS_MPAM2_EL2, xzr // use the default partition
298+
// and disable lower traps
299+
mrs_s x0, SYS_MPAMIDR_EL1
300+
tbz x0, #MPAMIDR_EL1_HAS_HCR_SHIFT, .Lskip_mpam_\@ // skip if no MPAMHCR reg
301+
msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2
302+
303+
.Lskip_mpam_\@:
308304
check_override id_aa64pfr0, ID_AA64PFR0_EL1_SVE_SHIFT, .Linit_sve_\@, .Lskip_sve_\@, x1, x2
309305

310306
.Linit_sve_\@: /* SVE register access */

arch/arm64/kernel/cpufeature.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,8 +1173,10 @@ void __init init_cpu_features(struct cpuinfo_arm64 *info)
11731173
cpacr_restore(cpacr);
11741174
}
11751175

1176-
if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
1176+
if (id_aa64pfr0_mpam(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) {
1177+
info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
11771178
init_cpu_ftr_reg(SYS_MPAMIDR_EL1, info->reg_mpamidr);
1179+
}
11781180

11791181
if (id_aa64pfr1_mte(info->reg_id_aa64pfr1))
11801182
init_cpu_ftr_reg(SYS_GMID_EL1, info->reg_gmid);
@@ -1431,7 +1433,8 @@ void update_cpu_features(int cpu,
14311433
cpacr_restore(cpacr);
14321434
}
14331435

1434-
if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0)) {
1436+
if (id_aa64pfr0_mpam(read_sanitised_ftr_reg(SYS_ID_AA64PFR0_EL1))) {
1437+
info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
14351438
taint |= check_update_ftr_reg(SYS_MPAMIDR_EL1, cpu,
14361439
info->reg_mpamidr, boot->reg_mpamidr);
14371440
}

arch/arm64/kernel/cpuinfo.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,8 +477,11 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
477477
if (id_aa64pfr0_32bit_el0(info->reg_id_aa64pfr0))
478478
__cpuinfo_store_cpu_32bit(&info->aarch32);
479479

480-
if (id_aa64pfr0_mpam(info->reg_id_aa64pfr0))
481-
info->reg_mpamidr = read_cpuid(MPAMIDR_EL1);
480+
/*
481+
* info->reg_mpamidr deferred to {init,update}_cpu_features because we
482+
* don't want to read it (and trigger a trap on buggy firmware) if
483+
* using an aa64pfr0_el1 override to unconditionally disable MPAM.
484+
*/
482485

483486
cpuinfo_detect_icache_policy(info);
484487
}

arch/arm64/kernel/pi/idreg-override.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static const struct ftr_set_desc pfr0 __prel64_initconst = {
109109
.fields = {
110110
FIELD("sve", ID_AA64PFR0_EL1_SVE_SHIFT, pfr0_sve_filter),
111111
FIELD("el0", ID_AA64PFR0_EL1_EL0_SHIFT, NULL),
112+
FIELD("mpam", ID_AA64PFR0_EL1_MPAM_SHIFT, NULL),
112113
{}
113114
},
114115
};
@@ -135,6 +136,7 @@ static const struct ftr_set_desc pfr1 __prel64_initconst = {
135136
FIELD("bt", ID_AA64PFR1_EL1_BT_SHIFT, NULL ),
136137
FIELD("mte", ID_AA64PFR1_EL1_MTE_SHIFT, NULL),
137138
FIELD("sme", ID_AA64PFR1_EL1_SME_SHIFT, pfr1_sme_filter),
139+
FIELD("mpam_frac", ID_AA64PFR1_EL1_MPAM_frac_SHIFT, NULL),
138140
{}
139141
},
140142
};
@@ -225,6 +227,7 @@ static const struct {
225227
{ "rodata=off", "arm64_sw.rodataoff=1" },
226228
{ "arm64.nolva", "id_aa64mmfr2.varange=0" },
227229
{ "arm64.no32bit_el0", "id_aa64pfr0.el0=1" },
230+
{ "arm64.nompam", "id_aa64pfr0.mpam=0 id_aa64pfr1.mpam_frac=0" },
228231
};
229232

230233
static int __init parse_hexdigit(const char *p, u64 *v)

0 commit comments

Comments
 (0)