Skip to content

Commit b3000e2

Browse files
Marc Zyngierwilldeacon
authored andcommitted
arm64: Add the arm64.nosme command line option
In order to be able to completely disable SME even if the HW seems to support it (most likely because the FW is broken), move the SME setup into the EL2 finalisation block, and use a new idreg override to deal with it. Note that we also nuke id_aa64smfr0_el1 as a byproduct. Signed-off-by: Marc Zyngier <[email protected]> Reviewed-by: Mark Brown <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Will Deacon <[email protected]>
1 parent 6ab7661 commit b3000e2

File tree

6 files changed

+65
-46
lines changed

6 files changed

+65
-46
lines changed

Documentation/admin-guide/kernel-parameters.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,9 @@
400400
arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension
401401
support
402402

403+
arm64.nosme [ARM64] Unconditionally disable Scalable Matrix
404+
Extension support
405+
403406
ataflop= [HW,M68k]
404407

405408
atarimouse= [HW,MOUSE] Atari Mouse

arch/arm64/include/asm/cpufeature.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
909909

910910
extern struct arm64_ftr_override id_aa64mmfr1_override;
911911
extern struct arm64_ftr_override id_aa64pfr1_override;
912+
extern struct arm64_ftr_override id_aa64smfr0_override;
912913
extern struct arm64_ftr_override id_aa64isar1_override;
913914
extern struct arm64_ftr_override id_aa64isar2_override;
914915

arch/arm64/include/asm/el2_setup.h

Lines changed: 0 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -143,50 +143,6 @@
143143
.Lskip_sve_\@:
144144
.endm
145145

146-
/* SME register access and priority mapping */
147-
.macro __init_el2_nvhe_sme
148-
mrs x1, id_aa64pfr1_el1
149-
ubfx x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
150-
cbz x1, .Lskip_sme_\@
151-
152-
bic x0, x0, #CPTR_EL2_TSM // Also disable SME traps
153-
msr cptr_el2, x0 // Disable copro. traps to EL2
154-
isb
155-
156-
mrs x1, sctlr_el2
157-
orr x1, x1, #SCTLR_ELx_ENTP2 // Disable TPIDR2 traps
158-
msr sctlr_el2, x1
159-
isb
160-
161-
mov x1, #0 // SMCR controls
162-
163-
mrs_s x2, SYS_ID_AA64SMFR0_EL1
164-
ubfx x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
165-
cbz x2, .Lskip_sme_fa64_\@
166-
167-
orr x1, x1, SMCR_ELx_FA64_MASK
168-
.Lskip_sme_fa64_\@:
169-
170-
orr x1, x1, #SMCR_ELx_LEN_MASK // Enable full SME vector
171-
msr_s SYS_SMCR_EL2, x1 // length for EL1.
172-
173-
mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported?
174-
ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
175-
cbz x1, .Lskip_sme_\@
176-
177-
msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal
178-
179-
mrs x1, id_aa64mmfr1_el1 // HCRX_EL2 present?
180-
ubfx x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
181-
cbz x1, .Lskip_sme_\@
182-
183-
mrs_s x1, SYS_HCRX_EL2
184-
orr x1, x1, #HCRX_EL2_SMPME_MASK // Enable priority mapping
185-
msr_s SYS_HCRX_EL2, x1
186-
187-
.Lskip_sme_\@:
188-
.endm
189-
190146
/* Disable any fine grained traps */
191147
.macro __init_el2_fgt
192148
mrs x1, id_aa64mmfr0_el1
@@ -251,7 +207,6 @@
251207
__init_el2_nvhe_idregs
252208
__init_el2_nvhe_cptr
253209
__init_el2_nvhe_sve
254-
__init_el2_nvhe_sme
255210
__init_el2_fgt
256211
__init_el2_nvhe_prepare_eret
257212
.endm

arch/arm64/kernel/cpufeature.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
632632

