Skip to content

Commit 504ee23

Browse files
Marc Zyngierwilldeacon
authored andcommitted
arm64: Add the arm64.nosve command line option
In order to be able to completely disable SVE even if the HW seems to support it (most likely because the FW is broken), move the SVE setup into the EL2 finalisation block, and use a new idreg override to deal with it. Note that we also nuke id_aa64zfr0_el1 as a byproduct, and that SME also gets disabled, due to the dependency between the two features. 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 b3000e2 commit 504ee23

File tree

6 files changed

+48
-17
lines changed

6 files changed

+48
-17
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.nosve [ARM64] Unconditionally disable Scalable Vector
404+
Extension support
405+
403406
arm64.nosme [ARM64] Unconditionally disable Scalable Matrix
404407
Extension support
405408

arch/arm64/include/asm/cpufeature.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -908,7 +908,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
908908
}
909909

910910
extern struct arm64_ftr_override id_aa64mmfr1_override;
911+
extern struct arm64_ftr_override id_aa64pfr0_override;
911912
extern struct arm64_ftr_override id_aa64pfr1_override;
913+
extern struct arm64_ftr_override id_aa64zfr0_override;
912914
extern struct arm64_ftr_override id_aa64smfr0_override;
913915
extern struct arm64_ftr_override id_aa64isar1_override;
914916
extern struct arm64_ftr_override id_aa64isar2_override;

arch/arm64/include/asm/el2_setup.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -129,20 +129,6 @@
129129
msr cptr_el2, x0 // Disable copro. traps to EL2
130130
.endm
131131

132-
/* SVE register access */
133-
.macro __init_el2_nvhe_sve
134-
mrs x1, id_aa64pfr0_el1
135-
ubfx x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
136-
cbz x1, .Lskip_sve_\@
137-
138-
bic x0, x0, #CPTR_EL2_TZ // Also disable SVE traps
139-
msr cptr_el2, x0 // Disable copro. traps to EL2
140-
isb
141-
mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector
142-
msr_s SYS_ZCR_EL2, x1 // length for EL1.
143-
.Lskip_sve_\@:
144-
.endm
145-
146132
/* Disable any fine grained traps */
147133
.macro __init_el2_fgt
148134
mrs x1, id_aa64mmfr0_el1
@@ -206,7 +192,6 @@
206192
__init_el2_hstr
207193
__init_el2_nvhe_idregs
208194
__init_el2_nvhe_cptr
209-
__init_el2_nvhe_sve
210195
__init_el2_fgt
211196
__init_el2_nvhe_prepare_eret
212197
.endm

arch/arm64/kernel/cpufeature.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,9 @@ static const struct arm64_ftr_bits ftr_raz[] = {
631631
__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
632632

633633
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
634+
struct arm64_ftr_override __ro_after_init id_aa64pfr0_override;
634635
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
636+
struct arm64_ftr_override __ro_after_init id_aa64zfr0_override;
635637
struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
636638
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
637639
struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
@@ -669,10 +671,12 @@ static const struct __ftr_reg_entry {
669671
ARM64_FTR_REG(SYS_ID_MMFR5_EL1, ftr_id_mmfr5),
670672

671673
/* Op1 = 0, CRn = 0, CRm = 4 */
672-
ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
674+
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0,
675+
&id_aa64pfr0_override),
673676
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
674677
&id_aa64pfr1_override),
675-
ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
678+
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0,
679+
&id_aa64zfr0_override),
676680
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
677681
&id_aa64smfr0_override),
678682

arch/arm64/kernel/hyp-stub.S

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

100100
SYM_CODE_START_LOCAL(__finalise_el2)
101+
check_override id_aa64pfr0 ID_AA64PFR0_SVE_SHIFT .Linit_sve .Lskip_sve
102+
103+
.Linit_sve: /* SVE register access */
104+
mrs x0, cptr_el2 // Disable SVE traps
105+
bic x0, x0, #CPTR_EL2_TZ
106+
msr cptr_el2, x0
107+
isb
108+
mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector
109+
msr_s SYS_ZCR_EL2, x1 // length for EL1.
110+
111+
.Lskip_sve:
101112
check_override id_aa64pfr1 ID_AA64PFR1_SME_SHIFT .Linit_sme .Lskip_sme
102113

103114
.Linit_sme: /* SME register access and priority mapping */

arch/arm64/kernel/idreg-override.c

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

58+
static bool __init pfr0_sve_filter(u64 val)
59+
{
60+
/*
61+
* Disabling SVE also means disabling all the features that
62+
* are associated with it. The easiest way to do it is just to
63+
* override id_aa64zfr0_el1 to be 0.
64+
*/
65+
if (!val) {
66+
id_aa64zfr0_override.val = 0;
67+
id_aa64zfr0_override.mask = GENMASK(63, 0);
68+
}
69+
70+
return true;
71+
}
72+
73+
static const struct ftr_set_desc pfr0 __initconst = {
74+
.name = "id_aa64pfr0",
75+
.override = &id_aa64pfr0_override,
76+
.fields = {
77+
FIELD("sve", ID_AA64PFR0_SVE_SHIFT, pfr0_sve_filter),
78+
{}
79+
},
80+
};
81+
5882
static bool __init pfr1_sme_filter(u64 val)
5983
{
6084
/*
@@ -118,6 +142,7 @@ static const struct ftr_set_desc kaslr __initconst = {
118142

119143
static const struct ftr_set_desc * const regs[] __initconst = {
120144
&mmfr1,
145+
&pfr0,
121146
&pfr1,
122147
&isar1,
123148
&isar2,
@@ -130,6 +155,7 @@ static const struct {
130155
} aliases[] __initconst = {
131156
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
132157
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
158+
{ "arm64.nosve", "id_aa64pfr0.sve=0 id_aa64pfr1.sme=0" },
133159
{ "arm64.nosme", "id_aa64pfr1.sme=0" },
134160
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
135161
{ "arm64.nopauth",

0 commit comments

Comments
 (0)