* [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line
@ 2022-06-30 16:04 Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 1/9] arm64: Rename the VHE switch to "finalise_el2" Marc Zyngier
` (9 more replies)
0 siblings, 10 replies; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
This very short series reworks the way arm64 CPUs boot (yes, again) in
order to opt out of some features early at boot, on top of the
existing VHE-forced-into-nVHE use case and using the same idreg
override infrastructure.
The main victim here is SVE, because it seems that people have all
sort of broken firmware out there, and that a distribution kernel
cannot boot on that. And since we have a dependency between SVE and
SME, disabling the former also disables the latter.
The only positive aspect about this series is that it unifies the way
the VHE-stuck CPUs boot with way the full-fat CPUs do (everybody takes
a trip to EL1 before coming back to EL2, instead of the stay-at-EL2
approach we currently have). A small victory, which allows us to
control the EL2 setup code more easily.
Note that the SME code is totally untested (I don't have a model with
that), but it looks obviously correct ;-), and that my SVE "platform"
has a working firmware...
* From v1:
- Fixed glaring bug spotted by Mark where CPTR_EL2 was never really
written to...
- Don't write the E2H tracking flag to memory, since Ard reworked
the boot flow to avoid writing to RAM without the MMU on
- Added an explicit way to disable FA64 independently from SME
- Made the override code able to deal with arbitrary field widths to
deal with FA64 (a single-bit field...)
- Now rebased on top of arm64/for-next/boot
Marc Zyngier (9):
arm64: Rename the VHE switch to "finalise_el2"
arm64: Save state of HCR_EL2.E2H before switch to EL1
arm64: Allow sticky E2H when entering EL1
arm64: Factor out checking of a feature against the override into a
macro
arm64: Allow the idreg override to deal with variable field width
arm64: Expose a __check_override primitive for oddball features
arm64: Add the arm64.nosme command line option
arm64: Add the arm64.nosve command line option
arm64: Add an override for ID_AA64SMFR0_EL1.FA64
.../admin-guide/kernel-parameters.txt | 6 +
Documentation/virt/kvm/arm/hyp-abi.rst | 11 +-
arch/arm64/include/asm/cpufeature.h | 3 +
arch/arm64/include/asm/el2_setup.h | 60 ----------
arch/arm64/include/asm/virt.h | 11 +-
arch/arm64/kernel/cpufeature.c | 12 +-
arch/arm64/kernel/head.S | 43 +++----
arch/arm64/kernel/hyp-stub.S | 113 ++++++++++++++----
arch/arm64/kernel/idreg-override.c | 93 +++++++++++---
arch/arm64/kernel/sleep.S | 2 +-
10 files changed, 216 insertions(+), 138 deletions(-)
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2 1/9] arm64: Rename the VHE switch to "finalise_el2"
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 2/9] arm64: Save state of HCR_EL2.E2H before switch to EL1 Marc Zyngier
` (8 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
as we are about to perform a lot more in 'mutate_to_vhe' than
we currently do, this function really becomes the point where
we finalise the basic EL2 configuration.
Reflect this into the code by renaming a bunch of things:
- HVC_VHE_RESTART -> HVC_FINALISE_EL2
- switch_to_vhe --> finalise_el2
- mutate_to_vhe -> __finalise_el2
No functional changes.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
Documentation/virt/kvm/arm/hyp-abi.rst | 11 ++++++-----
arch/arm64/include/asm/virt.h | 4 ++--
arch/arm64/kernel/head.S | 6 +++---
arch/arm64/kernel/hyp-stub.S | 21 ++++++++++-----------
arch/arm64/kernel/sleep.S | 2 +-
5 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/Documentation/virt/kvm/arm/hyp-abi.rst b/Documentation/virt/kvm/arm/hyp-abi.rst
index 4d43fbc25195..412b276449d3 100644
--- a/Documentation/virt/kvm/arm/hyp-abi.rst
+++ b/Documentation/virt/kvm/arm/hyp-abi.rst
@@ -60,12 +60,13 @@ these functions (see arch/arm{,64}/include/asm/virt.h):
* ::
- x0 = HVC_VHE_RESTART (arm64 only)
+ x0 = HVC_FINALISE_EL2 (arm64 only)
- Attempt to upgrade the kernel's exception level from EL1 to EL2 by enabling
- the VHE mode. This is conditioned by the CPU supporting VHE, the EL2 MMU
- being off, and VHE not being disabled by any other means (command line
- option, for example).
+ Finish configuring EL2 depending on the command-line options,
+ including an attempt to upgrade the kernel's exception level from
+ EL1 to EL2 by enabling the VHE mode. This is conditioned by the CPU
+ supporting VHE, the EL2 MMU being off, and VHE not being disabled by
+ any other means (command line option, for example).
Any other value of r0/x0 triggers a hypervisor-specific handling,
which is not documented here.
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index 0e80db4327b6..dec6eee0eda5 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -36,9 +36,9 @@
#define HVC_RESET_VECTORS 2
/*
- * HVC_VHE_RESTART - Upgrade the CPU from EL1 to EL2, if possible
+ * HVC_FINALISE_EL2 - Upgrade the CPU from EL1 to EL2, if possible
*/
-#define HVC_VHE_RESTART 3
+#define HVC_FINALISE_EL2 3
/* Max number of HYP stub hypercalls */
#define HVC_STUB_HCALL_NR 4
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 6bf685f988f1..04ebfe663eae 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -449,7 +449,7 @@ SYM_FUNC_START_LOCAL(__primary_switched)
mov x0, x22 // pass FDT address in x0
bl init_feature_override // Parse cpu feature overrides
mov x0, x20
- bl switch_to_vhe // Prefer VHE if possible
+ bl finalise_el2 // Prefer VHE if possible
ldp x29, x30, [sp], #16
bl start_kernel
ASM_BUG()
@@ -532,7 +532,7 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
eret
__cpu_stick_to_vhe:
- mov x0, #HVC_VHE_RESTART
+ mov x0, #HVC_FINALISE_EL2
hvc #0
mov x0, #BOOT_CPU_MODE_EL2
ret
@@ -582,7 +582,7 @@ SYM_FUNC_START_LOCAL(secondary_startup)
* Common entry point for secondary CPUs.
*/
mov x20, x0 // preserve boot mode
- bl switch_to_vhe
+ bl finalise_el2
bl __cpu_secondary_check52bitva
bl __cpu_setup // initialise processor
adrp x1, swapper_pg_dir
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 5bafb53fafb4..571286eb443c 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -51,8 +51,8 @@ SYM_CODE_START_LOCAL(elx_sync)
msr vbar_el2, x1
b 9f
-1: cmp x0, #HVC_VHE_RESTART
- b.eq mutate_to_vhe
+1: cmp x0, #HVC_FINALISE_EL2
+ b.eq __finalise_el2
2: cmp x0, #HVC_SOFT_RESTART
b.ne 3f
@@ -73,8 +73,8 @@ SYM_CODE_START_LOCAL(elx_sync)
eret
SYM_CODE_END(elx_sync)
-// nVHE? No way! Give me the real thing!
-SYM_CODE_START_LOCAL(mutate_to_vhe)
+SYM_CODE_START_LOCAL(__finalise_el2)
+ // nVHE? No way! Give me the real thing!
// Sanity check: MMU *must* be off
mrs x1, sctlr_el2
tbnz x1, #0, 1f
@@ -140,10 +140,10 @@ SYM_CODE_START_LOCAL(mutate_to_vhe)
msr spsr_el1, x0
b enter_vhe
-SYM_CODE_END(mutate_to_vhe)
+SYM_CODE_END(__finalise_el2)
// At the point where we reach enter_vhe(), we run with
- // the MMU off (which is enforced by mutate_to_vhe()).
+ // the MMU off (which is enforced by __finalise_el2()).
// We thus need to be in the idmap, or everything will
// explode when enabling the MMU.
@@ -222,11 +222,11 @@ SYM_FUNC_START(__hyp_reset_vectors)
SYM_FUNC_END(__hyp_reset_vectors)
/*
- * Entry point to switch to VHE if deemed capable
+ * Entry point to finalise EL2 and switch to VHE if deemed capable
*
* w0: boot mode, as returned by init_kernel_el()
*/
-SYM_FUNC_START(switch_to_vhe)
+SYM_FUNC_START(finalise_el2)
// Need to have booted at EL2
cmp w0, #BOOT_CPU_MODE_EL2
b.ne 1f
@@ -236,9 +236,8 @@ SYM_FUNC_START(switch_to_vhe)
cmp x0, #CurrentEL_EL1
b.ne 1f
- // Turn the world upside down
- mov x0, #HVC_VHE_RESTART
+ mov x0, #HVC_FINALISE_EL2
hvc #0
1:
ret
-SYM_FUNC_END(switch_to_vhe)
+SYM_FUNC_END(finalise_el2)
diff --git a/arch/arm64/kernel/sleep.S b/arch/arm64/kernel/sleep.S
index e36b09d942f7..617f78ad43a1 100644
--- a/arch/arm64/kernel/sleep.S
+++ b/arch/arm64/kernel/sleep.S
@@ -100,7 +100,7 @@ SYM_FUNC_END(__cpu_suspend_enter)
.pushsection ".idmap.text", "awx"
SYM_CODE_START(cpu_resume)
bl init_kernel_el
- bl switch_to_vhe
+ bl finalise_el2
bl __cpu_setup
/* enable the MMU early - so we can access sleep_save_stash by va */
adrp x1, swapper_pg_dir
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 2/9] arm64: Save state of HCR_EL2.E2H before switch to EL1
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 1/9] arm64: Rename the VHE switch to "finalise_el2" Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 3/9] arm64: Allow sticky E2H when entering EL1 Marc Zyngier
` (7 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
As we're about to switch the way E2H-stuck CPUs boot, save
the boot CPU E2H state as a flag tied to the boot mode
that can then be checked by the idreg override code.
This allows us to replace the is_kernel_in_hyp_mode() check
with a simple comparison with this state, even when running
at EL1. Note that this flag isn't saved in __boot_cpu_mode,
and is only kept in a register in the assembly code.
Use with caution.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/include/asm/virt.h | 7 +++++++
arch/arm64/kernel/head.S | 7 +++++--
arch/arm64/kernel/idreg-override.c | 11 ++++++++---
3 files changed, 20 insertions(+), 5 deletions(-)
diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h
index dec6eee0eda5..4eb601e7de50 100644
--- a/arch/arm64/include/asm/virt.h
+++ b/arch/arm64/include/asm/virt.h
@@ -49,6 +49,13 @@
#define BOOT_CPU_MODE_EL1 (0xe11)
#define BOOT_CPU_MODE_EL2 (0xe12)
+/*
+ * Flags returned together with the boot mode, but not preserved in
+ * __boot_cpu_mode. Used by the idreg override code to work out the
+ * boot state.
+ */
+#define BOOT_CPU_FLAG_E2H BIT_ULL(32)
+
#ifndef __ASSEMBLY__
#include <asm/ptrace.h>
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 04ebfe663eae..053cd6803147 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -447,6 +447,7 @@ SYM_FUNC_START_LOCAL(__primary_switched)
bl kasan_early_init
#endif
mov x0, x22 // pass FDT address in x0
+ mov x1, x20 // pass the full boot status
bl init_feature_override // Parse cpu feature overrides
mov x0, x20
bl finalise_el2 // Prefer VHE if possible
@@ -469,8 +470,9 @@ SYM_FUNC_END(__primary_switched)
* Since we cannot always rely on ERET synchronizing writes to sysregs (e.g. if
* SCTLR_ELx.EOS is clear), we place an ISB prior to ERET.
*
- * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in w0 if
- * booted in EL1 or EL2 respectively.
+ * Returns either BOOT_CPU_MODE_EL1 or BOOT_CPU_MODE_EL2 in x0 if
+ * booted in EL1 or EL2 respectively, with the top 32 bits containing
+ * potential context flags. These flags are *not* stored in __boot_cpu_mode.
*/
SYM_FUNC_START(init_kernel_el)
mrs x0, CurrentEL
@@ -535,6 +537,7 @@ __cpu_stick_to_vhe:
mov x0, #HVC_FINALISE_EL2
hvc #0
mov x0, #BOOT_CPU_MODE_EL2
+ orr x0, x0, #BOOT_CPU_FLAG_E2H
ret
SYM_FUNC_END(init_kernel_el)
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index f92836e196e5..03185bc46d69 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -19,6 +19,8 @@
#define FTR_ALIAS_NAME_LEN 30
#define FTR_ALIAS_OPTION_LEN 116
+static u64 __boot_status __initdata;
+
struct ftr_set_desc {
char name[FTR_DESC_NAME_LEN];
struct arm64_ftr_override *override;
@@ -37,7 +39,8 @@ static bool __init mmfr1_vh_filter(u64 val)
* the user was trying to force nVHE on us, proceed with
* attitude adjustment.
*/
- return !(is_kernel_in_hyp_mode() && val == 0);
+ return !(__boot_status == (BOOT_CPU_FLAG_E2H | BOOT_CPU_MODE_EL2) &&
+ val == 0);
}
static const struct ftr_set_desc mmfr1 __initconst = {
@@ -229,9 +232,9 @@ static __init void parse_cmdline(const void *fdt)
}
/* Keep checkers quiet */
-void init_feature_override(const void *fdt);
+void init_feature_override(const void *fdt, u64 boot_status);
-asmlinkage void __init init_feature_override(const void *fdt)
+asmlinkage void __init init_feature_override(const void *fdt, u64 boot_status)
{
int i;
@@ -242,6 +245,8 @@ asmlinkage void __init init_feature_override(const void *fdt)
}
}
+ __boot_status = boot_status;
+
parse_cmdline(fdt);
for (i = 0; i < ARRAY_SIZE(regs); i++) {
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 3/9] arm64: Allow sticky E2H when entering EL1
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 1/9] arm64: Rename the VHE switch to "finalise_el2" Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 2/9] arm64: Save state of HCR_EL2.E2H before switch to EL1 Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 4/9] arm64: Factor out checking of a feature against the override into a macro Marc Zyngier
` (6 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
For CPUs that have the unfortunate mis-feature to be stuck in
VHE mode, we perform a funny dance where we completely shortcut
the normal boot process to enable VHE and run the kernel at EL2,
and only then start booting the kernel.
Not only this is pretty ugly, but it means that the EL2 finalisation
occurs before we have processed the sysreg override.
Instead, start executing the kernel as if it was an EL1 guest and
rely on the normal EL2 finalisation to go back to EL2.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/head.S | 34 ++++++++++------------------------
1 file changed, 10 insertions(+), 24 deletions(-)
diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S
index 053cd6803147..fbdb651c090f 100644
--- a/arch/arm64/kernel/head.S
+++ b/arch/arm64/kernel/head.S
@@ -501,6 +501,8 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
msr vbar_el2, x0
isb
+ mov_q x1, INIT_SCTLR_EL1_MMU_OFF
+
/*
* Fruity CPUs seem to have HCR_EL2.E2H set to RES1,
* making it impossible to start in nVHE mode. Is that
@@ -510,35 +512,19 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL)
and x0, x0, #HCR_E2H
cbz x0, 1f
- /* Switching to VHE requires a sane SCTLR_EL1 as a start */
- mov_q x0, INIT_SCTLR_EL1_MMU_OFF
- msr_s SYS_SCTLR_EL12, x0
-
- /*
- * Force an eret into a helper "function", and let it return
- * to our original caller... This makes sure that we have
- * initialised the basic PSTATE state.
- */
- mov x0, #INIT_PSTATE_EL2
- msr spsr_el1, x0
- adr x0, __cpu_stick_to_vhe
- msr elr_el1, x0
- eret
+ /* Set a sane SCTLR_EL1, the VHE way */
+ msr_s SYS_SCTLR_EL12, x1
+ mov x2, #BOOT_CPU_FLAG_E2H
+ b 2f
1:
- mov_q x0, INIT_SCTLR_EL1_MMU_OFF
- msr sctlr_el1, x0
-
+ msr sctlr_el1, x1
+ mov x2, xzr
+2:
msr elr_el2, lr
mov w0, #BOOT_CPU_MODE_EL2
+ orr x0, x0, x2
eret
-
-__cpu_stick_to_vhe:
- mov x0, #HVC_FINALISE_EL2
- hvc #0
- mov x0, #BOOT_CPU_MODE_EL2
- orr x0, x0, #BOOT_CPU_FLAG_E2H
- ret
SYM_FUNC_END(init_kernel_el)
/*
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 4/9] arm64: Factor out checking of a feature against the override into a macro
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (2 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 3/9] arm64: Allow sticky E2H when entering EL1 Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width Marc Zyngier
` (5 subsequent siblings)
9 siblings, 0 replies; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
Checking for a feature being supported from assembly code is
a bit tedious if we need to factor in the idreg override.
Since we already have such code written for forcing nVHE, move
the whole thing into a macro. This heavily relies on the override
structure being called foo_override for foo_el1.
No functional change.
Reviewed-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/hyp-stub.S | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 571286eb443c..43c94e7a2c1d 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -16,6 +16,25 @@
#include <asm/ptrace.h>
#include <asm/virt.h>
+// Warning, hardcoded register allocation
+// This will clobber x1 and x2.
+.macro check_override idreg, fld, pass, fail
+ mrs x1, \idreg\()_el1
+ ubfx x1, x1, #\fld, #4
+ cbz x1, \fail
+
+ adr_l x1, \idreg\()_override
+ ldr x2, [x1, FTR_OVR_VAL_OFFSET]
+ ldr x1, [x1, FTR_OVR_MASK_OFFSET]
+ ubfx x2, x2, #\fld, #4
+ ubfx x1, x1, #\fld, #4
+ cmp x1, xzr
+ and x2, x2, x1
+ csinv x2, x2, xzr, ne
+ cbnz x2, \pass
+ b \fail
+.endm
+
.text
.pushsection .hyp.text, "ax"
@@ -80,20 +99,7 @@ SYM_CODE_START_LOCAL(__finalise_el2)
tbnz x1, #0, 1f
// Needs to be VHE capable, obviously
- mrs x1, id_aa64mmfr1_el1
- ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4
- cbz x1, 1f
-
- // Check whether VHE is disabled from the command line
- adr_l x1, id_aa64mmfr1_override
- ldr x2, [x1, FTR_OVR_VAL_OFFSET]
- ldr x1, [x1, FTR_OVR_MASK_OFFSET]
- ubfx x2, x2, #ID_AA64MMFR1_VHE_SHIFT, #4
- ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4
- cmp x1, xzr
- and x2, x2, x1
- csinv x2, x2, xzr, ne
- cbnz x2, 2f
+ check_override id_aa64mmfr1 ID_AA64MMFR1_VHE_SHIFT 2f 1f
1: mov_q x0, HVC_STUB_ERR
eret
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (3 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 4/9] arm64: Factor out checking of a feature against the override into a macro Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-07-01 14:00 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features Marc Zyngier
` (4 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
Currently, the override mechanism can only deal with 4bit fields,
which is the most common case. However, we now have a bunch of
ID registers that have more diverse field widths, such as
ID_AA64SMFR0_EL1, which has fields that are a single bit wide.
Add the support for variable width, and a macro that encodes
a feature width of 4 for all existing override.
No functional change.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/idreg-override.c | 28 ++++++++++++++++------------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 03185bc46d69..1e5f3dba3f01 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -27,10 +27,13 @@ struct ftr_set_desc {
struct {
char name[FTR_DESC_FIELD_LEN];
u8 shift;
+ u8 width;
bool (*filter)(u64 val);
} fields[];
};
+#define FIELD(n, s, f) { .name = n, .shift = s, .width = 4, .filter = f }
+
static bool __init mmfr1_vh_filter(u64 val)
{
/*
@@ -47,7 +50,7 @@ static const struct ftr_set_desc mmfr1 __initconst = {
.name = "id_aa64mmfr1",
.override = &id_aa64mmfr1_override,
.fields = {
- { "vh", ID_AA64MMFR1_VHE_SHIFT, mmfr1_vh_filter },
+ FIELD("vh", ID_AA64MMFR1_VHE_SHIFT, mmfr1_vh_filter),
{}
},
};
@@ -56,8 +59,8 @@ static const struct ftr_set_desc pfr1 __initconst = {
.name = "id_aa64pfr1",
.override = &id_aa64pfr1_override,
.fields = {
- { "bt", ID_AA64PFR1_BT_SHIFT },
- { "mte", ID_AA64PFR1_MTE_SHIFT},
+ FIELD("bt", ID_AA64PFR1_BT_SHIFT, NULL),
+ FIELD("mte", ID_AA64PFR1_MTE_SHIFT, NULL),
{}
},
};
@@ -66,10 +69,10 @@ static const struct ftr_set_desc isar1 __initconst = {
.name = "id_aa64isar1",
.override = &id_aa64isar1_override,
.fields = {
- { "gpi", ID_AA64ISAR1_GPI_SHIFT },
- { "gpa", ID_AA64ISAR1_GPA_SHIFT },
- { "api", ID_AA64ISAR1_API_SHIFT },
- { "apa", ID_AA64ISAR1_APA_SHIFT },
+ FIELD("gpi", ID_AA64ISAR1_GPI_SHIFT, NULL),
+ FIELD("gpa", ID_AA64ISAR1_GPA_SHIFT, NULL),
+ FIELD("api", ID_AA64ISAR1_API_SHIFT, NULL),
+ FIELD("apa", ID_AA64ISAR1_APA_SHIFT, NULL),
{}
},
};
@@ -78,8 +81,8 @@ static const struct ftr_set_desc isar2 __initconst = {
.name = "id_aa64isar2",
.override = &id_aa64isar2_override,
.fields = {
- { "gpa3", ID_AA64ISAR2_GPA3_SHIFT },
- { "apa3", ID_AA64ISAR2_APA3_SHIFT },
+ FIELD("gpa3", ID_AA64ISAR2_GPA3_SHIFT, NULL),
+ FIELD("apa3", ID_AA64ISAR2_APA3_SHIFT, NULL),
{}
},
};
@@ -92,7 +95,7 @@ static const struct ftr_set_desc kaslr __initconst = {
.override = &kaslr_feature_override,
#endif
.fields = {
- { "disabled", 0 },
+ FIELD("disabled", 0, NULL),
{}
},
};
@@ -147,7 +150,8 @@ static void __init match_options(const char *cmdline)
for (f = 0; strlen(regs[i]->fields[f].name); f++) {
u64 shift = regs[i]->fields[f].shift;
- u64 mask = 0xfUL << shift;
+ u64 width = regs[i]->fields[f].width ?: 4;
+ u64 mask = GENMASK_ULL(shift + width - 1, shift);
u64 v;
if (find_field(cmdline, regs[i], f, &v))
@@ -155,7 +159,7 @@ static void __init match_options(const char *cmdline)
/*
* If an override gets filtered out, advertise
- * it by setting the value to 0xf, but
+ * it by setting the value to the all-ones while
* clearing the mask... Yes, this is fragile.
*/
if (regs[i]->fields[f].filter &&
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (4 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-07-01 14:03 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 7/9] arm64: Add the arm64.nosme command line option Marc Zyngier
` (3 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
In order to feal with early override of features that are not
classically encoded in a standard ID register with a 4 bit wide
field, add a primitive that takes a sysreg value as an input
(instead of the usual sysreg name) as well as a bit field
width (usually 4).
No functional change.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/hyp-stub.S | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 43c94e7a2c1d..de1ab9843c31 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -17,17 +17,17 @@
#include <asm/virt.h>
// Warning, hardcoded register allocation
-// This will clobber x1 and x2.
-.macro check_override idreg, fld, pass, fail
- mrs x1, \idreg\()_el1
- ubfx x1, x1, #\fld, #4
+// This will clobber x1 and x2, and expect x1 to contain
+// the id register value as read from the HW
+.macro __check_override idreg, fld, width, pass, fail
+ ubfx x1, x1, #\fld, #\width
cbz x1, \fail
adr_l x1, \idreg\()_override
ldr x2, [x1, FTR_OVR_VAL_OFFSET]
ldr x1, [x1, FTR_OVR_MASK_OFFSET]
- ubfx x2, x2, #\fld, #4
- ubfx x1, x1, #\fld, #4
+ ubfx x2, x2, #\fld, #\width
+ ubfx x1, x1, #\fld, #\width
cmp x1, xzr
and x2, x2, x1
csinv x2, x2, xzr, ne
@@ -35,6 +35,11 @@
b \fail
.endm
+.macro check_override idreg, fld, pass, fail
+ mrs x1, \idreg\()_el1
+ __check_override \idreg \fld 4 \pass \fail
+.endm
+
.text
.pushsection .hyp.text, "ax"
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 7/9] arm64: Add the arm64.nosme command line option
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (5 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-07-01 13:44 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 8/9] arm64: Add the arm64.nosve " Marc Zyngier
` (2 subsequent siblings)
9 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
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 <maz@kernel.org>
---
.../admin-guide/kernel-parameters.txt | 3 ++
arch/arm64/include/asm/cpufeature.h | 1 +
arch/arm64/include/asm/el2_setup.h | 45 -------------------
arch/arm64/kernel/cpufeature.c | 4 +-
arch/arm64/kernel/hyp-stub.S | 41 +++++++++++++++++
arch/arm64/kernel/idreg-override.c | 17 +++++++
6 files changed, 65 insertions(+), 46 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 2522b11e593f..301d2d0fee80 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -400,6 +400,9 @@
arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension
support
+ arm64.nosme [ARM64] Unconditionally disable Scalable Matrix
+ Extension support
+
ataflop= [HW,M68k]
atarimouse= [HW,MOUSE] Atari Mouse
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 14a8f3d93add..5adda12b1946 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -909,6 +909,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
extern struct arm64_ftr_override id_aa64mmfr1_override;
extern struct arm64_ftr_override id_aa64pfr1_override;
+extern struct arm64_ftr_override id_aa64smfr0_override;
extern struct arm64_ftr_override id_aa64isar1_override;
extern struct arm64_ftr_override id_aa64isar2_override;
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 34ceff08cac4..18641dce5184 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -143,50 +143,6 @@
.Lskip_sve_\@:
.endm
-/* SME register access and priority mapping */
-.macro __init_el2_nvhe_sme
- mrs x1, id_aa64pfr1_el1
- ubfx x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
- cbz x1, .Lskip_sme_\@
-
- bic x0, x0, #CPTR_EL2_TSM // Also disable SME traps
- msr cptr_el2, x0 // Disable copro. traps to EL2
- isb
-
- mrs x1, sctlr_el2
- orr x1, x1, #SCTLR_ELx_ENTP2 // Disable TPIDR2 traps
- msr sctlr_el2, x1
- isb
-
- mov x1, #0 // SMCR controls
-
- mrs_s x2, SYS_ID_AA64SMFR0_EL1
- ubfx x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
- cbz x2, .Lskip_sme_fa64_\@
-
- orr x1, x1, SMCR_ELx_FA64_MASK
-.Lskip_sme_fa64_\@:
-
- orr x1, x1, #SMCR_ELx_LEN_MASK // Enable full SME vector
- msr_s SYS_SMCR_EL2, x1 // length for EL1.
-
- mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported?
- ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
- cbz x1, .Lskip_sme_\@
-
- msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal
-
- mrs x1, id_aa64mmfr1_el1 // HCRX_EL2 present?
- ubfx x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
- cbz x1, .Lskip_sme_\@
-
- mrs_s x1, SYS_HCRX_EL2
- orr x1, x1, #HCRX_EL2_SMPME_MASK // Enable priority mapping
- msr_s SYS_HCRX_EL2, x1
-
-.Lskip_sme_\@:
-.endm
-
/* Disable any fine grained traps */
.macro __init_el2_fgt
mrs x1, id_aa64mmfr0_el1
@@ -251,7 +207,6 @@
__init_el2_nvhe_idregs
__init_el2_nvhe_cptr
__init_el2_nvhe_sve
- __init_el2_nvhe_sme
__init_el2_fgt
__init_el2_nvhe_prepare_eret
.endm
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a97913d19709..a7d0686123a6 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -632,6 +632,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
+struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
@@ -672,7 +673,8 @@ static const struct __ftr_reg_entry {
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
&id_aa64pfr1_override),
ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
- ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
+ &id_aa64smfr0_override),
/* Op1 = 0, CRn = 0, CRm = 5 */
ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index de1ab9843c31..0c69defa069e 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -98,6 +98,47 @@ SYM_CODE_START_LOCAL(elx_sync)
SYM_CODE_END(elx_sync)
SYM_CODE_START_LOCAL(__finalise_el2)
+ check_override id_aa64pfr1 ID_AA64PFR1_SME_SHIFT .Linit_sme .Lskip_sme
+
+.Linit_sme: /* SME register access and priority mapping */
+ mrs x0, cptr_el2 // Disable SME traps
+ bic x0, x0, #CPTR_EL2_TSM
+ msr cptr_el2, x0
+ isb
+
+ mrs x1, sctlr_el2
+ orr x1, x1, #SCTLR_ELx_ENTP2 // Disable TPIDR2 traps
+ msr sctlr_el2, x1
+ isb
+
+ mov x1, #0 // SMCR controls
+
+ mrs_s x2, SYS_ID_AA64SMFR0_EL1
+ ubfx x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
+ cbz x2, .Lskip_sme_fa64
+
+ orr x1, x1, SMCR_ELx_FA64_MASK
+.Lskip_sme_fa64:
+
+ orr x1, x1, #SMCR_ELx_LEN_MASK // Enable full SME vector
+ msr_s SYS_SMCR_EL2, x1 // length for EL1.
+
+ mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported?
+ ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
+ cbz x1, .Lskip_sme
+
+ msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal
+
+ mrs x1, id_aa64mmfr1_el1 // HCRX_EL2 present?
+ ubfx x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
+ cbz x1, .Lskip_sme
+
+ mrs_s x1, SYS_HCRX_EL2
+ orr x1, x1, #HCRX_EL2_SMPME_MASK // Enable priority mapping
+ msr_s SYS_HCRX_EL2, x1
+
+.Lskip_sme:
+
// nVHE? No way! Give me the real thing!
// Sanity check: MMU *must* be off
mrs x1, sctlr_el2
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 1e5f3dba3f01..9314f0a8561c 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -55,12 +55,28 @@ static const struct ftr_set_desc mmfr1 __initconst = {
},
};
+static bool __init pfr1_sme_filter(u64 val)
+{
+ /*
+ * Similarly to SVE, disabling SME also means disabling all
+ * the features that are associated with it. Just set
+ * id_aa64smfr0_el1 to 0 and don't look back.
+ */
+ if (!val) {
+ id_aa64smfr0_override.val = 0;
+ id_aa64smfr0_override.mask = GENMASK(63, 0);
+ }
+
+ return true;
+}
+
static const struct ftr_set_desc pfr1 __initconst = {
.name = "id_aa64pfr1",
.override = &id_aa64pfr1_override,
.fields = {
FIELD("bt", ID_AA64PFR1_BT_SHIFT, NULL),
FIELD("mte", ID_AA64PFR1_MTE_SHIFT, NULL),
+ FIELD("sme", ID_AA64PFR1_SME_SHIFT, pfr1_sme_filter),
{}
},
};
@@ -114,6 +130,7 @@ static const struct {
} aliases[] __initconst = {
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
+ { "arm64.nosme", "id_aa64pfr1.sme=0" },
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
{ "arm64.nopauth",
"id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 "
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 8/9] arm64: Add the arm64.nosve command line option
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (6 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 7/9] arm64: Add the arm64.nosme command line option Marc Zyngier
@ 2022-06-30 16:04 ` Marc Zyngier
2022-07-01 13:45 ` Mark Brown
2022-06-30 16:05 ` [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64 Marc Zyngier
2022-07-01 15:41 ` [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Will Deacon
9 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:04 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
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 <maz@kernel.org>
---
.../admin-guide/kernel-parameters.txt | 3 +++
arch/arm64/include/asm/cpufeature.h | 2 ++
arch/arm64/include/asm/el2_setup.h | 15 -----------
arch/arm64/kernel/cpufeature.c | 8 ++++--
arch/arm64/kernel/hyp-stub.S | 11 ++++++++
arch/arm64/kernel/idreg-override.c | 26 +++++++++++++++++++
6 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 301d2d0fee80..0f1344eb7c2f 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -400,6 +400,9 @@
arm64.nomte [ARM64] Unconditionally disable Memory Tagging Extension
support
+ arm64.nosve [ARM64] Unconditionally disable Scalable Vector
+ Extension support
+
arm64.nosme [ARM64] Unconditionally disable Scalable Matrix
Extension support
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 5adda12b1946..0fc4f6e068e5 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -908,7 +908,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)
}
extern struct arm64_ftr_override id_aa64mmfr1_override;
+extern struct arm64_ftr_override id_aa64pfr0_override;
extern struct arm64_ftr_override id_aa64pfr1_override;
+extern struct arm64_ftr_override id_aa64zfr0_override;
extern struct arm64_ftr_override id_aa64smfr0_override;
extern struct arm64_ftr_override id_aa64isar1_override;
extern struct arm64_ftr_override id_aa64isar2_override;
diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h
index 18641dce5184..2630faa5bc08 100644
--- a/arch/arm64/include/asm/el2_setup.h
+++ b/arch/arm64/include/asm/el2_setup.h
@@ -129,20 +129,6 @@
msr cptr_el2, x0 // Disable copro. traps to EL2
.endm
-/* SVE register access */
-.macro __init_el2_nvhe_sve
- mrs x1, id_aa64pfr0_el1
- ubfx x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4
- cbz x1, .Lskip_sve_\@
-
- bic x0, x0, #CPTR_EL2_TZ // Also disable SVE traps
- msr cptr_el2, x0 // Disable copro. traps to EL2
- isb
- mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector
- msr_s SYS_ZCR_EL2, x1 // length for EL1.
-.Lskip_sve_\@:
-.endm
-
/* Disable any fine grained traps */
.macro __init_el2_fgt
mrs x1, id_aa64mmfr0_el1
@@ -206,7 +192,6 @@
__init_el2_hstr
__init_el2_nvhe_idregs
__init_el2_nvhe_cptr
- __init_el2_nvhe_sve
__init_el2_fgt
__init_el2_nvhe_prepare_eret
.endm
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index a7d0686123a6..e5afa9eba85d 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -631,7 +631,9 @@ static const struct arm64_ftr_bits ftr_raz[] = {
__ARM64_FTR_REG_OVERRIDE(#id, id, table, &no_override)
struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
+struct arm64_ftr_override __ro_after_init id_aa64pfr0_override;
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
+struct arm64_ftr_override __ro_after_init id_aa64zfr0_override;
struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
struct arm64_ftr_override __ro_after_init id_aa64isar2_override;
@@ -669,10 +671,12 @@ static const struct __ftr_reg_entry {
ARM64_FTR_REG(SYS_ID_MMFR5_EL1, ftr_id_mmfr5),
/* Op1 = 0, CRn = 0, CRm = 4 */
- ARM64_FTR_REG(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR0_EL1, ftr_id_aa64pfr0,
+ &id_aa64pfr0_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
&id_aa64pfr1_override),
- ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
+ ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0,
+ &id_aa64zfr0_override),
ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
&id_aa64smfr0_override),
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index 0c69defa069e..d6b0a70a7080 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -98,6 +98,17 @@ SYM_CODE_START_LOCAL(elx_sync)
SYM_CODE_END(elx_sync)
SYM_CODE_START_LOCAL(__finalise_el2)
+ check_override id_aa64pfr0 ID_AA64PFR0_SVE_SHIFT .Linit_sve .Lskip_sve
+
+.Linit_sve: /* SVE register access */
+ mrs x0, cptr_el2 // Disable SVE traps
+ bic x0, x0, #CPTR_EL2_TZ
+ msr cptr_el2, x0
+ isb
+ mov x1, #ZCR_ELx_LEN_MASK // SVE: Enable full vector
+ msr_s SYS_ZCR_EL2, x1 // length for EL1.
+
+.Lskip_sve:
check_override id_aa64pfr1 ID_AA64PFR1_SME_SHIFT .Linit_sme .Lskip_sme
.Linit_sme: /* SME register access and priority mapping */
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 9314f0a8561c..7cca82639606 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -55,6 +55,30 @@ static const struct ftr_set_desc mmfr1 __initconst = {
},
};
+static bool __init pfr0_sve_filter(u64 val)
+{
+ /*
+ * Disabling SVE also means disabling all the features that
+ * are associated with it. The easiest way to do it is just to
+ * override id_aa64zfr0_el1 to be 0.
+ */
+ if (!val) {
+ id_aa64zfr0_override.val = 0;
+ id_aa64zfr0_override.mask = GENMASK(63, 0);
+ }
+
+ return true;
+}
+
+static const struct ftr_set_desc pfr0 __initconst = {
+ .name = "id_aa64pfr0",
+ .override = &id_aa64pfr0_override,
+ .fields = {
+ FIELD("sve", ID_AA64PFR0_SVE_SHIFT, pfr0_sve_filter),
+ {}
+ },
+};
+
static bool __init pfr1_sme_filter(u64 val)
{
/*
@@ -118,6 +142,7 @@ static const struct ftr_set_desc kaslr __initconst = {
static const struct ftr_set_desc * const regs[] __initconst = {
&mmfr1,
+ &pfr0,
&pfr1,
&isar1,
&isar2,
@@ -130,6 +155,7 @@ static const struct {
} aliases[] __initconst = {
{ "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" },
{ "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" },
+ { "arm64.nosve", "id_aa64pfr0.sve=0 id_aa64pfr1.sme=0" },
{ "arm64.nosme", "id_aa64pfr1.sme=0" },
{ "arm64.nobti", "id_aa64pfr1.bt=0" },
{ "arm64.nopauth",
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (7 preceding siblings ...)
2022-06-30 16:04 ` [PATCH v2 8/9] arm64: Add the arm64.nosve " Marc Zyngier
@ 2022-06-30 16:05 ` Marc Zyngier
2022-07-01 13:52 ` Mark Brown
2022-07-01 15:41 ` [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Will Deacon
9 siblings, 1 reply; 16+ messages in thread
From: Marc Zyngier @ 2022-06-30 16:05 UTC (permalink / raw)
To: linux-arm-kernel
Cc: Will Deacon, Catalin Marinas, Mark Rutland, Ard Biesheuvel,
broonie, danielmentz, saravanak, kernel-team
Add a specific override for ID_AA64SMFR0_EL1.FA64, which
disables the full A64 streaming SVE mode.
Note that no alias is provided for this, as this is already
covered by arm64.nosme, and is only added as a debugging
facility.
Signed-off-by: Marc Zyngier <maz@kernel.org>
---
arch/arm64/kernel/hyp-stub.S | 15 ++++++++-------
arch/arm64/kernel/idreg-override.c | 11 +++++++++++
2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S
index d6b0a70a7080..3dcc3272ce16 100644
--- a/arch/arm64/kernel/hyp-stub.S
+++ b/arch/arm64/kernel/hyp-stub.S
@@ -122,17 +122,18 @@ SYM_CODE_START_LOCAL(__finalise_el2)
msr sctlr_el2, x1
isb
- mov x1, #0 // SMCR controls
+ mov x0, #0 // SMCR controls
- mrs_s x2, SYS_ID_AA64SMFR0_EL1
- ubfx x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
- cbz x2, .Lskip_sme_fa64
+ // Full FP in SM?
+ mrs_s x1, SYS_ID_AA64SMFR0_EL1
+ __check_override id_aa64smfr0 ID_AA64SMFR0_FA64_SHIFT 1 .Linit_sme_fa64 .Lskip_sme_fa64
- orr x1, x1, SMCR_ELx_FA64_MASK
+.Linit_sme_fa64:
+ orr x0, x0, SMCR_ELx_FA64_MASK
.Lskip_sme_fa64:
- orr x1, x1, #SMCR_ELx_LEN_MASK // Enable full SME vector
- msr_s SYS_SMCR_EL2, x1 // length for EL1.
+ orr x0, x0, #SMCR_ELx_LEN_MASK // Enable full SME vector
+ msr_s SYS_SMCR_EL2, x0 // length for EL1.
mrs_s x1, SYS_SMIDR_EL1 // Priority mapping supported?
ubfx x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
diff --git a/arch/arm64/kernel/idreg-override.c b/arch/arm64/kernel/idreg-override.c
index 7cca82639606..aa2a53d0d417 100644
--- a/arch/arm64/kernel/idreg-override.c
+++ b/arch/arm64/kernel/idreg-override.c
@@ -127,6 +127,16 @@ static const struct ftr_set_desc isar2 __initconst = {
},
};
+static const struct ftr_set_desc smfr0 __initconst = {
+ .name = "id_aa64smfr0",
+ .override = &id_aa64smfr0_override,
+ .fields = {
+ /* FA64 is a one bit field... :-/ */
+ { "fa64", ID_AA64SMFR0_FA64_SHIFT, 1, },
+ {}
+ },
+};
+
extern struct arm64_ftr_override kaslr_feature_override;
static const struct ftr_set_desc kaslr __initconst = {
@@ -146,6 +156,7 @@ static const struct ftr_set_desc * const regs[] __initconst = {
&pfr1,
&isar1,
&isar2,
+ &smfr0,
&kaslr,
};
--
2.34.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2 7/9] arm64: Add the arm64.nosme command line option
2022-06-30 16:04 ` [PATCH v2 7/9] arm64: Add the arm64.nosme command line option Marc Zyngier
@ 2022-07-01 13:44 ` Mark Brown
0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2022-07-01 13:44 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ard Biesheuvel, danielmentz, saravanak, kernel-team
[-- Attachment #1.1: Type: text/plain, Size: 335 bytes --]
On Thu, Jun 30, 2022 at 05:04:58PM +0100, Marc Zyngier wrote:
> 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.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 8/9] arm64: Add the arm64.nosve command line option
2022-06-30 16:04 ` [PATCH v2 8/9] arm64: Add the arm64.nosve " Marc Zyngier
@ 2022-07-01 13:45 ` Mark Brown
0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2022-07-01 13:45 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ard Biesheuvel, danielmentz, saravanak, kernel-team
[-- Attachment #1.1: Type: text/plain, Size: 335 bytes --]
On Thu, Jun 30, 2022 at 05:04:59PM +0100, Marc Zyngier wrote:
> 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.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64
2022-06-30 16:05 ` [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64 Marc Zyngier
@ 2022-07-01 13:52 ` Mark Brown
0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2022-07-01 13:52 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ard Biesheuvel, danielmentz, saravanak, kernel-team
[-- Attachment #1.1: Type: text/plain, Size: 444 bytes --]
On Thu, Jun 30, 2022 at 05:05:00PM +0100, Marc Zyngier wrote:
> Add a specific override for ID_AA64SMFR0_EL1.FA64, which
> disables the full A64 streaming SVE mode.
Reviewed-by: Mark Brown <broonie@kernel.org>
> Note that no alias is provided for this, as this is already
> covered by arm64.nosme, and is only added as a debugging
> facility.
It is possible that EL3 could correctly enable SME but forget
that FA64 also needs to be enabled.
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width
2022-06-30 16:04 ` [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width Marc Zyngier
@ 2022-07-01 14:00 ` Mark Brown
0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2022-07-01 14:00 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ard Biesheuvel, danielmentz, saravanak, kernel-team
[-- Attachment #1.1: Type: text/plain, Size: 366 bytes --]
On Thu, Jun 30, 2022 at 05:04:56PM +0100, Marc Zyngier wrote:
> Currently, the override mechanism can only deal with 4bit fields,
> which is the most common case. However, we now have a bunch of
> ID registers that have more diverse field widths, such as
> ID_AA64SMFR0_EL1, which has fields that are a single bit wide.
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features
2022-06-30 16:04 ` [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features Marc Zyngier
@ 2022-07-01 14:03 ` Mark Brown
0 siblings, 0 replies; 16+ messages in thread
From: Mark Brown @ 2022-07-01 14:03 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-arm-kernel, Will Deacon, Catalin Marinas, Mark Rutland,
Ard Biesheuvel, danielmentz, saravanak, kernel-team
[-- Attachment #1.1: Type: text/plain, Size: 382 bytes --]
On Thu, Jun 30, 2022 at 05:04:57PM +0100, Marc Zyngier wrote:
> In order to feal with early override of features that are not
> classically encoded in a standard ID register with a 4 bit wide
> field, add a primitive that takes a sysreg value as an input
> (instead of the usual sysreg name) as well as a bit field
> width (usually 4).
Reviewed-by: Mark Brown <broonie@kernel.org>
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
[-- Attachment #2: Type: text/plain, Size: 176 bytes --]
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
` (8 preceding siblings ...)
2022-06-30 16:05 ` [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64 Marc Zyngier
@ 2022-07-01 15:41 ` Will Deacon
9 siblings, 0 replies; 16+ messages in thread
From: Will Deacon @ 2022-07-01 15:41 UTC (permalink / raw)
To: Marc Zyngier, linux-arm-kernel
Cc: catalin.marinas, kernel-team, Will Deacon, danielmentz, broonie,
saravanak, Mark Rutland, Ard Biesheuvel
On Thu, 30 Jun 2022 17:04:51 +0100, Marc Zyngier wrote:
> This very short series reworks the way arm64 CPUs boot (yes, again) in
> order to opt out of some features early at boot, on top of the
> existing VHE-forced-into-nVHE use case and using the same idreg
> override infrastructure.
>
> The main victim here is SVE, because it seems that people have all
> sort of broken firmware out there, and that a distribution kernel
> cannot boot on that. And since we have a dependency between SVE and
> SME, disabling the former also disables the latter.
>
> [...]
Applied to arm64 (testing), thanks!
[1/9] arm64: Rename the VHE switch to "finalise_el2"
https://git.kernel.org/arm64/c/7ddb0c3df788
[2/9] arm64: Save state of HCR_EL2.E2H before switch to EL1
https://git.kernel.org/arm64/c/b65e411d6cc2
[3/9] arm64: Allow sticky E2H when entering EL1
https://git.kernel.org/arm64/c/ae4b7e38e9a9
[4/9] arm64: Factor out checking of a feature against the override into a macro
https://git.kernel.org/arm64/c/fa8aa59ae645
[5/9] arm64: Allow the idreg override to deal with variable field width
https://git.kernel.org/arm64/c/6b7ec18c0976
[6/9] arm64: Expose a __check_override primitive for oddball features
https://git.kernel.org/arm64/c/6ab7661e1d39
[7/9] arm64: Add the arm64.nosme command line option
https://git.kernel.org/arm64/c/b3000e2133d8
[8/9] arm64: Add the arm64.nosve command line option
https://git.kernel.org/arm64/c/504ee23611c4
[9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64
https://git.kernel.org/arm64/c/18c9aa490795
Cheers,
--
Will
https://fixes.arm64.dev
https://next.arm64.dev
https://will.arm64.dev
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2022-07-01 15:43 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-30 16:04 [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 1/9] arm64: Rename the VHE switch to "finalise_el2" Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 2/9] arm64: Save state of HCR_EL2.E2H before switch to EL1 Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 3/9] arm64: Allow sticky E2H when entering EL1 Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 4/9] arm64: Factor out checking of a feature against the override into a macro Marc Zyngier
2022-06-30 16:04 ` [PATCH v2 5/9] arm64: Allow the idreg override to deal with variable field width Marc Zyngier
2022-07-01 14:00 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 6/9] arm64: Expose a __check_override primitive for oddball features Marc Zyngier
2022-07-01 14:03 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 7/9] arm64: Add the arm64.nosme command line option Marc Zyngier
2022-07-01 13:44 ` Mark Brown
2022-06-30 16:04 ` [PATCH v2 8/9] arm64: Add the arm64.nosve " Marc Zyngier
2022-07-01 13:45 ` Mark Brown
2022-06-30 16:05 ` [PATCH v2 9/9] arm64: Add an override for ID_AA64SMFR0_EL1.FA64 Marc Zyngier
2022-07-01 13:52 ` Mark Brown
2022-07-01 15:41 ` [PATCH v2 0/9] arm64: Disabling SVE/SME from the command-line Will Deacon
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).