633633
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
634634
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
635+
struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
635636
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
636637
struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
637638

@@ -672,7 +673,8 @@ static const struct __ftr_reg_entry {
672673
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
673674
&id_aa64pfr1_override),
674675
ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
675-
ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
676+
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
677+
&id_aa64smfr0_override),
676678

677679
/* Op1 = 0, CRn = 0, CRm = 5 */
678680
ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),

arch/arm64/kernel/hyp-stub.S

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,47 @@ SYM_CODE_START_LOCAL(elx_sync)
9898
SYM_CODE_END(elx_sync)
9999

100100
SYM_CODE_START_LOCAL(__finalise_el2)
101+
check_override id_aa64pfr1 ID_AA64PFR1_SME_SHIFT .Linit_sme .Lskip_sme
102+
103+
.Linit_sme: /* SME register access and priority mapping */
104+
mrs x0, cptr_el2 // Disable SME traps
105+
bic x0, x0, #CPTR_EL2_TSM
106+
msr cptr_el2, x0
107+
isb
108+
109+
mrs x1, sctlr_el2
110+
orr x1, x1, #SCTLR_ELx_ENTP2 // Disable TPIDR2 traps
111+
msr sctlr_el2, x1
112+
isb
113+
114+
mov x1, #0 // SMCR controls
115+
116+
mrs_s x2, SYS_ID_AA64SMFR0_EL1
117+
ubfx x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
118+
cbz x2, .Lskip_sme_fa64
119+
120+
orr x1, x1, SMCR_ELx_FA64_MASK
121+
.Lskip_sme_fa64:
122+
123+
orr x1, x1, #SMCR_ELx_LEN_MASK // Enable full SME vector
124+
msr_s SYS_SMCR_EL2, x1 // length for EL1.
125+
126+
mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported?
127+
ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
128+
cbz x1, .Lskip_sme
129+
130+
msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal
131+
132+
mrs x1, id_aa64mmfr1_el1 // HCRX_EL2 present?
133+
ubfx x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
134+
cbz x1, .Lskip_sme
135+
136+
mrs_s x1, SYS_HCRX_EL2
137+
orr x1, x1, #HCRX_EL2_SMPME_MASK // Enable priority mapping
138+
msr_s SYS_HCRX_EL2, x1
139+
140+
.Lskip_sme:
141+
101142
// nVHE? No way! Give me the real thing!
102143
// Sanity check: MMU *must* be off
103144
mrs x1, sctlr_el2

arch/arm64/kernel/idreg-override.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,28 @@ static const struct ftr_set_desc mmfr1 __initconst = {
5555
},
5656
};
5757

58+
static bool __init pfr1_sme_filter(u64 val)
59+
{
60+
/*
61+
* Similarly to SVE, disabling SME also means disabling all
62+
* the features that are associated with it. Just set
63+
* id_aa64smfr0_el1 to 0 and don't look back.
64+
*/
65+
if (!val) {
66+
id_aa64smfr0_override.val = 0;
67+
id_aa64smfr0_override.mask = GENMASK(63, 0);
68+
}
69+
70+
return true;
71+
}
72+
5873
static const struct ftr_set_desc pfr1 __initconst = {
5974
.name = "id_aa64pfr1",
6075
.override = &id_aa64pfr1_override,
6176
.fields = {
6277
FIELD("bt", ID_AA64PFR1_BT_SHIFT, NULL),
6378
FIELD("mte", ID_AA64PFR1_MTE_SHIFT, NULL),
79+
FIELD("sme", ID_AA64PFR1_SME_SHIFT, pfr1_sme_filter),
6480
{}
6581
},
6682
};
@@ -114,6 +130,7 @@ static const struct {
114130
} aliases[] __initconst = {
115131
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
116132
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
133+
{ "arm64.nosme", "id_aa64pfr1.sme=0" },
117134
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
118135
{ "arm64.nopauth",
119136
"id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "

0 commit comments

Comments
 (0)