arm64: Early CPU feature override, and applications to VHE, BTI and PAuth
Subsystems (4)
Marc Zyngier
maintainerv4 cover arm64: Early CPU feature override, and applications to VHE, BTI and PAuth
It recently came to light that there is a need to be able to override some CPU features very early on, before the kernel is fully up and running. The reasons for this range from specific feature support (such as using Protected KVM on VHE HW, which is the main motivation for this work) to errata workaround (a feature is broken on a CPU and needs to be turned off, or rather not enabled).
This series tries to offer a limited framework for this kind of problems, by allowing a set of options to be passed on the command-line and altering the feature set that the cpufeature subsystem exposes to the rest of the kernel. Note that this doesn't change anything for code that directly uses the CPU ID registers.
The series completely changes the way a VHE-capable system boots, by *always* booting non-VHE first, and then upgrading to VHE when deemed capable. Although it sounds scary, this is actually simple to implement (and I wish I had done that five years ago). The "upgrade to VHE" path is then conditioned on the VHE feature not being disabled from the command-line.
Said command-line parsing borrows a lot from the kaslr code, and subsequently allows the "nokaslr" option to be moved to the new infrastructure (though it all looks a bit... odd).
Further patches now add support for disabling BTI and PAuth, the latter being based on an initial series by Srinivas Ramana[0]. There is some ongoing discussions about being able to disable MTE, but no clear resolution on that subject yet.
This has been tested on multiple VHE and non-VHE systems.
* From v3 [3]:
- Fixed the VHE_RESTART stub (duh!)
- Switched to using arm64_ftr_safe_value() instead of the user provided value
- Per-feature override warning
* From v2 [2]:
- Simplify the VHE_RESTART stub
- Fixed a number of spelling mistakes, and hopefully introduced a few more
- Override features in __read_sysreg_by_encoding()
- Allow both BTI and PAuth to be overridden on the command line
- Rebased on -rc3
* From v1 [1]:
- Fix SPE init on VHE when EL2 doesn't own SPE
- Fix re-init when KASLR is used
- Handle the resume path
- Rebased to 5.11-rc2
[0] https://lore.kernel.org/r/[email protected]
[1] https://lore.kernel.org/r/[email protected]
[2] https://lore.kernel.org/r/[email protected]
[3] https://lore.kernel.org/r/[email protected]
Marc Zyngier (20):
arm64: Fix labels in el2_setup macros
arm64: Fix outdated TCR setup comment
arm64: Turn the MMU-on sequence into a macro
arm64: Provide an 'upgrade to VHE' stub hypercall
arm64: Initialise as nVHE before switching to VHE
arm64: Move VHE-specific SPE setup to mutate_to_vhe()
arm64: Simplify init_el2_state to be non-VHE only
arm64: Move SCTLR_EL1 initialisation to EL-agnostic code
arm64: cpufeature: Add global feature override facility
arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()
arm64: Extract early FDT mapping from kaslr_early_init()
arm64: cpufeature: Add an early command-line cpufeature override
facility
arm64: Allow ID_AA64MMFR1_EL1.VH to be overridden from the command
line
arm64: Honor VHE being disabled from the command-line
arm64: Add an aliasing facility for the idreg override
arm64: Make kvm-arm.mode={nvhe,protected} an alias of
id_aa64mmfr1.vh=0
KVM: arm64: Document HVC_VHE_RESTART stub hypercall
arm64: Move "nokaslr" over to the early cpufeature infrastructure
arm64: cpufeatures: Allow disabling of BTI from the command-line
arm64: cpufeatures: Allow disabling of Pointer Auth from the
command-line
Srinivas Ramana (1):
arm64: Defer enabling pointer authentication on boot core
.../admin-guide/kernel-parameters.txt | 9 + Documentation/virt/kvm/arm/hyp-abi.rst | 9 + arch/arm64/include/asm/assembler.h | 17 ++ arch/arm64/include/asm/cpufeature.h | 10 + arch/arm64/include/asm/el2_setup.h | 60 ++---- arch/arm64/include/asm/pointer_auth.h | 10 + arch/arm64/include/asm/setup.h | 11 + arch/arm64/include/asm/stackprotector.h | 1 + arch/arm64/include/asm/virt.h | 7 +- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/cpufeature.c | 75 ++++++- arch/arm64/kernel/head.S | 75 ++----- arch/arm64/kernel/hyp-stub.S | 124 ++++++++++- arch/arm64/kernel/idreg-override.c | 199 ++++++++++++++++++ arch/arm64/kernel/kaslr.c | 44 +--- arch/arm64/kernel/setup.c | 15 ++ arch/arm64/kernel/sleep.S | 1 + arch/arm64/kvm/arm.c | 3 + arch/arm64/kvm/hyp/nvhe/hyp-init.S | 2 +- arch/arm64/mm/mmu.c | 2 +- arch/arm64/mm/proc.S | 16 +- 21 files changed, 523 insertions(+), 169 deletions(-) create mode 100644 arch/arm64/include/asm/setup.h create mode 100644 arch/arm64/kernel/idreg-override.c
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 1/21 arm64: Fix labels in el2_setup macros
If someone happens to write the following code:
b 1f init_el2_state vhe 1: [...]
they will be in for a long debugging session, as the label "1f" will be resolved *inside* the init_el2_state macro instead of after it. Not really what one expects.
Instead, rewite the EL2 setup macros to use unambiguous labels, thanks to the usual macro counter trick.
--- arch/arm64/include/asm/el2_setup.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
arch/arm64/include/asm/el2_setup.h +12 -12
@@ -45,24 +45,24 @@mrs x1, id_aa64dfr0_el1 sbfx x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4 cmp x0, #1 - b.lt 1f // Skip if no PMU present + b.lt .Lskip_pmu_\@ // Skip if no PMU present mrs x0, pmcr_el0 // Disable debug access traps ubfx x0, x0, #11, #5 // to EL2 and allow access to -1: +.Lskip_pmu_\@: csel x2, xzr, x0, lt // all PMU counters from EL1/* Statistical profiling */ ubfx x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 - cbz x0, 3f // Skip if SPE not present + cbz x0, .Lskip_spe_\@ // Skip if SPE not present .ifeqs "\mode", "nvhe" mrs_s x0, SYS_PMBIDR_EL1 // If SPE available at EL2, and x0, x0, #(1 << SYS_PMBIDR_EL1_P_SHIFT) - cbnz x0, 2f // then permit sampling of physical + cbnz x0, .Lskip_spe_el2_\@ // then permit sampling of physical mov x0, #(1 << SYS_PMSCR_EL2_PCT_SHIFT | \ 1 << SYS_PMSCR_EL2_PA_SHIFT) msr_s SYS_PMSCR_EL2, x0 // addresses and physical counter -2: +.Lskip_spe_el2_\@: mov x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) orr x2, x2, x0 // If we don't have VHE, then// use EL1&0 translation.
@@ -71,7 +71,7 @@// and disable access from EL1 .endif -3: +.Lskip_spe_\@:msr mdcr_el2, x2// Configure debug traps .endm
@@ -79,9 +79,9 @@ .macro __init_el2_lormrs x1, id_aa64mmfr1_el1 ubfx x0, x1, #ID_AA64MMFR1_LOR_SHIFT, 4 - cbz x0, 1f + cbz x0, .Lskip_lor_\@ msr_s SYS_LORC_EL1, xzr -1: +.Lskip_lor_\@: .endm/* Stage-2 translation */
@@ -93,7 +93,7 @@ .macro __init_el2_gicv3mrs x0, id_aa64pfr0_el1 ubfx x0, x0, #ID_AA64PFR0_GIC_SHIFT, #4 - cbz x0, 1f + cbz x0, .Lskip_gicv3_\@ mrs_s x0, SYS_ICC_SRE_EL2 orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1
@@ -103,7 +103,7 @@mrs_s x0,SYS_ICC_SRE_EL2 // Read SRE back, tbz x0, #0, 1f // and check that it sticks msr_s SYS_ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults -1: +.Lskip_gicv3_\@: .endm .macro __init_el2_hstr
@@ -128,14 +128,14 @@ .macro __init_el2_nvhe_svemrs x1, id_aa64pfr0_el1 ubfx x1, x1, #ID_AA64PFR0_SVE_SHIFT, #4 - cbz x1, 1f + 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. -1: +.Lskip_sve_\@: .endm .macro __init_el2_nvhe_prepare_eret
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 01/21] arm64: Fix labels in el2_setup macros
Quoted 11 lines · Marc Zyngier
If someone happens to write the following code:
b 1f init_el2_state vhe 1: [...]they will be in for a long debugging session, as the label "1f" will be resolved *inside* the
init_el2_statemacro instead of after it. Not really what one expects.
Quoted 8 lines
Instead, rewite the EL2 setup macros to use unambiguous labels, thanks to the usual macro counter trick.
Acked-by Catalin Marinas <[email protected]>Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/include/asm/el2_setup.h | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 2/21 arm64: Fix outdated TCR setup comment
In reply to Marc ZyngierThe arm64 kernel has long be able to use more than 39bit VAs. Since day one, actually. Let's rewrite the offending comment.
--- arch/arm64/mm/proc.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/mm/proc.S +2 -2
@@ -464,8 +464,8 @@ SYM_FUNC_START(__cpu_setup) #endif msr mair_el1, x5 /* - * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for - * both user and kernel. + * Set/prepare TCR and TTBR. TCR_EL1.T1SZ gets further + * adjusted if the kernel is compiled with 52bit VA support. */ mov_q x10, TCR_TxSZ(VA_BITS) | TCR_CACHE_FLAGS | TCR_SMP_FLAGS | \ TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 02/21] arm64: Fix outdated TCR setup comment
Quoted 13 lines · Marc Zyngier
The arm64 kernel has long be able to use more than 39bit VAs. Since day one, actually. Let's rewrite the offending comment.
Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/mm/proc.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)arch/arm64/mm/proc.S +0
-0
arch/arm64/mm/proc.S SYM_FUNC_START(__cpu_setup) · line 468
Quoted 7 lines
arch/arm64/mm/proc.S +2
-2@@ -464,8 +464,8 @@ SYM_FUNC_START(__cpu_setup) #endif msr mair_el1, x5 /* - * Set/prepare TCR and TTBR. We use 512GB (39-bit) address range for - * both user and kernel. + * Set/prepare TCR and TTBR. TCR_EL1.T1SZ gets further + * adjusted if the kernel is compiled with 52bit VA support.
I think both T0SZ and T1SZ get updated based on a mismatch between the kernel configuration and the hardware support. Anyway, I'm not asking for a detailed comment here, so:
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 3/21 arm64: Turn the MMU-on sequence into a macro
In reply to Marc ZyngierTurning the MMU on is a popular sport in the arm64 kernel, and we do it more than once, or even twice. As we are about to add even more, let's turn it into a macro.
No expected functional change.
--- arch/arm64/include/asm/assembler.h | 17 +++++++++++++++++ arch/arm64/kernel/head.S | 19 ++++--------------- arch/arm64/mm/proc.S | 12 +----------- 3 files changed, 22 insertions(+), 26 deletions(-)
arch/arm64/include/asm/assembler.h +17 -0
@@ -675,6 +675,23 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU .endif .endm +/* + * Set SCTLR_EL1 to the passed value, and invalidate the local icache + * in the process. This is called when setting the MMU on. + */ +.macro set_sctlr_el1, reg + msr sctlr_el1, \reg + isb + /* + * Invalidate the local I-cache so that any instructions fetched + * speculatively from the PoC are discarded, since they may have + * been dynamically patched at the PoU. + */ + ic iallu + dsb nsh + isb +.endm +/* * Check whether to yield to another runnable task from kernel mode NEON code * (which runs with preemption disabled).
arch/arm64/kernel/head.S +4 -15
@@ -703,16 +703,9 @@ SYM_FUNC_START(__enable_mmu) offset_ttbr1 x1, x3 msr ttbr1_el1, x1 // load TTBR1 isb - msr sctlr_el1, x0 - isb - /* - * Invalidate the local I-cache so that any instructions fetched - * speculatively from the PoC are discarded, since they may have - * been dynamically patched at the PoU. - */ - ic iallu - dsb nsh - isb + + set_sctlr_el1 x0 + ret SYM_FUNC_END(__enable_mmu)
@@ -883,11 +876,7 @@ SYM_FUNC_START_LOCAL(__primary_switch) tlbi vmalle1 // Remove any stale TLB entries dsb nsh - msr sctlr_el1, x19 // re-enable the MMU - isb - ic iallu // flush instructions fetched - dsb nsh // via old mapping - isb + set_sctlr_el1 x19 // re-enable the MMU bl __relocate_kernel #endif
arch/arm64/mm/proc.S +1 -11
@@ -291,17 +291,7 @@ skip_pgd: /* We're done: fire up the MMU again */ mrs x17, sctlr_el1 orr x17, x17, #SCTLR_ELx_M - msr sctlr_el1, x17 - isb - - /* - * Invalidate the local I-cache so that any instructions fetched - * speculatively from the PoC are discarded, since they may have - * been dynamically patched at the PoU. - */ - ic iallu - dsb nsh - isb + set_sctlr_el1 x17 /* Set the flag to zero to indicate that we're all done */ str wzr, [flag_ptr]
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 03/21] arm64: Turn the MMU-on sequence into a macro
Quoted 7 lines · Marc Zyngier
Turning the MMU on is a popular sport in the arm64 kernel, and we do it more than once, or even twice. As we are about to add even more, let's turn it into a macro.
No expected functional change.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 4/21 arm64: Provide an 'upgrade to VHE' stub hypercall
In reply to Marc ZyngierAs we are about to change the way a VHE system boots, let's provide the core helper, in the form of a stub hypercall that enables VHE and replicates the full EL1 context at EL2, thanks to EL1 and VHE-EL2 being extremely similar.
On exception return, the kernel carries on at EL2. Fancy!
Nothing calls this new hypercall yet, so no functional change.
--- arch/arm64/include/asm/virt.h | 7 +++- arch/arm64/kernel/hyp-stub.S | 67 +++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-)
arch/arm64/include/asm/virt.h +6 -1
@@ -35,8 +35,13 @@*/ #define HVC_RESET_VECTORS 2 +/* +* HVC_VHE_RESTART - Upgrade the CPU from EL1 to EL2, if possible +*/ +#define HVC_VHE_RESTART 3 +/* Max number of HYP stub hypercalls */ -#define HVC_STUB_HCALL_NR 3 +#define HVC_STUB_HCALL_NR 4/* Error returned when an invalid stub number is passed into x0 */ #define HVC_STUB_ERR 0xbadca11
arch/arm64/kernel/hyp-stub.S +65 -2
90 lines not on this page · raw message
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 04/21] arm64: Provide an 'upgrade to VHE' stub hypercall
Quoted 68 lines · Marc Zyngier
As we are about to change the way a VHE system boots, let's provide the core helper, in the form of a stub hypercall that enables VHE and replicates the full EL1 context at EL2, thanks to EL1 and VHE-EL2 being extremely similar.
On exception return, the kernel carries on at EL2. Fancy!
Nothing calls this new hypercall yet, so no functional change.
Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/include/asm/virt.h | 7 +++- arch/arm64/kernel/hyp-stub.S | 67 +++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-)arch/arm64/include/asm/virt.h +6
-1@@ -35,8 +35,13 @@*/ #define HVC_RESET_VECTORS 2 +/* +* HVC_VHE_RESTART - Upgrade the CPU from EL1 to EL2, if possible +*/ +#define HVC_VHE_RESTART 3 +/* Max number of HYP stub hypercalls */ -#define HVC_STUB_HCALL_NR 3 +#define HVC_STUB_HCALL_NR 4/* Error returned when an invalid stub number is passed into x0 */ #define HVC_STUB_ERR 0xbadca11arch/arm64/kernel/hyp-stub.S +5
-2@@ -8,9 +8,9 @@ #include <linux/init.h> #include <linux/linkage.h> -#include <linux/irqchip/arm-gic-v3.h> #include <asm/assembler.h> +#include <asm/el2_setup.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> #include <asm/ptrace.h>@@ -47,10 +47,13 @@ SYM_CODE_END(__hyp_stub_vectors) SYM_CODE_START_LOCAL(el1_sync) cmp x0, #HVC_SET_VECTORS - b.ne 2f + b.ne 1f msr vbar_el2, x1 b 9f +1: cmp x0, #HVC_VHE_RESTART + b.eq mutate_to_vhe + 2: cmp x0, #HVC_SOFT_RESTART b.ne 3f mov x0, x2@@ -70,6 +73,66 @@ SYM_CODE_START_LOCAL(el1_sync) eret SYM_CODE_END(el1_sync)
arch/arm64/kernel/hyp-stub.S SYM_CODE_START_LOCAL(el1_sync) · line 85
Quoted 10 lines
arch/arm64/kernel/hyp-stub.S +10
-0+// nVHE? No way! Give me the real thing! +SYM_CODE_START_LOCAL(mutate_to_vhe) + // Sanity check: MMU *must* be off + mrs x0, sctlr_el2 + tbnz x0, #0, 1f + + // Needs to be VHE capable, obviously + mrs x0, id_aa64mmfr1_el1 + ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x0, 1f
nit: There is a HVC_STUB_ERR that you could return if these sanity checks fail. The documentation also states that it should be returned on error.
Quoted 56 lines
arch/arm64/kernel/hyp-stub.S +50
-0+ + // Engage the VHE magic! + mov_q x0, HCR_HOST_VHE_FLAGS + msr hcr_el2, x0 + isb + + // Doesn't do much on VHE, but still, worth a shot + init_el2_state vhe + + // Use the EL1 allocated stack, per-cpu offset + mrs x0, sp_el1 + mov sp, x0 + mrs x0, tpidr_el1 + msr tpidr_el2, x0 + + // FP configuration, vectors + mrs_s x0, SYS_CPACR_EL12 + msr cpacr_el1, x0 + mrs_s x0, SYS_VBAR_EL12 + msr vbar_el1, x0 + + // Transfer the MM state from EL1 to EL2 + mrs_s x0, SYS_TCR_EL12 + msr tcr_el1, x0 + mrs_s x0, SYS_TTBR0_EL12 + msr ttbr0_el1, x0 + mrs_s x0, SYS_TTBR1_EL12 + msr ttbr1_el1, x0 + mrs_s x0, SYS_MAIR_EL12 + msr mair_el1, x0 + isb + + // Invalidate TLBs before enabling the MMU + tlbi vmalle1 + dsb nsh + + // Enable the EL2 S1 MMU, as set up from EL1 + mrs_s x0, SYS_SCTLR_EL12 + set_sctlr_el1 x0 + + // Hack the exception return to stay at EL2 + mrs x0, spsr_el1 + and x0, x0, #~PSR_MODE_MASK + mov x1, #PSR_MODE_EL2h + orr x0, x0, x1 + msr spsr_el1, x0 + +1: eret +SYM_CODE_END(mutate_to_vhe) + .macro invalid_vector label SYM_CODE_START_LOCAL(\label) b \labelSignature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerRe: [PATCH v4 04/21] arm64: Provide an 'upgrade to VHE' stub hypercall
Quoted 70 lines · David Brazdil
Quoted 68 lines · Marc Zyngier
As we are about to change the way a VHE system boots, let's provide the core helper, in the form of a stub hypercall that enables VHE and replicates the full EL1 context at EL2, thanks to EL1 and VHE-EL2 being extremely similar.
On exception return, the kernel carries on at EL2. Fancy!
Nothing calls this new hypercall yet, so no functional change.
Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/include/asm/virt.h | 7 +++- arch/arm64/kernel/hyp-stub.S | 67 +++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-)arch/arm64/include/asm/virt.h +6
-1@@ -35,8 +35,13 @@*/ #define HVC_RESET_VECTORS 2 +/* +* HVC_VHE_RESTART - Upgrade the CPU from EL1 to EL2, if possible +*/ +#define HVC_VHE_RESTART 3 +/* Max number of HYP stub hypercalls */ -#define HVC_STUB_HCALL_NR 3 +#define HVC_STUB_HCALL_NR 4/* Error returned when an invalid stub number is passed into x0 */ #define HVC_STUB_ERR 0xbadca11arch/arm64/kernel/hyp-stub.S +5
-2@@ -8,9 +8,9 @@ #include <linux/init.h> #include <linux/linkage.h> -#include <linux/irqchip/arm-gic-v3.h> #include <asm/assembler.h> +#include <asm/el2_setup.h> #include <asm/kvm_arm.h> #include <asm/kvm_asm.h> #include <asm/ptrace.h>@@ -47,10 +47,13 @@ SYM_CODE_END(__hyp_stub_vectors) SYM_CODE_START_LOCAL(el1_sync) cmp x0, #HVC_SET_VECTORS - b.ne 2f + b.ne 1f msr vbar_el2, x1 b 9f +1: cmp x0, #HVC_VHE_RESTART + b.eq mutate_to_vhe + 2: cmp x0, #HVC_SOFT_RESTART b.ne 3f mov x0, x2@@ -70,6 +73,66 @@ SYM_CODE_START_LOCAL(el1_sync) eret SYM_CODE_END(el1_sync)
Quoted 14 lines
arch/arm64/kernel/hyp-stub.S SYM_CODE_START_LOCAL(el1_sync) · line 85
Quoted 10 lines
arch/arm64/kernel/hyp-stub.S +10
-0+// nVHE? No way! Give me the real thing! +SYM_CODE_START_LOCAL(mutate_to_vhe) + // Sanity check: MMU *must* be off + mrs x0, sctlr_el2 + tbnz x0, #0, 1f + + // Needs to be VHE capable, obviously + mrs x0, id_aa64mmfr1_el1 + ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x0, 1fnit: There is a
HVC_STUB_ERRthat you could return if these sanity checks fail. The documentation also states that it should be returned on error.
Good point. I've now added it, but how the error can be handled is still up in the air. For now, I've decided to let the kernel continue its (probably doomed) course.
Thanks,
M.
Signature · 5 lines
Without deviation from the norm, progress is not possible. _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 5/21 arm64: Initialise as nVHE before switching to VHE
In reply to Marc ZyngierAs we are aiming to be able to control whether we enable VHE or not, let's always drop down to EL1 first, and only then upgrade to VHE if at all possible.
This means that if the kernel is booted at EL2, we always start with a nVHE init, drop to EL1 to initialise the the kernel, and only then upgrade the kernel EL to EL2 if possible (the process is obviously shortened for secondary CPUs).
The resume path is handled similarly to a secondary CPU boot.
--- arch/arm64/kernel/head.S | 38 ++---------------------------------- arch/arm64/kernel/hyp-stub.S | 24 +++++++++++++++++++++++ arch/arm64/kernel/sleep.S | 1 + 3 files changed, 27 insertions(+), 36 deletions(-)
arch/arm64/kernel/head.S +2 -36
@@ -433,6 +433,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) bl __pi_memset dsb ishst // Make zero page visible to PTW + bl switch_to_vhe #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_init #endif
@@ -493,42 +494,6 @@ SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) eret SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) -#ifdef CONFIG_ARM64_VHE - /* - * Check for VHE being present. x2 being non-zero indicates that we - * do have VHE, and that the kernel is intended to run at EL2. - */ - mrs x2, id_aa64mmfr1_el1 - ubfx x2, x2, #ID_AA64MMFR1_VHE_SHIFT, #4 -#else - mov x2, xzr -#endif - cbz x2, init_el2_nvhe - - /* - * When VHE _is_ in use, EL1 will not be used in the host and - * requires no configuration, and all non-hyp-specific EL2 setup - * will be done via the _EL1 system register aliases in __cpu_setup. - */ - mov_q x0, HCR_HOST_VHE_FLAGS - msr hcr_el2, x0 - isb - - init_el2_state vhe - - isb - - mov_q x0, INIT_PSTATE_EL2 - msr spsr_el2, x0 - msr elr_el2, lr - mov w0, #BOOT_CPU_MODE_EL2 - eret - -SYM_INNER_LABEL(init_el2_nvhe, SYM_L_LOCAL) - /* - * When VHE is not in use, early init of EL2 and EL1 needs to be - * done here. - */ mov_q x0, INIT_SCTLR_EL1_MMU_OFF msr sctlr_el1, x0
@@ -623,6 +588,7 @@ SYM_FUNC_START_LOCAL(secondary_startup) /* * Common entry point for secondary CPUs. */ + bl switch_to_vhe bl __cpu_secondary_check52bitva bl __cpu_setup // initialise processor adrp x1, swapper_pg_dir
arch/arm64/kernel/hyp-stub.S +24 -0
@@ -181,3 +181,27 @@ SYM_FUNC_START(__hyp_reset_vectors) hvc #0 ret SYM_FUNC_END(__hyp_reset_vectors) + +/* + * Entry point to switch to VHE if deemed capable + */ +SYM_FUNC_START(switch_to_vhe) +#ifdef CONFIG_ARM64_VHE + // Need to have booted at EL2 + adr_l x1, __boot_cpu_mode + ldr w0, [x1] + cmp w0, #BOOT_CPU_MODE_EL2 + b.ne 1f + + // and still be at EL1 + mrs x0, CurrentEL + cmp x0, #CurrentEL_EL1 + b.ne 1f + + // Turn the world upside down + mov x0, #HVC_VHE_RESTART + hvc #0 +1: +#endif + ret +SYM_FUNC_END(switch_to_vhe)
arch/arm64/kernel/sleep.S +1 -0
@@ -100,6 +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 __cpu_setup /* enable the MMU early - so we can access sleep_save_stash by va */ adrp x1, swapper_pg_dir
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 6/21 arm64: Move VHE-specific SPE setup to mutate_to_vhe()
In reply to Marc ZyngierThere isn't much that a VHE kernel needs on top of whatever has been done for nVHE, so let's move the little we need to the VHE stub (the SPE setup), and drop the init_el2_state macro.
No expected functional change.
--- arch/arm64/kernel/hyp-stub.S | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
arch/arm64/kernel/hyp-stub.S +25 -3
@@ -89,9 +89,6 @@ SYM_CODE_START_LOCAL(mutate_to_vhe) msr hcr_el2, x0 isb - // Doesn't do much on VHE, but still, worth a shot - init_el2_state vhe - // Use the EL1 allocated stack, per-cpu offset mrs x0, sp_el1 mov sp, x0
@@ -104,6 +101,31 @@ SYM_CODE_START_LOCAL(mutate_to_vhe) mrs_s x0, SYS_VBAR_EL12 msr vbar_el1, x0 + // Fixup SPE configuration, if supported... + mrs x1, id_aa64dfr0_el1 + ubfx x1, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 + mov x2, xzr + cbz x1, skip_spe + + // ... and not owned by EL3 + mrs_s x0, SYS_PMBIDR_EL1 + and x0, x0, #(1 << SYS_PMBIDR_EL1_P_SHIFT) + cbnz x0, skip_spe + + // Let the SPE driver in control of the sampling + mrs_s x0, SYS_PMSCR_EL1 + bic x0, x0, #(1 << SYS_PMSCR_EL2_PCT_SHIFT) + bic x0, x0, #(1 << SYS_PMSCR_EL2_PA_SHIFT) + msr_s SYS_PMSCR_EL1, x0 + mov x2, #MDCR_EL2_TPMS + +skip_spe: + // For VHE, use EL2 translation and disable access from EL1 + mrs x0, mdcr_el2 + bic x0, x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) + orr x0, x0, x2 + msr mdcr_el2, x0 + // Transfer the MM state from EL1 to EL2 mrs_s x0, SYS_TCR_EL12 msr tcr_el1, x0
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 7/21 arm64: Simplify init_el2_state to be non-VHE only
In reply to Marc ZyngierAs init_el2_state is now nVHE only, let's simplify it and drop the VHE setup.
--- arch/arm64/include/asm/el2_setup.h | 36 +++++++----------------------- arch/arm64/kernel/head.S | 2 +- arch/arm64/kvm/hyp/nvhe/hyp-init.S | 2 +- 3 files changed, 10 insertions(+), 30 deletions(-)
arch/arm64/include/asm/el2_setup.h +8 -28
@@ -32,16 +32,14 @@* to transparently mess with the EL0 bits via CNTKCTL_EL1 access in * EL2. */ -.macro __init_el2_timers mode -.ifeqs "\mode", "nvhe" +.macro __init_el2_timersmrs x0, cnthctl_el2 orr x0, x0, #3 // Enable EL1 physical timers msr cnthctl_el2, x0 -.endif msr cntvoff_el2, xzr // Clear virtual offset .endm -.macro __init_el2_debug mode +.macro __init_el2_debug mrs x1, id_aa64dfr0_el1 sbfx x0, x1, #ID_AA64DFR0_PMUVER_SHIFT, #4 cmp x0, #1
@@ -55,7 +53,6 @@ ubfx x0, x1, #ID_AA64DFR0_PMSVER_SHIFT, #4 cbz x0, .Lskip_spe_\@ // Skip if SPE not present -.ifeqs "\mode", "nvhe" mrs_s x0, SYS_PMBIDR_EL1 // If SPE available at EL2, and x0, x0, #(1 << SYS_PMBIDR_EL1_P_SHIFT) cbnz x0, .Lskip_spe_el2_\@ // then permit sampling of physical
@@ -66,10 +63,6 @@ mov x0, #(MDCR_EL2_E2PB_MASK << MDCR_EL2_E2PB_SHIFT) orr x2, x2, x0 // If we don't have VHE, then// use EL1&0 translation. -.else - orr x2, x2, #MDCR_EL2_TPMS // For VHE, use EL2 translation - // and disable access from EL1 -.endif .Lskip_spe_\@: msr mdcr_el2, x2 // Configure debug traps
@@ -145,37 +138,24 @@/** * Initialize EL2 registers to sane values. This should be called early on all -* cores that were booted in EL2. +* cores that were booted in EL2. Note that everything gets initialised as +* if VHE was not evailable. The kernel context will be upgraded to VHE +* if possible later on in the boot process * * Regs: x0, x1 and x2 are clobbered. */ -.macro init_el2_state mode -.ifnes "\mode", "vhe" -.ifnes "\mode", "nvhe" -.error "Invalid 'mode' argument" -.endif -.endif - +.macro init_el2_state__init_el2_sctlr - __init_el2_timers \mode - __init_el2_debug \mode + __init_el2_timers +__init_el2_debug __init_el2_lor__init_el2_stage2 __init_el2_gicv3__init_el2_hstr - - /* - * When VHE is not in use, early init of EL2 needs to be done here. - * When VHE _is_ in use, EL1 will not be used in the host and - * requires no configuration, and all non-hyp-specific EL2 setup - * will be done via the _EL1 system register aliases in __cpu_setup. - */ -.ifeqs "\mode", "nvhe" __init_el2_nvhe_idregs__init_el2_nvhe_cptr __init_el2_nvhe_sve __init_el2_nvhe_prepare_eret -.endif .endm#endif /* __ARM_KVM_INIT_H__ */
arch/arm64/kernel/head.S +1 -1
@@ -501,7 +501,7 @@ SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) msr hcr_el2, x0 isb - init_el2_state nvhe + init_el2_state /* Hypervisor stub */ adr_l x0, __hyp_stub_vectors
arch/arm64/kvm/hyp/nvhe/hyp-init.S +1 -1
@@ -189,7 +189,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) 2: msr SPsel, #1 // We want to use SP_EL{1,2} /* Initialize EL2 CPU state to sane values. */ - init_el2_state nvhe // Clobbers x0..x2 + init_el2_state // Clobbers x0..x2 /* Enable MMU, set vectors and stack. */ mov x0, x28
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 8/21 arm64: Move SCTLR_EL1 initialisation to EL-agnostic code
In reply to Marc ZyngierWe can now move the initial SCTLR_EL1 setup to be used for both EL1 and EL2 setup.
--- arch/arm64/kernel/head.S | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
arch/arm64/kernel/head.S +3 -5
@@ -479,13 +479,14 @@ EXPORT_SYMBOL(kimage_vaddr) * booted in EL1 or EL2 respectively. */ SYM_FUNC_START(init_kernel_el) + mov_q x0, INIT_SCTLR_EL1_MMU_OFF + msr sctlr_el1, x0 + mrs x0, CurrentEL cmp x0, #CurrentEL_EL2 b.eq init_el2 SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) - mov_q x0, INIT_SCTLR_EL1_MMU_OFF - msr sctlr_el1, x0 isb mov_q x0, INIT_PSTATE_EL1 msr spsr_el1, x0
@@ -494,9 +495,6 @@ SYM_INNER_LABEL(init_el1, SYM_L_LOCAL) eret SYM_INNER_LABEL(init_el2, SYM_L_LOCAL) - mov_q x0, INIT_SCTLR_EL1_MMU_OFF - msr sctlr_el1, x0 - mov_q x0, HCR_HOST_NVHE_FLAGS msr hcr_el2, x0 isb
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 08/21] arm64: Move SCTLR_EL1 initialisation to EL-agnostic code
Quoted 4 lines · Marc Zyngier
We can now move the initial
SCTLR_EL1setup to be used for both EL1 and EL2 setup.Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 9/21 arm64: cpufeature: Add global feature override facility
In reply to Marc ZyngierAdd a facility to globally override a feature, no matter what the HW says. Yes, this sounds dangerous, but we do respect the "safe" value for a given feature. This doesn't mean the user doesn't need to know what they are doing.
Nothing uses this yet, so we are pretty safe. For now.
--- arch/arm64/include/asm/cpufeature.h | 2 ++ arch/arm64/kernel/cpufeature.c | 44 +++++++++++++++++++++++++---- 2 files changed, 41 insertions(+), 5 deletions(-)
arch/arm64/include/asm/cpufeature.h +2 -0
@@ -75,6 +75,8 @@ struct arm64_ftr_reg {u64 sys_val;u64 user_val;const struct arm64_ftr_bits *ftr_bits; +u64 *override_val; +u64 *override_mask; };extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;
arch/arm64/kernel/cpufeature.c +39 -5
67 lines not on this page · raw message
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 09/21] arm64: cpufeature: Add global feature override facility
Quoted 60 lines · Marc Zyngier
arch/arm64/include/asm/cpufeature.h +2
-0@@ -75,6 +75,8 @@ struct arm64_ftr_reg {u64 sys_val;u64 user_val;const struct arm64_ftr_bits *ftr_bits; +u64 *override_val; +u64 *override_mask; };extern struct arm64_ftr_reg arm64_ftr_reg_ctrel0;arch/arm64/kernel/cpufeature.c +15
-5@@ -544,13 +544,17 @@ static const struct arm64_ftr_bits ftr_raz[] = { ARM64_FTR_END, }; -#define ARM64_FTR_REG (id, table) { \ - .sys_id = id, \ - .reg = &(struct arm64_ftr_reg){ \ - .name = #id, \ - .ftr_bits = &((table)[0]), \ +#define ARM64_FTR_REG_OVERRIDE (id, table, v, m) { \ + .sys_id = id, \ + .reg = &(struct arm64_ftr_reg){ \ + .name = #id, \ + .ftr_bits = &((table)[0]), \ + .override_val = v, \ + .override_mask = m, \ }} +#define ARM64_FTR_REG (id, table) ARM64_FTR_REG_OVERRIDE(id, table, NULL, NULL) + static const struct __ftr_reg_entry { u32 sys_id; struct arm64_ftr_reg *reg;@@ -760,6 +764,7 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)u64 strict_mask = ~0x0ULL ;u64 user_mask =0 ;u64 valid_mask =0 ; +u64 override_val =0 , override_mask =0 ;const struct arm64_ftr_bits *ftrp;struct arm64_ftr_reg *reg =get_arm64_ftr_reg (sys_reg);@@ -767,9 +772,38 @@ static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new)if (!reg)return ; +if (reg->override_mask && reg->override_val) { + override_mask = *reg->override_mask; + override_val = *reg->override_val; + } +for (ftrp = reg->ftr_bits; ftrp->width; ftrp++) {u64 ftr_mask =arm64_ftr_mask (ftrp);s64 ftr_new =arm64_ftr_value (ftrp, new);
arch/arm64/kernel/cpufeature.c static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new) · line 792
Quoted 10 lines
arch/arm64/kernel/cpufeature.c +10
-0+s64 ftr_ovr =arm64_ftr_value (ftrp, override_val); + +if ((ftr_mask & override_mask) == ftr_mask) { +s64 tmp =arm64_ftr_safe_value (ftrp, ftr_ovr, ftr_new); +char *str =NULL ; + +if (ftr_ovr != tmp) { +/* Unsafe, remove the override */ + *reg->override_mask &= ~ftr_mask; + *reg->override_val &= ~ftr_mask;
Do we need such clearing here? I don't think that's ever called again for this feature/reg.
Quoted 6 lines
arch/arm64/kernel/cpufeature.c +6
-0+ tmp = ftr_ovr; + str ="ignoring override" ; + }else if (ftr_new != tmp) { +/* Override was valid */ + ftr_new = tmp; + str ="forced" ;
arch/arm64/kernel/cpufeature.c static void __init init_cpu_ftr_reg(u32 sys_reg, u64 new) · line 808
Quoted 10 lines
arch/arm64/kernel/cpufeature.c +8
-0+ } + +if (str) +pr_warn ("%s[%d:%d]: %s to %llx\n" , + reg->name, + ftrp->shift + ftrp->width -1 , + ftrp->shift, str, tmp); + } val =arm64_ftr_set_value (ftrp, val, ftr_new);
I wonder whether we could call, after init_cpu_ftr_reg(), a new function similar to update_cpu_ftr_reg() that takes a mask and value and leave init_cpu_ftr_reg() unchanged. The only advantage would be if we can get rid of the reg->override* fields. Anyway, I need to read the rest of the series to see whether it's possible. Otherwise this patch looks fine.
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 09/21] arm64: cpufeature: Add global feature override facility
In reply to Marc ZyngierQuoted 8 lines · Marc Zyngier
Add a facility to globally override a feature, no matter what the HW says. Yes, this sounds dangerous, but we do respect the "safe" value for a given feature. This doesn't mean the user doesn't need to know what they are doing.
Nothing uses this yet, so we are pretty safe. For now.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 10/21 arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()
In reply to Marc Zyngier__read_sysreg_by_encoding() is used by a bunch of cpufeature helpers, which should take the feature override into account. Let's do that.
For a good measure (and because we are likely to need to further down the line), make this helper available to the rest of the non-modular kernel.
Code that needs to know the *real* features of a CPU can still use read_sysreg_s(), and find the bare, ugly truth.
--- arch/arm64/include/asm/cpufeature.h | 1 + arch/arm64/kernel/cpufeature.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-)
arch/arm64/include/asm/cpufeature.h +1 -0
@@ -602,6 +602,7 @@ void __init setup_cpu_features(void);void check_local_cpu_capabilities (void );u64 read_sanitised_ftr_reg (u32 id); +u64 __read_sysreg_by_encoding (u32 sys_id);static inline bool cpu_supports_mixed_endian_el0 (void ) {
arch/arm64/kernel/cpufeature.c +13 -2
@@ -1149,14 +1149,17 @@ u64 read_sanitised_ftr_reg(u32 id)EXPORT_SYMBOL_GPL (read_sanitised_ftr_reg);#define read_sysreg_case (r) \ - case r: return read_sysreg_s(r) + case r: val = read_sysreg_s(r); break;/* * __read_sysreg_by_encoding() - Used by a STARTING cpu before cpuinfo is populated. * Read the system register on the current CPU */ -static u64 __read_sysreg_by_encoding (u32 sys_id) +u64 __read_sysreg_by_encoding (u32 sys_id) { +struct arm64_ftr_reg *regp; +u64 val; +switch (sys_id) {read_sysreg_case (SYS_ID_PFR0_EL1 );read_sysreg_case (SYS_ID_PFR1_EL1 );
@@ -1199,6 +1202,14 @@ static u64 __read_sysreg_by_encoding(u32 sys_id)BUG ();return 0 ; } + + regp =get_arm64_ftr_reg (sys_id); +if (regp && regp->override_mask && regp->override_val) { + val &= ~*regp->override_mask; + val |= (*regp->override_val & *regp->override_mask); + } + +return val; }#include <linux/irqchip/arm-gic-v3.h>
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 10/21] arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()
Quoted 54 lines · Marc Zyngier
__read_sysreg_by_encoding()is used by a bunch of cpufeature helpers, which should take the feature override into account. Let's do that.For a good measure (and because we are likely to need to further down the line), make this helper available to the rest of the non-modular kernel.
Code that needs to know the *real* features of a CPU can still use
read_sysreg_s(), and find the bare, ugly truth.Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/include/asm/cpufeature.h | 1 + arch/arm64/kernel/cpufeature.c | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-)arch/arm64/include/asm/cpufeature.h +1
-0@@ -602,6 +602,7 @@ void __init setup_cpu_features(void);void check_local_cpu_capabilities (void );u64 read_sanitised_ftr_reg (u32 id); +u64 __read_sysreg_by_encoding (u32 sys_id);static inline bool cpu_supports_mixed_endian_el0 (void ) {arch/arm64/kernel/cpufeature.c +5
-2@@ -1149,14 +1149,17 @@ u64 read_sanitised_ftr_reg(u32 id)EXPORT_SYMBOL_GPL (read_sanitised_ftr_reg);#define read_sysreg_case (r) \ - case r: return read_sysreg_s(r) + case r: val = read_sysreg_s(r); break;/* * __read_sysreg_by_encoding() - Used by a STARTING cpu before cpuinfo is populated. * Read the system register on the current CPU */ -static u64 __read_sysreg_by_encoding (u32 sys_id) +u64 __read_sysreg_by_encoding (u32 sys_id) { +struct arm64_ftr_reg *regp; +u64 val; +switch (sys_id) {read_sysreg_case (SYS_ID_PFR0_EL1 );read_sysreg_case (SYS_ID_PFR1_EL1 );@@ -1199,6 +1202,14 @@ static u64 __read_sysreg_by_encoding(u32 sys_id)BUG ();
arch/arm64/kernel/cpufeature.c static u64 __read_sysreg_by_encoding(u32 sys_id) · line 1212
Quoted 10 lines
arch/arm64/kernel/cpufeature.c +8
-0return 0 ; } + + regp =get_arm64_ftr_reg (sys_id); +if (regp && regp->override_mask && regp->override_val) { + val &= ~*regp->override_mask; + val |= (*regp->override_val & *regp->override_mask); + } + +return val;
Ah, now the previous patch makes more sense. I don't particularly like this but I can't tell how to work around it. I was hoping that the overriding feature behaves more like a secondary CPU that limits all the overridden features. However, this approach would fail for FTR_EXACT cases (like PAC, though I wonder whether it fails already with your previous patch since the boot CPU value won't match the override, hence dropping to the safe one).
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 10/21] arm64: cpufeature: Use IDreg override in __read_sysreg_by_encoding()
Quoted 50 lines · Catalin Marinas
Quoted 38 lines · Marc Zyngier
__read_sysreg_by_encoding()is used by a bunch of cpufeature helpers, which should take the feature override into account. Let's do that.For a good measure (and because we are likely to need to further down the line), make this helper available to the rest of the non-modular kernel.
Code that needs to know the *real* features of a CPU can still use
read_sysreg_s(), and find the bare, ugly truth.Signed-off-by Marc Zyngier <[email protected]>arch/arm64/kernel/cpufeature.c +5
-2@@ -1149,14 +1149,17 @@ u64 read_sanitised_ftr_reg(u32 id)EXPORT_SYMBOL_GPL (read_sanitised_ftr_reg);#define read_sysreg_case (r) \ - case r: return read_sysreg_s(r) + case r: val = read_sysreg_s(r); break;/* * __read_sysreg_by_encoding() - Used by a STARTING cpu before cpuinfo is populated. * Read the system register on the current CPU */ -static u64 __read_sysreg_by_encoding (u32 sys_id) +u64 __read_sysreg_by_encoding (u32 sys_id) { +struct arm64_ftr_reg *regp; +u64 val; +switch (sys_id) {read_sysreg_case (SYS_ID_PFR0_EL1 );read_sysreg_case (SYS_ID_PFR1_EL1 );@@ -1199,6 +1202,14 @@ static u64 __read_sysreg_by_encoding(u32 sys_id)BUG ();arch/arm64/kernel/cpufeature.c static u64 __read_sysreg_by_encoding(u32 sys_id) · line 1212
Quoted 10 lines
arch/arm64/kernel/cpufeature.c +8
-0return 0 ; } + + regp =get_arm64_ftr_reg (sys_id); +if (regp && regp->override_mask && regp->override_val) { + val &= ~*regp->override_mask; + val |= (*regp->override_val & *regp->override_mask); + } + +return val;
Quoted 8 lines
Ah, now the previous patch makes more sense. I don't particularly like this but I can't tell how to work around it. I was hoping that the overriding feature behaves more like a secondary CPU that limits all the overridden features. However, this approach would fail for
FTR_EXACTcases (like PAC, though I wonder whether it fails already with your previous patch since the boot CPU value won't match the override, hence dropping to the safe one).
Correct !For FTR_EXACT, we dont want to override a value that is not safe, e.g PAC. This is handled correctly in the previous patch and thus we are covered.
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 11/21 arm64: Extract early FDT mapping from kaslr_early_init()
In reply to Marc ZyngierAs we want to parse more options very early in the kernel lifetime, let's always map the FDT early. This is achieved by moving that code out of kaslr_early_init().
No functionnal change expected.
--- arch/arm64/include/asm/setup.h | 11 +++++++++++ arch/arm64/kernel/head.S | 3 ++- arch/arm64/kernel/kaslr.c | 7 +++---- arch/arm64/kernel/setup.c | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 arch/arm64/include/asm/setup.h
arch/arm64/include/asm/setup.h new file +11 -0
@@ -0,0 +1,11 @@ +// SPDX-License-Identifier: GPL-2.0 + +#ifndef __ARM64_ASM_SETUP_H +#define __ARM64_ASM_SETUP_H + +#include <uapi/asm/setup.h> + +void *get_early_fdt_ptr (void ); +void early_fdt_map (u64 dt_phys); + +#endif
arch/arm64/kernel/head.S +2 -1
@@ -433,6 +433,8 @@ SYM_FUNC_START_LOCAL(__primary_switched) bl __pi_memset dsb ishst // Make zero page visible to PTW + mov x0, x21 // pass FDT address in x0 + bl early_fdt_map // Try mapping the FDT early bl switch_to_vhe #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_init
@@ -440,7 +442,6 @@ SYM_FUNC_START_LOCAL(__primary_switched) #ifdef CONFIG_RANDOMIZE_BASE tst x23, ~(MIN_KIMG_ALIGN - 1) // already running randomized? b.ne 0f - mov x0, x21 // pass FDT address in x0 bl kaslr_early_init // parse FDT for KASLR options cbz x0, 0f // KASLR disabled? just proceed orr x23, x23, x0 // record KASLR offset
arch/arm64/kernel/kaslr.c +3 -4
@@ -19,6 +19,7 @@#include <asm/memory.h> #include <asm/mmu.h> #include <asm/sections.h> +#include <asm/setup.h> enum kaslr_status {KASLR_ENABLED ,
@@ -92,12 +93,11 @@ static __init bool is_kaslr_disabled_cmdline(void *fdt)* containing function pointers) to be reinitialized, and zero-initialized * .bss variables will be reset to 0. */ -u64 __init kaslr_early_init (u64 dt_phys) +u64 __init kaslr_early_init (void ) {void *fdt;u64 seed, offset, mask, module_range;unsigned long raw; -int size;/* * Set a reasonable default for module_alloc_base in case
@@ -111,8 +111,7 @@ u64 __init kaslr_early_init(u64 dt_phys)* and proceed with KASLR disabled. We will make another * attempt at mapping the FDT in setup_machine() */ -early_fixmap_init (); - fdt =fixmap_remap_fdt (dt_phys, &size,PAGE_KERNEL ); + fdt =get_early_fdt_ptr ();if (!fdt) { kaslr_status =KASLR_DISABLED_FDT_REMAP ;return 0 ;
arch/arm64/kernel/setup.c +15 -0
@@ -168,6 +168,21 @@ static void __init smp_build_mpidr_hash(void)pr_warn ("Large number of MPIDR hash buckets detected\n" ); } +static void *early_fdt_ptr__initdata ; + +void __init *get_early_fdt_ptr (void ) +{ +return early_fdt_ptr; +} + +void __init early_fdt_map (u64 dt_phys) +{ +int fdt_size; + +early_fixmap_init (); + early_fdt_ptr =fixmap_remap_fdt (dt_phys, &fdt_size,PAGE_KERNEL ); +} +static void __init setup_machine_fdt (phys_addr_t dt_phys) {int size;
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 11/21] arm64: Extract early FDT mapping from kaslr_early_init()
Quoted 7 lines · Marc Zyngier
As we want to parse more options very early in the kernel lifetime, let's always map the FDT early. This is achieved by moving that code out of
kaslr_early_init().No functionnal change expected.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 11/21] arm64: Extract early FDT mapping from kaslr_early_init()
In reply to Marc Zyngierarch/arm64/kernel/setup.c static void __init smp_build_mpidr_hash(void) · line 184
Quoted 7 lines · Marc Zyngier
arch/arm64/kernel/setup.c +7
-0+void __init early_fdt_map (u64 dt_phys) +{ +int fdt_size; + +early_fixmap_init (); + early_fdt_ptr =fixmap_remap_fdt (dt_phys, &fdt_size,PAGE_KERNEL ); +}
asmlinkage here as well I think.
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 12/21 arm64: cpufeature: Add an early command-line cpufeature override facility
In reply to Marc ZyngierIn order to be able to override CPU features at boot time, let's add a command line parser that matches options of the form "cpureg.feature=value", and store the corresponding value into the override val/mask pair.
No features are currently defined, so no expected change in functionality.
--- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/head.S | 1 + arch/arm64/kernel/idreg-override.c | 119 +++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kernel/idreg-override.c
arch/arm64/kernel/Makefile +1 -1
@@ -17,7 +17,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - syscall.o proton-pack.o + syscall.o proton-pack.o idreg-override.o targets += efi-entry.o
arch/arm64/kernel/head.S +1 -0
@@ -435,6 +435,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) mov x0, x21 // pass FDT address in x0 bl early_fdt_map // Try mapping the FDT early + bl init_shadow_regs bl switch_to_vhe #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_init
arch/arm64/kernel/idreg-override.c new file +119 -0
119 lines not on this page · raw message
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 12/21] arm64: cpufeature: Add an early command-line cpufeature override facility
Quoted 9 lines · Marc Zyngier
In order to be able to override CPU features at boot time, let's add a command line parser that matches options of the form "cpureg.feature=value", and store the corresponding value into the override val/mask pair.
No features are currently defined, so no expected change in functionality.
Signed-off-by Marc Zyngier <[email protected]>
Quoted 49 lines
--- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/head.S | 1 + arch/arm64/kernel/idreg-override.c | 119 +++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/kernel/idreg-override.carch/arm64/kernel/Makefile +1
-1@@ -17,7 +17,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ return_address.o cpuinfo.o cpu_errata.o \ cpufeature.o alternative.o cacheinfo.o \ smp.o smp_spin_table.o topology.o smccc-call.o \ - syscall.o proton-pack.o + syscall.o proton-pack.o idreg-override.o targets += efi-entry.oarch/arm64/kernel/head.S +1
-0@@ -435,6 +435,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) mov x0, x21 // pass FDT address in x0 bl early_fdt_map // Try mapping the FDT early + bl init_shadow_regs bl switch_to_vhe #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_initarch/arm64/kernel/idreg-override.c new file +11
-0@@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* +* Early cpufeature override framework +* +* Copyright (C) 2020 Google LLC +* Author: Marc Zyngier <[email protected]> +*/ + +#include <linux/kernel.h> +#include <linux/libfdt.h> +
arch/arm64/kernel/idreg-override.c line 21
Quoted 10 lines
arch/arm64/kernel/idreg-override.c new file +10
-0+#include <asm/cacheflush.h> +#include <asm/setup.h> + +struct reg_desc { +const char *const name; +u64 *const val; +u64 *const mask; +struct { +const char *const name; +u8 shift;
nit: There's an extra space before shift.
Quoted 101 lines
arch/arm64/kernel/idreg-override.c new file +98
-0+ } fields[]; +}; + +static const struct reg_desc *const regs[]__initdata = { +}; + +static int __init find_field (const char *cmdline,const struct reg_desc *reg, +int f,u64 *v) +{ +char buf[256 ], *str; +size_t len; + +snprintf (buf,ARRAY_SIZE (buf),"%s.%s=" , reg->name, reg->fields[f].name); + + str =strstr (cmdline, buf); +if (!(str == cmdline || (str > cmdline && *(str -1 ) ==' ' ))) +return -1 ; + + str +=strlen (buf); + len =strcspn (str," " ); + len =min (len,ARRAY_SIZE (buf) -1 ); +strncpy (buf, str, len); + buf[len] =0 ; + +return kstrtou64 (buf,0 , v); +} + +static void __init match_options (const char *cmdline) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (regs); i++) { +int f; + +if (!regs[i]->val || !regs[i]->mask) +continue ; + +for (f =0 ; regs[i]->fields[f].name; f++) { +u64 v; + +if (find_field (cmdline, regs[i], f, &v)) +continue ; + + *regs[i]->val |= (v &0xf ) << regs[i]->fields[f].shift; + *regs[i]->mask |=0xfUL << regs[i]->fields[f].shift; + } + } +} + +static __init void parse_cmdline (void ) +{ +if (!IS_ENABLED (CONFIG_CMDLINE_FORCE )) { +const u8 *prop; +void *fdt; +int node; + + fdt =get_early_fdt_ptr (); +if (!fdt) + goto out; + + node =fdt_path_offset (fdt,"/chosen" ); +if (node <0 ) + goto out; + + prop =fdt_getprop (fdt, node,"bootargs" ,NULL ); +if (!prop) + goto out; + +match_options (prop); + +if (!IS_ENABLED (CONFIG_CMDLINE_EXTEND )) +return ; + } + +out: +match_options (CONFIG_CMDLINE ); +} + +void __init init_shadow_regs (void ) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (regs); i++) { +if (regs[i]->val) + *regs[i]->val =0 ; +if (regs[i]->mask) + *regs[i]->mask =0 ; + } + +parse_cmdline (); + +for (i =0 ; i <ARRAY_SIZE (regs); i++) { +if (regs[i]->val) +__flush_dcache_area (regs[i]->val,sizeof (*regs[i]->val)); +if (regs[i]->mask) +__flush_dcache_area (regs[i]->mask,sizeof (*regs[i]->mask)); + } +}Signature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 12/21] arm64: cpufeature: Add an early command-line cpufeature override facility
In reply to Marc ZyngierQuoted 12 lines · Marc Zyngier
arch/arm64/kernel/head.S +1
-0@@ -435,6 +435,7 @@ SYM_FUNC_START_LOCAL(__primary_switched) mov x0, x21 // pass FDT address in x0 bl early_fdt_map // Try mapping the FDT early + bl init_shadow_regs bl switch_to_vhe #if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS) bl kasan_early_init
[...]
Quoted 1 line
+void
__initinit_shadow_regs(void)
Do we need an asmlinkage here? And a declaration somewhere to silence sparse (we did this for entry-common.c function even if the .S files don't consume the prototypes).
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 12/21] arm64: cpufeature: Add an early command-line cpufeature override facility
In reply to Marc Zyngierarch/arm64/kernel/idreg-override.c line 23
Quoted 9 lines · Marc Zyngier
arch/arm64/kernel/idreg-override.c new file +9
-0+struct reg_desc { +const char *const name; +u64 *const val; +u64 *const mask; +struct { +const char *const name; +u8 shift; + } fields[]; +};
Sorry, I didn't see this earlier. Do we need to add all these consts here? So you want the pointers to be const but why is 'shift' special and not a const then? Is it modified later?
Would this not work:
struct reg_desc {
const char *name;
u64 *val;
u64 *mask;
struct {
const char *name;
u8 shift;
} fields[];
};Quoted 1 line
+static const struct
reg_desc* const regs[]__initdata= {
as we already declare the whole struct reg_desc pointers here as const. I may have confused myself...
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerRe: [PATCH v4 12/21] arm64: cpufeature: Add an early command-line cpufeature override facility
Quoted 28 lines · Catalin Marinas
arch/arm64/kernel/idreg-override.c line 23
Quoted 9 lines · Marc Zyngier
arch/arm64/kernel/idreg-override.c new file +9
-0+struct reg_desc { +const char *const name; +u64 *const val; +u64 *const mask; +struct { +const char *const name; +u8 shift; + } fields[]; +};Sorry, I didn't see this earlier. Do we need to add all these consts here? So you want the pointers to be const but why is 'shift' special and not a const then? Is it modified later?
Would this not work:
struct reg_desc { const char *name; u64 *val; u64 *mask; struct { const char *name; u8 shift; } fields[]; };
Quoted 4 lines
Quoted 1 line
+static const struct
reg_desc* const regs[]__initdata= {as we already declare the whole struct
reg_descpointers here as const. I may have confused myself...
It definitely is better. Specially given that we throw all of this away right after boot, there is no harm in keeping it simple.
I've also renamed "reg_desc" to "ftr_set_desc", because we don't always describe a register (like for kaslr).
Thanks,
M.
Signature · 5 lines
Without deviation from the norm, progress is not possible. _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 13/21 arm64: Allow ID_AA64MMFR1_EL1.VH to be overridden from the command line
In reply to Marc ZyngierAs we want to be able to disable VHE at runtime, let's match "id_aa64mmfr1.vh=" from the command line as an override. This doesn't have much effect yet as our boot code doesn't look at the cpufeature, but only at the HW registers.
--- arch/arm64/include/asm/cpufeature.h | 3 +++ arch/arm64/kernel/cpufeature.c | 6 +++++- arch/arm64/kernel/idreg-override.c | 12 ++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-)
arch/arm64/include/asm/cpufeature.h +3 -0
@@ -814,6 +814,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)return 8 ; } +extern u64 id_aa64mmfr1_val; +extern u64 id_aa64mmfr1_mask; +u32 get_kvm_ipa_limit (void );void dump_cpu_features (void );
arch/arm64/kernel/cpufeature.c +5 -1
@@ -555,6 +555,9 @@ static const struct arm64_ftr_bits ftr_raz[] = {#define ARM64_FTR_REG (id, table) ARM64_FTR_REG_OVERRIDE(id, table, NULL, NULL) +u64 id_aa64mmfr1_val; +u64 id_aa64mmfr1_mask; + static const struct __ftr_reg_entry { u32 sys_id; struct arm64_ftr_reg *reg;
@@ -602,7 +605,8 @@ static const struct __ftr_reg_entry {/* Op1 = 0, CRn = 0, CRm = 7 */ ARM64_FTR_REG (SYS_ID_AA64MMFR0_EL1 , ftr_id_aa64mmfr0), -ARM64_FTR_REG (SYS_ID_AA64MMFR1_EL1 , ftr_id_aa64mmfr1), +ARM64_FTR_REG_OVERRIDE (SYS_ID_AA64MMFR1_EL1 , ftr_id_aa64mmfr1, + &id_aa64mmfr1_val, &id_aa64mmfr1_mask), ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),/* Op1 = 0, CRn = 1, CRm = 2 */
arch/arm64/kernel/idreg-override.c +12 -0
@@ -10,6 +10,7 @@#include <linux/libfdt.h> #include <asm/cacheflush.h> +#include <asm/cpufeature.h> #include <asm/setup.h> struct reg_desc {
@@ -22,7 +23,18 @@ struct reg_desc { } fields[]; }; +static const struct reg_desc mmfr1__initdata = { + .name ="id_aa64mmfr1" , + .val = &id_aa64mmfr1_val, + .mask = &id_aa64mmfr1_mask, + .fields = { + {"vh" ,ID_AA64MMFR1_VHE_SHIFT }, + {} + }, +}; +static const struct reg_desc *const regs[]__initdata = { + &mmfr1, }; static int __init find_field(const char *cmdline, const struct reg_desc *reg,
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 13/21] arm64: Allow ID_AA64MMFR1_EL1.VH to be overridden from the command line
Quoted 57 lines · Marc Zyngier
arch/arm64/include/asm/cpufeature.h +3
-0@@ -814,6 +814,9 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)return 8 ; } +extern u64 id_aa64mmfr1_val; +extern u64 id_aa64mmfr1_mask; +u32 get_kvm_ipa_limit (void );void dump_cpu_features (void );arch/arm64/kernel/cpufeature.c +5
-1@@ -555,6 +555,9 @@ static const struct arm64_ftr_bits ftr_raz[] = {#define ARM64_FTR_REG (id, table) ARM64_FTR_REG_OVERRIDE(id, table, NULL, NULL) +u64 id_aa64mmfr1_val; +u64 id_aa64mmfr1_mask; + static const struct __ftr_reg_entry { u32 sys_id; struct arm64_ftr_reg *reg;@@ -602,7 +605,8 @@ static const struct __ftr_reg_entry {/* Op1 = 0, CRn = 0, CRm = 7 */ ARM64_FTR_REG (SYS_ID_AA64MMFR0_EL1 , ftr_id_aa64mmfr0), -ARM64_FTR_REG (SYS_ID_AA64MMFR1_EL1 , ftr_id_aa64mmfr1), +ARM64_FTR_REG_OVERRIDE (SYS_ID_AA64MMFR1_EL1 , ftr_id_aa64mmfr1, + &id_aa64mmfr1_val, &id_aa64mmfr1_mask), ARM64_FTR_REG(SYS_ID_AA64MMFR2_EL1, ftr_id_aa64mmfr2),/* Op1 = 0, CRn = 1, CRm = 2 */ arch/arm64/kernel/idreg-override.c +4
-0@@ -10,6 +10,7 @@#include <linux/libfdt.h> #include <asm/cacheflush.h> +#include <asm/cpufeature.h> #include <asm/setup.h> struct reg_desc {@@ -22,7 +23,18 @@ struct reg_desc { } fields[]; }; +static const struct reg_desc mmfr1__initdata = { + .name ="id_aa64mmfr1" , + .val = &id_aa64mmfr1_val,
arch/arm64/kernel/idreg-override.c struct reg_desc { · line 38
Quoted 10 lines
arch/arm64/kernel/idreg-override.c +8
-0+ .mask = &id_aa64mmfr1_mask, + .fields = { + { "vh", ID_AA64MMFR1_VHE_SHIFT }, + {} + }, +}; + static const struct reg_desc * const regs[] __initdata = { + &mmfr1, };
I'm ok in principle with how all these link together. I wonder however if we could skip the separate u64 variables and just have a struct reg_override with val and mask u64 rather than pointers. The ARM64_FTR_REG_OVERRIDE macro takes a pointer to this new struct reg_override and can access val/mask directly. Some 'const' may need to be dropped.
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 14/21 arm64: Honor VHE being disabled from the command-line
In reply to Marc ZyngierFinally we can check whether VHE is disabled on the command line, and not enable it if that's the user's wish.
--- arch/arm64/kernel/hyp-stub.S | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)
arch/arm64/kernel/hyp-stub.S +14 -3
@@ -77,13 +77,24 @@ SYM_CODE_END(el1_sync) SYM_CODE_START_LOCAL(mutate_to_vhe) // Sanity check: MMU *must* be off mrs x0, sctlr_el2 - tbnz x0, #0, 1f + tbnz x0, #0, 2f // Needs to be VHE capable, obviously mrs x0, id_aa64mmfr1_el1 ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 - cbz x0, 1f + cbz x0, 2f + // Check whether VHE is disabled from the command line + adr_l x1, id_aa64mmfr1_val + ldr x0, [x1] + adr_l x1, id_aa64mmfr1_mask + ldr x1, [x1] + ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x1, 1f + and x0, x0, x1 + cbz x0, 2f +1: // Engage the VHE magic! mov_q x0, HCR_HOST_VHE_FLAGS msr hcr_el2, x0
@@ -152,7 +163,7 @@ skip_spe: orr x0, x0, x1 msr spsr_el1, x0 -1: eret +2: eret SYM_CODE_END(mutate_to_vhe) .macro invalid_vector label
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 14/21] arm64: Honor VHE being disabled from the command-line
Quoted 4 lines · Marc Zyngier
Finally we can check whether VHE is disabled on the command line, and not enable it if that's the user's wish.
Signed-off-by Marc Zyngier <[email protected]>
Quoted 16 lines
--- arch/arm64/kernel/hyp-stub.S | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-)arch/arm64/kernel/hyp-stub.S +1
-1@@ -77,13 +77,24 @@ SYM_CODE_END(el1_sync) SYM_CODE_START_LOCAL(mutate_to_vhe) // Sanity check: MMU *must* be off mrs x0, sctlr_el2 - tbnz x0, #0, 1f + tbnz x0, #0, 2f // Needs to be VHE capable, obviously
arch/arm64/kernel/hyp-stub.S SYM_CODE_END(el1_sync) · line 91
Quoted 10 lines
arch/arm64/kernel/hyp-stub.S +6
-1mrs x0, id_aa64mmfr1_el1 ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 - cbz x0, 1f + cbz x0, 2f + // Check whether VHE is disabled from the command line + adr_l x1, id_aa64mmfr1_val + ldr x0, [x1] + adr_l x1, id_aa64mmfr1_mask + ldr x1, [x1]
super nit: There's a ldr_l macro
Quoted 21 lines
arch/arm64/kernel/hyp-stub.S +7
-1+ ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x1, 1f + and x0, x0, x1 + cbz x0, 2f +1: // Engage the VHE magic! mov_q x0, HCR_HOST_VHE_FLAGS msr hcr_el2, x0@@ -152,7 +163,7 @@ skip_spe: orr x0, x0, x1 msr spsr_el1, x0 -1: eret +2: eret SYM_CODE_END(mutate_to_vhe) .macro invalid_vector labelSignature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Catalin Marinas
maintainerRe: [PATCH v4 14/21] arm64: Honor VHE being disabled from the command-line
In reply to Marc ZyngierQuoted 18 lines · Marc Zyngier
arch/arm64/kernel/hyp-stub.S +3
-2@@ -77,13 +77,24 @@ SYM_CODE_END(el1_sync) SYM_CODE_START_LOCAL(mutate_to_vhe) // Sanity check: MMU *must* be off mrs x0, sctlr_el2 - tbnz x0, #0, 1f + tbnz x0, #0, 2f // Needs to be VHE capable, obviously mrs x0, id_aa64mmfr1_el1 ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 - cbz x0, 1f + cbz x0, 2f + // Check whether VHE is disabled from the command line
arch/arm64/kernel/hyp-stub.S SYM_CODE_END(el1_sync) · line 97
Quoted 10 lines
arch/arm64/kernel/hyp-stub.S +10
-0+ adr_l x1, id_aa64mmfr1_val + ldr x0, [x1] + adr_l x1, id_aa64mmfr1_mask + ldr x1, [x1] + ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x1, 1f + and x0, x0, x1 + cbz x0, 2f +1:
I can see the advantage here in separate id_aa64mmfr1_val/mask but we could use some asm offsets here and keep the pointer indirection simpler in C code. You'd just need something like 'adr_l mmfr1_ovrd + VAL_OFFSET'.
Anyway, if you have a strong preference for the current approach, leave it as is.
Signature · 5 lines
Catalin _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerRe: [PATCH v4 14/21] arm64: Honor VHE being disabled from the command-line
Quoted 35 lines · Catalin Marinas
Quoted 18 lines · Marc Zyngier
arch/arm64/kernel/hyp-stub.S +3
-2@@ -77,13 +77,24 @@ SYM_CODE_END(el1_sync) SYM_CODE_START_LOCAL(mutate_to_vhe) // Sanity check: MMU *must* be off mrs x0, sctlr_el2 - tbnz x0, #0, 1f + tbnz x0, #0, 2f // Needs to be VHE capable, obviously mrs x0, id_aa64mmfr1_el1 ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 - cbz x0, 1f + cbz x0, 2f + // Check whether VHE is disabled from the command linearch/arm64/kernel/hyp-stub.S SYM_CODE_END(el1_sync) · line 97
Quoted 10 lines
arch/arm64/kernel/hyp-stub.S +10
-0+ adr_l x1, id_aa64mmfr1_val + ldr x0, [x1] + adr_l x1, id_aa64mmfr1_mask + ldr x1, [x1] + ubfx x0, x0, #ID_AA64MMFR1_VHE_SHIFT, #4 + ubfx x1, x1, #ID_AA64MMFR1_VHE_SHIFT, #4 + cbz x1, 1f + and x0, x0, x1 + cbz x0, 2f +1:I can see the advantage here in separate id_aa64mmfr1_val/mask but we could use some asm offsets here and keep the pointer indirection simpler in C code. You'd just need something like '
adr_lmmfr1_ovrd+VAL_OFFSET'.
Quoted 2 lines
Anyway, if you have a strong preference for the current approach, leave it as is.
I've now moved over to a structure containing both val/mask, meaning that we only need to keep a single pointer around in the various feature descriptors. It certainly looks better.
Thanks,
M.
Signature · 5 lines
Without deviation from the norm, progress is not possible. _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 15/21 arm64: Add an aliasing facility for the idreg override
In reply to Marc ZyngierIn order to map the override of idregs to options that a user can easily understand, let's introduce yet another option array, which maps an option to the corresponding idreg options.
--- arch/arm64/kernel/idreg-override.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)
arch/arm64/kernel/idreg-override.c +20 -0
@@ -37,6 +37,12 @@ static const struct reg_desc * const regs[] __initdata = { &mmfr1, }; +static const struct { +const char *const alias; +const char *const feature; +} aliases[]__initdata = { +}; +static int __init find_field (const char *cmdline,const struct reg_desc *reg,int f,u64 *v) {
@@ -80,6 +86,18 @@ static void __init match_options(const char *cmdline) } } +static __init void match_aliases (const char *cmdline) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (aliases); i++) { +char *str =strstr (cmdline, aliases[i].alias); + +if ((str == cmdline || (str > cmdline && *(str -1 ) ==' ' ))) +match_options (aliases[i].feature); + } +} +static __init void parse_cmdline (void ) {if (!IS_ENABLED (CONFIG_CMDLINE_FORCE )) {
@@ -100,6 +118,7 @@ static __init void parse_cmdline(void) goto out;match_options (prop); +match_aliases (prop);if (!IS_ENABLED (CONFIG_CMDLINE_EXTEND ))return ;
@@ -107,6 +126,7 @@ static __init void parse_cmdline(void) out:match_options (CONFIG_CMDLINE ); +match_aliases (CONFIG_CMDLINE ); }void __init init_shadow_regs (void )
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 15/21] arm64: Add an aliasing facility for the idreg override
Quoted 5 lines · Marc Zyngier
In order to map the override of idregs to options that a user can easily understand, let's introduce yet another option array, which maps an option to the corresponding idreg options.
Signed-off-by Marc Zyngier <[email protected]>
Quoted 23 lines
--- arch/arm64/kernel/idreg-override.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)arch/arm64/kernel/idreg-override.c +6
-0@@ -37,6 +37,12 @@ static const struct reg_desc * const regs[] __initdata = { &mmfr1, }; +static const struct { +const char *const alias; +const char *const feature; +} aliases[]__initdata = { +}; +static int __init find_field (const char *cmdline,const struct reg_desc *reg,int f,u64 *v) {@@ -80,6 +86,18 @@ static void __init match_options(const char *cmdline) }
arch/arm64/kernel/idreg-override.c static void __init match_options(const char *cmdline) · line 96
Quoted 10 lines
arch/arm64/kernel/idreg-override.c +8
-0} +static __init void match_aliases (const char *cmdline) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (aliases); i++) { +char *str =strstr (cmdline, aliases[i].alias); + +if ((str == cmdline || (str > cmdline && *(str -1 ) ==' ' )))
nit: Extract to a 'cmdline_contains' helper? Took me a good few seconds to parse this in the previous patch. Giving it a name would help, and now it's also shared.
Quoted 26 lines
arch/arm64/kernel/idreg-override.c +6
-0+match_options (aliases[i].feature); + } +} +static __init void parse_cmdline (void ) {if (!IS_ENABLED (CONFIG_CMDLINE_FORCE )) {@@ -100,6 +118,7 @@ static __init void parse_cmdline(void) goto out;match_options (prop); +match_aliases (prop);if (!IS_ENABLED (CONFIG_CMDLINE_EXTEND ))return ;@@ -107,6 +126,7 @@ static __init void parse_cmdline(void) out:match_options (CONFIG_CMDLINE ); +match_aliases (CONFIG_CMDLINE ); }void __init init_shadow_regs (void )Signature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerRe: [PATCH v4 15/21] arm64: Add an aliasing facility for the idreg override
Quoted 34 lines · David Brazdil
Quoted 5 lines · Marc Zyngier
In order to map the override of idregs to options that a user can easily understand, let's introduce yet another option array, which maps an option to the corresponding idreg options.
Signed-off-by Marc Zyngier <[email protected]>Acked-by David Brazdil <[email protected]>Quoted 25 lines
--- arch/arm64/kernel/idreg-override.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+)arch/arm64/kernel/idreg-override.c +6
-0@@ -37,6 +37,12 @@ static const struct reg_desc * const regs[] __initdata = { &mmfr1, }; +static const struct { +const char *const alias; +const char *const feature; +} aliases[]__initdata = { +}; +static int __init find_field (const char *cmdline,const struct reg_desc *reg,int f,u64 *v) {@@ -80,6 +86,18 @@ static void __init match_options(const char *cmdline) } }
Quoted 12 lines
arch/arm64/kernel/idreg-override.c static void __init match_options(const char *cmdline) · line 96
Quoted 8 lines
arch/arm64/kernel/idreg-override.c +8
-0+static __init void match_aliases (const char *cmdline) +{ +int i; + +for (i =0 ; i <ARRAY_SIZE (aliases); i++) { +char *str =strstr (cmdline, aliases[i].alias); + +if ((str == cmdline || (str > cmdline && *(str -1 ) ==' ' )))nit: Extract to a '
cmdline_contains' helper? Took me a good few seconds to parse this in the previous patch. Giving it a name would help, and now it's also shared.
Good point. Adopted!
Thanks,
M.
Signature · 5 lines
Without deviation from the norm, progress is not possible. _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 15/21] arm64: Add an aliasing facility for the idreg override
In reply to Marc Zyngierarch/arm64/kernel/idreg-override.c static const struct reg_desc * const regs[] __initdata = { · line 44
Quoted 13 lines · Marc Zyngier
arch/arm64/kernel/idreg-override.c +5
-0@@ -37,6 +37,12 @@ static const struct reg_desc * const regs[] __initdata = { &mmfr1, }; +static const struct { +const char *const alias; +const char *const feature; +} aliases[]__initdata = { +};
As before, do we need the second 'const' for alias and feature? The aliases array is already a const.
Otherwise,
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 16/21 arm64: Make kvm-arm.mode={nvhe,protected} an alias of id_aa64mmfr1.vh=0
In reply to Marc ZyngierAdmitedly, passing id_aa64mmfr1.vh=0 on the command-line isn't that easy to understand, and it is likely that users would much prefer write "kvm-arm.mode=nvhe", or "...=protected".
So here you go. This has the added advantage that we can now always honor the "kvm-arm.mode=protected" option, even when booting on a VHE system.
--- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/kernel/idreg-override.c | 2 ++ arch/arm64/kvm/arm.c | 3 +++ 3 files changed, 8 insertions(+)
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -2257,6 +2257,9 @@ kvm-arm.mode= [KVM,ARM] Select one of KVM/arm64's modes of operation. + nvhe: Standard nVHE-based mode, without support for + protected guests. + protected: nVHE-based mode with support for guests whose state is kept private from the host. Not valid if the kernel is running in EL2.
arch/arm64/kernel/idreg-override.c +2 -0
@@ -41,6 +41,8 @@ static const struct {const char *const alias;const char *const feature; } aliases[] __initdata = { + { "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" }, + { "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" }, }; static int __init find_field(const char *cmdline, const struct reg_desc *reg,
arch/arm64/kvm/arm.c +3 -0
@@ -1966,6 +1966,9 @@ static int __init early_kvm_mode_cfg(char *arg)return 0 ; } +if (strcmp (arg,"nvhe" ) ==0 && !WARN_ON (is_kernel_in_hyp_mode ())) +return 0 ; +return -EINVAL ; }early_param ("kvm-arm.mode" , early_kvm_mode_cfg);
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 16/21] arm64: Make kvm-arm.mode={nvhe,protected} an alias of id_aa64mmfr1.vh=0
Quoted 9 lines · Marc Zyngier
Admitedly, passing id_aa64mmfr1.vh=0 on the command-line isn't that easy to understand, and it is likely that users would much prefer write "kvm-arm.mode=nvhe", or "...=protected".
So here you go. This has the added advantage that we can now always honor the "kvm-arm.mode=protected" option, even when booting on a VHE system.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 17/21 KVM: arm64: Document HVC_VHE_RESTART stub hypercall
In reply to Marc ZyngierFor completeness, let's document the HVC_VHE_RESTART stub.
--- Documentation/virt/kvm/arm/hyp-abi.rst | 9 +++++++++ 1 file changed, 9 insertions(+)
Documentation/virt/kvm/arm/hyp-abi.rst +9 -0
@@ -58,6 +58,15 @@ these functions (see arch/arm{,64}/include/asm/virt.h): into place (arm64 only), and jump to the restart address while at HYP/EL2. This hypercall is not expected to return to its caller. +* :: + + x0 = HVC_VHE_RESTART (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 mean (comment line option, + for example). + Any other value of r0/x0 triggers a hypervisor-specific handling, which is not documented here.
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 17/21] KVM: arm64: Document HVC_VHE_RESTART stub hypercall
Quoted 3 lines · Marc Zyngier
For completeness, let's document the
HVC_VHE_RESTARTstub.Signed-off-by Marc Zyngier <[email protected]>
Quoted 9 lines
--- Documentation/virt/kvm/arm/hyp-abi.rst | 9 +++++++++ 1 file changed, 9 insertions(+)Documentation/virt/kvm/arm/hyp-abi.rst +0
-0
Documentation/virt/kvm/arm/hyp-abi.rst these functions (see arch/arm{,64}/include/asm/virt.h): · line 67
Quoted 10 lines
Documentation/virt/kvm/arm/hyp-abi.rst +7
-0@@ -58,6 +58,15 @@ these functions (see arch/arm{,64}/include/asm/virt.h): into place (arm64 only), and jump to the restart address while at HYP/EL2. This hypercall is not expected to return to its caller. +* :: + + x0 = HVC_VHE_RESTART (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 mean (comment line option,
'means' (both singular and plural), and 'command line'
Quoted 8 lines
Documentation/virt/kvm/arm/hyp-abi.rst +2
-0+ for example). + Any other value of r0/x0 triggers a hypervisor-specific handling, which is not documented here.Signature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 18/21 arm64: Move "nokaslr" over to the early cpufeature infrastructure
In reply to Marc ZyngierGiven that the early cpufeature infrastructure has borrowed quite a lot of code from the kaslr implementation, let's reimplement the matching of the "nokaslr" option with it.
--- arch/arm64/kernel/idreg-override.c | 17 ++++++++++++++ arch/arm64/kernel/kaslr.c | 37 +++--------------------------- 2 files changed, 20 insertions(+), 34 deletions(-)
arch/arm64/kernel/idreg-override.c +17 -0
@@ -33,8 +33,24 @@ static const struct reg_desc mmfr1 __initdata = { }, }; +extern u64 kaslr_feature_val; +extern u64 kaslr_feature_mask; + +static const struct reg_desc kaslr__initdata = { + .name ="kaslr" , +#ifdef CONFIG_RANDOMIZE_BASE + .val = &kaslr_feature_val, + .mask = &kaslr_feature_mask, +#endif + .fields = { + {"disabled" ,0 }, + {} + }, +}; +static const struct reg_desc *const regs[]__initdata = { &mmfr1, + &kaslr, }; static const struct {
@@ -43,6 +59,7 @@ static const struct { } aliases[] __initdata = { { "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" }, { "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" }, + { "nokaslr", "kaslr.disabled=1" }, }; static int __init find_field(const char *cmdline, const struct reg_desc *reg,
arch/arm64/kernel/kaslr.c +3 -34
@@ -51,39 +51,8 @@ static __init u64 get_kaslr_seed(void *fdt)return ret; } -static __init bool cmdline_contains_nokaslr (const u8 *cmdline) -{ -const u8 *str; - - str =strstr (cmdline,"nokaslr" ); -return str == cmdline || (str > cmdline && *(str -1 ) ==' ' ); -} - -static __init bool is_kaslr_disabled_cmdline (void *fdt) -{ -if (!IS_ENABLED (CONFIG_CMDLINE_FORCE )) { -int node; -const u8 *prop; - - node =fdt_path_offset (fdt,"/chosen" ); -if (node <0 ) - goto out; - - prop =fdt_getprop (fdt, node,"bootargs" ,NULL ); -if (!prop) - goto out; - -if (cmdline_contains_nokaslr (prop)) -return true; - -if (IS_ENABLED (CONFIG_CMDLINE_EXTEND )) - goto out; - -return false; - } -out: -return cmdline_contains_nokaslr (CONFIG_CMDLINE ); -} +u64 kaslr_feature_val__initdata ; +u64 kaslr_feature_mask__initdata ;/* * This routine will be executed with the kernel mapped at its default virtual
@@ -126,7 +95,7 @@ u64 __init kaslr_early_init(void)* Check if 'nokaslr' appears on the command line, and * return 0 if that is the case. */ -if (is_kaslr_disabled_cmdline (fdt)) { +if (kaslr_feature_val & kaslr_feature_mask &0xf ) { kaslr_status =KASLR_DISABLED_CMDLINE ;return 0 ; }
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 18/21] arm64: Move "nokaslr" over to the early cpufeature infrastructure
Quoted 5 lines · Marc Zyngier
Given that the early cpufeature infrastructure has borrowed quite a lot of code from the kaslr implementation, let's reimplement the matching of the "nokaslr" option with it.
Signed-off-by Marc Zyngier <[email protected]>
Quoted 89 lines
--- arch/arm64/kernel/idreg-override.c | 17 ++++++++++++++ arch/arm64/kernel/kaslr.c | 37 +++--------------------------- 2 files changed, 20 insertions(+), 34 deletions(-)arch/arm64/kernel/idreg-override.c +17
-0@@ -33,8 +33,24 @@ static const struct reg_desc mmfr1 __initdata = { }, }; +extern u64 kaslr_feature_val; +extern u64 kaslr_feature_mask; + +static const struct reg_desc kaslr__initdata = { + .name ="kaslr" , +#ifdef CONFIG_RANDOMIZE_BASE + .val = &kaslr_feature_val, + .mask = &kaslr_feature_mask, +#endif + .fields = { + {"disabled" ,0 }, + {} + }, +}; +static const struct reg_desc *const regs[]__initdata = { &mmfr1, + &kaslr, }; static const struct {@@ -43,6 +59,7 @@ static const struct { } aliases[] __initdata = { { "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" }, { "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" }, + { "nokaslr", "kaslr.disabled=1" }, }; static int __init find_field(const char *cmdline, const struct reg_desc *reg,arch/arm64/kernel/kaslr.c +2
-33@@ -51,39 +51,8 @@ static __init u64 get_kaslr_seed(void *fdt)return ret; } -static __init bool cmdline_contains_nokaslr (const u8 *cmdline) -{ -const u8 *str; - - str =strstr (cmdline,"nokaslr" ); -return str == cmdline || (str > cmdline && *(str -1 ) ==' ' ); -} - -static __init bool is_kaslr_disabled_cmdline (void *fdt) -{ -if (!IS_ENABLED (CONFIG_CMDLINE_FORCE )) { -int node; -const u8 *prop; - - node =fdt_path_offset (fdt,"/chosen" ); -if (node <0 ) - goto out; - - prop =fdt_getprop (fdt, node,"bootargs" ,NULL ); -if (!prop) - goto out; - -if (cmdline_contains_nokaslr (prop)) -return true; - -if (IS_ENABLED (CONFIG_CMDLINE_EXTEND )) - goto out; - -return false; - } -out: -return cmdline_contains_nokaslr (CONFIG_CMDLINE ); -} +u64 kaslr_feature_val__initdata ; +u64 kaslr_feature_mask__initdata ;/* * This routine will be executed with the kernel mapped at its default virtual
arch/arm64/kernel/kaslr.c u64 __init kaslr_early_init(void) · line 98
Quoted 5 lines
arch/arm64/kernel/kaslr.c +1
-1@@ -126,7 +95,7 @@ u64 __init kaslr_early_init(void)* Check if 'nokaslr' appears on the command line, and * return 0 if that is the case. */ -if (is_kaslr_disabled_cmdline (fdt)) { +if (kaslr_feature_val & kaslr_feature_mask &0xf ) {
nit: Isn't the 0xf redundant here? You don't re-mask for VH either.
Quoted 6 lines
arch/arm64/kernel/kaslr.c +0
-0kaslr_status =KASLR_DISABLED_CMDLINE ;return 0 ; }Signature · 1 line
2.29.2
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerRe: [PATCH v4 18/21] arm64: Move "nokaslr" over to the early cpufeature infrastructure
Quoted 8 lines · David Brazdil
Quoted 5 lines · Marc Zyngier
Given that the early cpufeature infrastructure has borrowed quite a lot of code from the kaslr implementation, let's reimplement the matching of the "nokaslr" option with it.
Signed-off-by Marc Zyngier <[email protected]>Acked-by David Brazdil <[email protected]>
[...]
Quoted 8 lines
arch/arm64/kernel/kaslr.c u64 __init kaslr_early_init(void) · line 98
Quoted 6 lines
arch/arm64/kernel/kaslr.c +1
-1@@ -126,7 +95,7 @@ u64 __init kaslr_early_init(void)* Check if 'nokaslr' appears on the command line, and * return 0 if that is the case. */ -if (is_kaslr_disabled_cmdline (fdt)) { +if (kaslr_feature_val & kaslr_feature_mask &0xf ) {nit: Isn't the
0xfredundant here? You don't re-mask for VH either.
Actually, I do. See the two back to back ubfx that extract both the mask and the feature. The "& 0xf" here serves the same purpose.
Is it redundant? At the moment, quite possibly. But since we have space for 16 "features", this is an indication that we are only using the first one. I expect that eventually, we'll use it for other things.
Thanks,
M.
Signature · 5 lines
Without deviation from the norm, progress is not possible. _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 18/21] arm64: Move "nokaslr" over to the early cpufeature infrastructure
In reply to Marc ZyngierQuoted 15 lines · Marc Zyngier
Given that the early cpufeature infrastructure has borrowed quite a lot of code from the kaslr implementation, let's reimplement the matching of the "nokaslr" option with it.
Signed-off-by Marc Zyngier <[email protected]>--- arch/arm64/kernel/idreg-override.c | 17 ++++++++++++++ arch/arm64/kernel/kaslr.c | 37 +++--------------------------- 2 files changed, 20 insertions(+), 34 deletions(-)arch/arm64/kernel/idreg-override.c +0
-0
arch/arm64/kernel/idreg-override.c static const struct reg_desc mmfr1 __initdata = { · line 40
Quoted 8 lines
arch/arm64/kernel/idreg-override.c +5
-0@@ -33,8 +33,24 @@ static const struct reg_desc mmfr1 __initdata = { }, }; +extern u64 kaslr_feature_val; +extern u64 kaslr_feature_mask; + +static const struct reg_desc kaslr__initdata = { + .name ="kaslr" ,
We might as well rename this ftr_override or something more generic as we no longer describe registers here. Otherwise:
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 19/21 arm64: cpufeatures: Allow disabling of BTI from the command-line
In reply to Marc ZyngierIn order to be able to disable BTI at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64PFR1_EL1.BTI field.
This is further mapped on the arm64.nobti command-line alias.
--- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/include/asm/cpufeature.h | 2 ++ arch/arm64/kernel/cpufeature.c | 5 ++++- arch/arm64/kernel/idreg-override.c | 12 ++++++++++++ arch/arm64/mm/mmu.c | 2 +- 5 files changed, 22 insertions(+), 2 deletions(-)
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -373,6 +373,9 @@ arcrimi= [HW,NET] ARCnet - "RIM I" (entirely mem-mapped) cards Format: <io>,<irq>,<nodeID> + arm64.nobti [ARM64] Unconditionally disable Branch Target + Identification support + ataflop= [HW,M68k] atarimouse= [HW,MOUSE] Atari Mouse
arch/arm64/include/asm/cpufeature.h +2 -0
@@ -816,6 +816,8 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)extern u64 id_aa64mmfr1_val;extern u64 id_aa64mmfr1_mask; +extern u64 id_aa64pfr1_val; +extern u64 id_aa64pfr1_mask;u32 get_kvm_ipa_limit (void );void dump_cpu_features (void );
arch/arm64/kernel/cpufeature.c +4 -1
@@ -557,6 +557,8 @@ static const struct arm64_ftr_bits ftr_raz[] = {u64 id_aa64mmfr1_val;u64 id_aa64mmfr1_mask; +u64 id_aa64pfr1_val; +u64 id_aa64pfr1_mask; static const struct __ftr_reg_entry { u32 sys_id;
@@ -592,7 +594,8 @@ static const struct __ftr_reg_entry {/* Op1 = 0, CRn = 0, CRm = 4 */ ARM64_FTR_REG (SYS_ID_AA64PFR0_EL1 , ftr_id_aa64pfr0), -ARM64_FTR_REG (SYS_ID_AA64PFR1_EL1 , ftr_id_aa64pfr1), +ARM64_FTR_REG_OVERRIDE (SYS_ID_AA64PFR1_EL1 , ftr_id_aa64pfr1, + &id_aa64pfr1_val, &id_aa64pfr1_mask), ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),/* Op1 = 0, CRn = 0, CRm = 5 */
arch/arm64/kernel/idreg-override.c +12 -0
@@ -33,6 +33,16 @@ static const struct reg_desc mmfr1 __initdata = { }, }; +static const struct reg_desc pfr1__initdata = { + .name ="id_aa64pfr1" , + .val = &id_aa64pfr1_val, + .mask = &id_aa64pfr1_mask, + .fields = { + {"bt" ,ID_AA64PFR1_BT_SHIFT }, + {} + }, +}; +extern u64 kaslr_feature_val;extern u64 kaslr_feature_mask;
@@ -50,6 +60,7 @@ static const struct reg_desc kaslr __initdata = {static const struct reg_desc *const regs[]__initdata = { &mmfr1, + &pfr1, &kaslr, };
@@ -59,6 +70,7 @@ static const struct { } aliases[] __initdata = { { "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" }, { "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" }, + { "arm64.nobti", "id_aa64pfr1.bt=0" }, { "nokaslr", "kaslr.disabled=1" }, };
arch/arm64/mm/mmu.c +1 -1
@@ -628,7 +628,7 @@ static bool arm64_early_this_cpu_has_bti(void)if (!IS_ENABLED (CONFIG_ARM64_BTI_KERNEL ))return false; - pfr1 =read_sysreg_s (SYS_ID_AA64PFR1_EL1 ); + pfr1 =__read_sysreg_by_encoding (SYS_ID_AA64PFR1_EL1 );return cpuid_feature_extract_unsigned_field (pfr1,ID_AA64PFR1_BT_SHIFT ); }
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 19/21] arm64: cpufeatures: Allow disabling of BTI from the command-line
Quoted 7 lines · Marc Zyngier
In order to be able to disable BTI at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64PFR1_EL1.BTI field.
This is further mapped on the arm64.nobti command-line alias.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Srinivas Ramana
Tested-byRe: [PATCH v4 19/21] arm64: cpufeatures: Allow disabling of BTI from the command-line
Hi Marc,
Quoted 9 lines · Catalin Marinas
Quoted 7 lines · Marc Zyngier
In order to be able to disable BTI at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64PFR1_EL1.BTI field.
This is further mapped on the arm64.nobti command-line alias.
Signed-off-by Marc Zyngier <[email protected]>Reviewed-by Catalin Marinas <[email protected]>
Verified this Series for BTI as well for command line control.
With arm64.nobti:
BTI is disabled on both primary and secondary cores as expected(verified page table entries). HWCAPs show no BTI support and kernel instructions are being treated as NOPs. We don't have plan to repeat the test on v5 as there are not major changes here.
Marc Zyngier
maintainerPATCH v4 20/21 arm64: Defer enabling pointer authentication on boot core
In reply to Marc ZyngierFrom: Srinivas Ramana <[email protected]>
Defer enabling pointer authentication on boot core until after its required to be enabled by cpufeature framework. This will help in controlling the feature dynamically with a boot parameter.
--- arch/arm64/include/asm/pointer_auth.h | 10 ++++++++++ arch/arm64/include/asm/stackprotector.h | 1 + arch/arm64/kernel/head.S | 4 ---- 3 files changed, 11 insertions(+), 4 deletions(-)
arch/arm64/include/asm/pointer_auth.h +10 -0
@@ -76,6 +76,15 @@ static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr)return ptrauth_clear_pac (ptr); } +static __always_inline void ptrauth_enable(void) +{ +if (!system_supports_address_auth ()) +return ; +sysreg_clear_set (sctlr_el1,0 , (SCTLR_ELx_ENIA | SCTLR_ELx_ENIB | + SCTLR_ELx_ENDA | SCTLR_ELx_ENDB)); +isb (); +} +#define ptrauth_thread_init_user (tsk) \ ptrauth_keys_init_user(&(tsk)->thread.keys_user)#define ptrauth_thread_init_kernel (tsk) \
@@ -84,6 +93,7 @@ static inline unsigned long ptrauth_strip_insn_pac(unsigned long ptr) ptrauth_keys_switch_kernel(&(tsk)->thread.keys_kernel)#else /* CONFIG_ARM64_PTR_AUTH */ +#define ptrauth_enable ()#define ptrauth_prctl_reset_keys (tsk, arg) (-EINVAL)#define ptrauth_strip_insn_pac (lr) (lr)#define ptrauth_thread_init_user (tsk)
arch/arm64/include/asm/stackprotector.h +1 -0
@@ -41,6 +41,7 @@ static __always_inline void boot_init_stack_canary(void)#endif ptrauth_thread_init_kernel (current);ptrauth_thread_switch_kernel (current); + ptrauth_enable(); }#endif /* _ASM_STACKPROTECTOR_H */
arch/arm64/kernel/head.S +0 -4
@@ -404,10 +404,6 @@ SYM_FUNC_START_LOCAL(__primary_switched) adr_l x5, init_task msr sp_el0, x5 // Save thread_info -#ifdef CONFIG_ARM64_PTR_AUTH - __ptrauth_keys_init_cpu x5, x6, x7, x8 -#endif - adr_l x8, vectors // load VBAR_EL1 with virtual msr vbar_el1, x8 // vector table address isb
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 20/21] arm64: Defer enabling pointer authentication on boot core
Quoted 7 lines · Marc Zyngier
From: Srinivas Ramana <[email protected]>
Defer enabling pointer authentication on boot core until after its required to be enabled by cpufeature framework. This will help in controlling the feature dynamically with a boot parameter.
Quoted 5 lines
Signed-off-by Ajay Patil <[email protected]>Signed-off-by Prasad Sodagudi <[email protected]>Signed-off-by Srinivas Ramana <[email protected]>Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Marc Zyngier
maintainerPATCH v4 21/21 arm64: cpufeatures: Allow disabling of Pointer Auth from the command-line
In reply to Marc ZyngierIn order to be able to disable Pointer Authentication at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64ISAR1_EL1.{GPI,GPA,API,APA} fields.
This is further mapped on the arm64.nopauth command-line alias.
--- Documentation/admin-guide/kernel-parameters.txt | 3 +++ arch/arm64/include/asm/cpufeature.h | 2 ++ arch/arm64/kernel/cpufeature.c | 5 ++++- arch/arm64/kernel/idreg-override.c | 17 +++++++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-)
Documentation/admin-guide/kernel-parameters.txt +3 -0
@@ -376,6 +376,9 @@ arm64.nobti [ARM64] Unconditionally disable Branch Target Identification support + arm64.nopauth [ARM64] Unconditionally disable Pointer Authentication + support + ataflop= [HW,M68k] atarimouse= [HW,MOUSE] Atari Mouse
arch/arm64/include/asm/cpufeature.h +2 -0
@@ -818,6 +818,8 @@ extern u64 id_aa64mmfr1_val;extern u64 id_aa64mmfr1_mask;extern u64 id_aa64pfr1_val;extern u64 id_aa64pfr1_mask; +extern u64 id_aa64isar1_val; +extern u64 id_aa64isar1_mask;u32 get_kvm_ipa_limit (void );void dump_cpu_features (void );
arch/arm64/kernel/cpufeature.c +4 -1
@@ -559,6 +559,8 @@ u64 id_aa64mmfr1_val;u64 id_aa64mmfr1_mask;u64 id_aa64pfr1_val;u64 id_aa64pfr1_mask; +u64 id_aa64isar1_val; +u64 id_aa64isar1_mask; static const struct __ftr_reg_entry { u32 sys_id;
@@ -604,7 +606,8 @@ static const struct __ftr_reg_entry {/* Op1 = 0, CRn = 0, CRm = 6 */ ARM64_FTR_REG (SYS_ID_AA64ISAR0_EL1 , ftr_id_aa64isar0), -ARM64_FTR_REG (SYS_ID_AA64ISAR1_EL1 , ftr_id_aa64isar1), +ARM64_FTR_REG_OVERRIDE (SYS_ID_AA64ISAR1_EL1 , ftr_id_aa64isar1, + &id_aa64isar1_val, &id_aa64isar1_mask),/* Op1 = 0, CRn = 0, CRm = 7 */ ARM64_FTR_REG(SYS_ID_AA64MMFR0_EL1, ftr_id_aa64mmfr0),
arch/arm64/kernel/idreg-override.c +17 -0
@@ -43,6 +43,19 @@ static const struct reg_desc pfr1 __initdata = { }, }; +static const struct reg_desc isar1__initdata = { + .name ="id_aa64isar1" , + .val = &id_aa64isar1_val, + .mask = &id_aa64isar1_mask, + .fields = { + {"gpi" ,ID_AA64ISAR1_GPI_SHIFT }, + {"gpa" ,ID_AA64ISAR1_GPA_SHIFT }, + {"api" ,ID_AA64ISAR1_API_SHIFT }, + {"apa" ,ID_AA64ISAR1_APA_SHIFT }, + {} + }, +}; +extern u64 kaslr_feature_val;extern u64 kaslr_feature_mask;
@@ -61,6 +74,7 @@ static const struct reg_desc kaslr __initdata = {static const struct reg_desc *const regs[]__initdata = { &mmfr1, &pfr1, + &isar1, &kaslr, };
@@ -71,6 +85,9 @@ static const struct { { "kvm-arm.mode=nvhe", "id_aa64mmfr1.vh=0" }, { "kvm-arm.mode=protected", "id_aa64mmfr1.vh=0" }, { "arm64.nobti", "id_aa64pfr1.bt=0" }, + { "arm64.nopauth", +"id_aa64isar1.gpi=0 id_aa64isar1.gpa=0 " + "id_aa64isar1.api=0 id_aa64isar1.apa=0" }, { "nokaslr", "kaslr.disabled=1" }, };
Signature · 6 lines
2.29.2 _______________________________________________ kvmarm mailing list [email protected] https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Re: [PATCH v4 21/21] arm64: cpufeatures: Allow disabling of Pointer Auth from the command-line
Quoted 8 lines · Marc Zyngier
In order to be able to disable Pointer Authentication at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64ISAR1_EL1.{GPI,GPA,API,APA} fields.
This is further mapped on the arm64.nopauth command-line alias.
Signed-off-by Marc Zyngier <[email protected]>
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm
Srinivas Ramana
Tested-byRe: [PATCH v4 21/21] arm64: cpufeatures: Allow disabling of Pointer Auth from the command-line
Hi Marc,
Quoted 10 lines · Catalin Marinas
Quoted 8 lines · Marc Zyngier
In order to be able to disable Pointer Authentication at runtime, whether it is for testing purposes, or to work around HW issues, let's add support for overriding the ID_AA64ISAR1_EL1.{GPI,GPA,API,APA} fields.
This is further mapped on the arm64.nopauth command-line alias.
Signed-off-by Marc Zyngier <[email protected]>Reviewed-by Catalin Marinas <[email protected]>
Verified this Series for PAC control feature from command line. with arm64.nopauth, we could see PAUTH is disabled on both primary and secondary cores as expected.
HWCAPs show no PAC support and kernel instructions are being treated as NOPs.
Quoted 51 lines · Marc Zyngier
It recently came to light that there is a need to be able to override some CPU features very early on, before the kernel is fully up and running. The reasons for this range from specific feature support (such as using Protected KVM on VHE HW, which is the main motivation for this work) to errata workaround (a feature is broken on a CPU and needs to be turned off, or rather not enabled).
This series tries to offer a limited framework for this kind of problems, by allowing a set of options to be passed on the command-line and altering the feature set that the cpufeature subsystem exposes to the rest of the kernel. Note that this doesn't change anything for code that directly uses the CPU ID registers.
The series completely changes the way a VHE-capable system boots, by *always* booting non-VHE first, and then upgrading to VHE when deemed capable. Although it sounds scary, this is actually simple to implement (and I wish I had done that five years ago). The "upgrade to VHE" path is then conditioned on the VHE feature not being disabled from the command-line.
Said command-line parsing borrows a lot from the kaslr code, and subsequently allows the "nokaslr" option to be moved to the new infrastructure (though it all looks a bit... odd).
Further patches now add support for disabling BTI and PAuth, the latter being based on an initial series by Srinivas Ramana[0]. There is some ongoing discussions about being able to disable MTE, but no clear resolution on that subject yet.
This has been tested on multiple VHE and non-VHE systems.
* From v3 [3]:
- Fixed theVHE_RESTARTstub (duh!)
- Switched to usingarm64_ftr_safe_value()instead of the user provided value
- Per-feature override warning* From v2 [2]:
- Simplify theVHE_RESTARTstub
- Fixed a number of spelling mistakes, and hopefully introduced a few more
- Override features in__read_sysreg_by_encoding()
- Allow both BTI and PAuth to be overridden on the command line
- Rebased on -rc3* From v1 [1]:
- Fix SPE init on VHE when EL2 doesn't own SPE
- Fix re-init when KASLR is used
- Handle the resume path
- Rebased to 5.11-rc2
Quoted 4 lines
[0] https://lore.kernel.org/r/[email protected]
[1] https://lore.kernel.org/r/[email protected]
[2] https://lore.kernel.org/r/[email protected]
[3] https://lore.kernel.org/r/[email protected]
Pretty cool! Left a few minor comments here and there, other than that:
_______________________________________________
kvmarm mailing list
[email protected]
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm