From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:58:21
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 v5 [5]:
- Turn most __initdata into __initconst
- Ensure that all strings are part of the __initconst section.
This is a bit ugly, but saves memory once up and running
- Make overrides __ro_after_init
- Change the command-line parsing so that the same feature can
be overridden multiple times, with the expected left-to-right
parsing order being respected
- Handle all space-like characters as option delimiters
- Collected Acks, RBs and TBs
* From v4 [4]:
- Documentation fixes
- Moved the val/mask pair into a arm64_ftr_override structure,
leading to simpler code
- All arm64_ftr_reg now have a default override, which simplifies
the code a bit further
- Dropped some of the "const" attributes
- Renamed init_shadow_regs() to init_feature_override()
- Renamed struct reg_desc to struct ftr_set_desc
- Refactored command-line parsing
- Simplified handling of VHE being disabled on the cmdline
- Turn EL1 S1 MMU off on switch to VHE
- HVC_VHE_RESTART now returns an error code on failure
- Added missing asmlinkage and dummy prototypes
- Collected Acks and RBs from David, Catalin and Suzuki
* 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/1610152163-16554-1-git-send-email-sramana@codeaurora.org
[1] https://lore.kernel.org/r/20201228104958.1848833-1-maz@kernel.org
[2] https://lore.kernel.org/r/20210104135011.2063104-1-maz@kernel.org
[3] https://lore.kernel.org/r/20210111132811.2455113-1-maz@kernel.org
[4] https://lore.kernel.org/r/20210118094533.2874082-1-maz@kernel.org
[5] https://lore.kernel.org/r/20210125105019.2946057-1-maz@kernel.org
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 | 11 +
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/asm-offsets.c | 3 +
arch/arm64/kernel/cpufeature.c | 73 +++++-
arch/arm64/kernel/head.S | 75 +-----
arch/arm64/kernel/hyp-stub.S | 133 +++++++++-
arch/arm64/kernel/idreg-override.c | 230 ++++++++++++++++++
arch/arm64/kernel/kaslr.c | 43 +---
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 +-
22 files changed, 563 insertions(+), 170 deletions(-)
create mode 100644 arch/arm64/include/asm/setup.h
create mode 100644 arch/arm64/kernel/idreg-override.c
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:57:58
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 <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
arch/arm64/mm/proc.S | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:57:58
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 <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/virt.h | 7 +++-
arch/arm64/kernel/hyp-stub.S | 76 ++++++++++++++++++++++++++++++++++-
2 files changed, 80 insertions(+), 3 deletions(-)
@@ -35,8 +35,13 @@*/#define HVC_RESET_VECTORS 2+/*+*HVC_VHE_RESTART-UpgradetheCPUfromEL1toEL2,ifpossible+*/+#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
@@ -70,6 +73,75 @@ SYM_CODE_START_LOCAL(el1_sync)eretSYM_CODE_END(el1_sync)+//nVHE?Noway!Givemetherealthing!+SYM_CODE_START_LOCAL(mutate_to_vhe)+//Bepreparedtofail+mov_qx0,HVC_STUB_ERR++//Sanitycheck:MMU*must*beoff+mrsx1,sctlr_el2+tbnzx1,#0, 1f++//NeedstobeVHEcapable,obviously+mrsx1,id_aa64mmfr1_el1+ubfxx1,x1,#ID_AA64MMFR1_VHE_SHIFT, #4+cbzx1,1f++//EngagetheVHEmagic!+mov_qx0,HCR_HOST_VHE_FLAGS+msrhcr_el2,x0+isb++//Doesn't do much on VHE, but still, worth a shot+init_el2_statevhe++//UsetheEL1allocatedstack,per-cpuoffset+mrsx0,sp_el1+movsp,x0+mrsx0,tpidr_el1+msrtpidr_el2,x0++//FPconfiguration,vectors+mrs_sx0,SYS_CPACR_EL12+msrcpacr_el1,x0+mrs_sx0,SYS_VBAR_EL12+msrvbar_el1,x0++//TransfertheMMstatefromEL1toEL2+mrs_sx0,SYS_TCR_EL12+msrtcr_el1,x0+mrs_sx0,SYS_TTBR0_EL12+msrttbr0_el1,x0+mrs_sx0,SYS_TTBR1_EL12+msrttbr1_el1,x0+mrs_sx0,SYS_MAIR_EL12+msrmair_el1,x0+isb++//InvalidateTLBsbeforeenablingtheMMU+tlbivmalle1+dsbnsh++//EnabletheEL2S1MMU,assetupfromEL1+mrs_sx0,SYS_SCTLR_EL12+set_sctlr_el1x0++//DisabletheEL1S1MMUforagoodmeasure+mov_qx0,INIT_SCTLR_EL1_MMU_OFF+msr_sSYS_SCTLR_EL12,x0++//HacktheexceptionreturntostayatEL2+mrsx0,spsr_el1+andx0,x0,#~PSR_MODE_MASK+movx1,#PSR_MODE_EL2h+orrx0,x0,x1+msrspsr_el1,x0++movx0,xzr++1:eret+SYM_CODE_END(mutate_to_vhe)+.macroinvalid_vectorlabelSYM_CODE_START_LOCAL(\label)b\label
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:57:58
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 <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
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(-)
@@ -675,6 +675,23 @@ USER(\label, ic ivau, \tmp2) // invalidate I line PoU.endif.endm+/*+*SetSCTLR_EL1tothepassedvalue,andinvalidatethelocalicache+*intheprocess.ThisiscalledwhensettingtheMMUon.+*/+.macroset_sctlr_el1,reg+msrsctlr_el1,\reg+isb+/*+*InvalidatethelocalI-cachesothatanyinstructionsfetched+*speculativelyfromthePoCarediscarded,sincetheymayhave+*beendynamicallypatchedatthePoU.+*/+iciallu+dsbnsh+isb+.endm+/**CheckwhethertoyieldtoanotherrunnabletaskfromkernelmodeNEONcode*(whichrunswithpreemptiondisabled).
@@ -291,17 +291,7 @@ skip_pgd:/*We're done: fire up the MMU again */mrsx17,sctlr_el1orrx17,x17,#SCTLR_ELx_M-msrsctlr_el1,x17-isb--/*-*InvalidatethelocalI-cachesothatanyinstructionsfetched-*speculativelyfromthePoCarediscarded,sincetheymayhave-*beendynamicallypatchedatthePoU.-*/-iciallu-dsbnsh-isb+set_sctlr_el1x17/*Settheflagtozerotoindicatethatwe're all done */strwzr,[flag_ptr]
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:58:46
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.
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
---
arch/arm64/include/asm/el2_setup.h | 24 ++++++++++++------------
1 file changed, 12 insertions(+), 12 deletions(-)
@@ -45,24 +45,24 @@mrsx1,id_aa64dfr0_el1sbfxx0,x1,#ID_AA64DFR0_PMUVER_SHIFT,#4cmpx0,#1-b.lt1f// Skip if no PMU present+b.lt.Lskip_pmu_\@// Skip if no PMU presentmrsx0,pmcr_el0// Disable debug access trapsubfxx0,x0,#11,#5// to EL2 and allow access to-1:+.Lskip_pmu_\@:cselx2,xzr,x0,lt// all PMU counters from EL1/* Statistical profiling */ubfxx0,x1,#ID_AA64DFR0_PMSVER_SHIFT,#4-cbzx0,3f// Skip if SPE not present+cbzx0,.Lskip_spe_\@// Skip if SPE not present.ifeqs"\mode","nvhe"mrs_sx0,SYS_PMBIDR_EL1// If SPE available at EL2,andx0,x0,#(1<<SYS_PMBIDR_EL1_P_SHIFT)-cbnzx0,2f// then permit sampling of physical+cbnzx0,.Lskip_spe_el2_\@// then permit sampling of physicalmovx0,#(1<<SYS_PMSCR_EL2_PCT_SHIFT|\1<<SYS_PMSCR_EL2_PA_SHIFT)msr_sSYS_PMSCR_EL2,x0// addresses and physical counter-2:+.Lskip_spe_el2_\@:movx0,#(MDCR_EL2_E2PB_MASK<<MDCR_EL2_E2PB_SHIFT)orrx2,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_\@:msrmdcr_el2,x2// Configure debug traps.endm
@@ -93,7 +93,7 @@.macro__init_el2_gicv3mrsx0,id_aa64pfr0_el1ubfxx0,x0,#ID_AA64PFR0_GIC_SHIFT,#4-cbzx0,1f+cbzx0,.Lskip_gicv3_\@mrs_sx0,SYS_ICC_SRE_EL2orrx0,x0,#ICC_SRE_EL2_SRE// Set ICC_SRE_EL2.SRE==1
@@ -103,7 +103,7 @@mrs_sx0,SYS_ICC_SRE_EL2// Read SRE back,tbzx0,#0,1f// and check that it sticksmsr_sSYS_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_svemrsx1,id_aa64pfr0_el1ubfxx1,x1,#ID_AA64PFR0_SVE_SHIFT,#4-cbzx1,1f+cbzx1,.Lskip_sve_\@bicx0,x0,#CPTR_EL2_TZ// Also disable SVE trapsmsrcptr_el2,x0// Disable copro. traps to EL2isbmovx1,#ZCR_ELx_LEN_MASK// SVE: Enable full vectormsr_sSYS_ZCR_EL2,x1// length for EL1.-1:+.Lskip_sve_\@:.endm.macro__init_el2_nvhe_prepare_eret
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:59:00
There 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/hyp-stub.S | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
@@ -92,9 +92,6 @@ SYM_CODE_START_LOCAL(mutate_to_vhe)msrhcr_el2,x0isb-//Doesn't do much on VHE, but still, worth a shot-init_el2_statevhe-//UsetheEL1allocatedstack,per-cpuoffsetmrsx0,sp_el1movsp,x0
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:59:24
As 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
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(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 11:59:45
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 <maz@kernel.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: David Brazdil <redacted>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 6 ++++
arch/arm64/kernel/cpufeature.c | 45 +++++++++++++++++++++++++----
2 files changed, 45 insertions(+), 6 deletions(-)
@@ -63,6 +63,11 @@ struct arm64_ftr_bits {s64safe_val;/* safe value for FTR_EXACT features */};+structarm64_ftr_override{+u64val;+u64mask;+};+/**@arm64_ftr_reg-Featureregister*@strict_maskBitswhichshouldmatchacrossallCPUsforsanity.
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:00:24
We can now move the initial SCTLR_EL1 setup to be used for both
EL1 and EL2 setup.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
arch/arm64/kernel/head.S | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
@@ -55,7 +53,6 @@ubfxx0,x1,#ID_AA64DFR0_PMSVER_SHIFT,#4cbzx0,.Lskip_spe_\@// Skip if SPE not present-.ifeqs"\mode","nvhe"mrs_sx0,SYS_PMBIDR_EL1// If SPE available at EL2,andx0,x0,#(1<<SYS_PMBIDR_EL1_P_SHIFT)cbnzx0,.Lskip_spe_el2_\@// then permit sampling of physical
@@ -66,10 +63,6 @@movx0,#(MDCR_EL2_E2PB_MASK<<MDCR_EL2_E2PB_SHIFT)orrx2,x2,x0// If we don't have VHE, then// use EL1&0 translation.-.else-orrx2,x2,#MDCR_EL2_TPMS// For VHE, use EL2 translation-// and disable access from EL1-.endif.Lskip_spe_\@:msrmdcr_el2,x2// Configure debug traps
@@ -189,7 +189,7 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu)2:msrSPsel,#1 // We want to use SP_EL{1,2}/*InitializeEL2CPUstatetosanevalues.*/-init_el2_statenvhe//Clobbersx0..x2+init_el2_state//Clobbersx0..x2/*EnableMMU,setvectorsandstack.*/movx0,x28
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:04:59
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 <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/head.S | 1 +
arch/arm64/kernel/idreg-override.c | 164 +++++++++++++++++++++++++++++
3 files changed, 166 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/idreg-override.c
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:17
From: Srinivas Ramana <redacted>
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.
Signed-off-by: Ajay Patil <redacted>
Signed-off-by: Prasad Sodagudi <redacted>
Signed-off-by: Srinivas Ramana <redacted>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/1610152163-16554-2-git-send-email-sramana@codeaurora.org
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
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(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:17
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 <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
arch/arm64/kernel/idreg-override.c | 15 +++++++++++++
arch/arm64/kernel/kaslr.c | 36 ++----------------------------
2 files changed, 17 insertions(+), 34 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:17
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 <maz@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
Tested-by: Srinivas Ramana <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 3 +++
arch/arm64/include/asm/cpufeature.h | 1 +
arch/arm64/kernel/cpufeature.c | 4 +++-
arch/arm64/kernel/idreg-override.c | 11 +++++++++++
arch/arm64/mm/mmu.c | 2 +-
5 files changed, 19 insertions(+), 2 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:37
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 <maz@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
arch/arm64/kernel/idreg-override.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:47
__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 <maz@kernel.org>
Reviewed-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Acked-by: David Brazdil <redacted>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 1 +
arch/arm64/kernel/cpufeature.c | 15 +++++++++++++--
2 files changed, 14 insertions(+), 2 deletions(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:05:51
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 <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/asm-offsets.c | 3 +++
arch/arm64/kernel/hyp-stub.S | 11 +++++++++++
2 files changed, 14 insertions(+)
@@ -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 means (command line+ option, for example).+ Any other value of r0/x0 triggers a hypervisor-specific handling, which is not documented here.
--
2.29.2
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:06:29
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 <maz@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
Tested-by: Srinivas Ramana <redacted>
---
Documentation/admin-guide/kernel-parameters.txt | 3 +++
arch/arm64/include/asm/cpufeature.h | 1 +
arch/arm64/kernel/cpufeature.c | 4 +++-
arch/arm64/kernel/idreg-override.c | 16 ++++++++++++++++
4 files changed, 23 insertions(+), 1 deletion(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:07:19
As 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/include/asm/cpufeature.h | 2 ++
arch/arm64/kernel/cpufeature.c | 5 ++++-
arch/arm64/kernel/idreg-override.c | 11 +++++++++++
3 files changed, 17 insertions(+), 1 deletion(-)
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:08:12
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 <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
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
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-01 12:08:12
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 <maz@kernel.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Brazdil <redacted>
---
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(+)
@@ -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.
From: Will Deacon <will@kernel.org> Date: 2021-02-03 21:14:25
Hi Marc,
On Mon, Feb 01, 2021 at 11:56:22AM +0000, Marc Zyngier wrote:
quoted hunk
There 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/hyp-stub.S | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
@@ -92,9 +92,6 @@ SYM_CODE_START_LOCAL(mutate_to_vhe)msrhcr_el2,x0isb-//Doesn't do much on VHE, but still, worth a shot-init_el2_statevhe-//UsetheEL1allocatedstack,per-cpuoffsetmrsx0,sp_el1movsp,x0
Why do we need to touch pmscr_el1 at all? The SPE driver should take care of
that, no? If you drop the pmscr_el1 accesses, I think you can drop the
pmbidr_el1 check as well. And actually, then why even check dfr0? Doing the
bic for the mdcr_el1.e2pb bits is harmless.
+ 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
Doesn't this undo the setting of mdcr_el2.hpmn if SPE is not present or
unavailable? (This wouldn't be an issue if we removed the skip_spe paths
altogether).
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-04 09:31:14
Hi Will,
On 2021-02-03 21:13, Will Deacon wrote:
Hi Marc,
On Mon, Feb 01, 2021 at 11:56:22AM +0000, Marc Zyngier wrote:
quoted
There 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/hyp-stub.S | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/hyp-stub.S
b/arch/arm64/kernel/hyp-stub.S
index 373ed2213e1d..6b5c73cf9d52 100644
@@ -92,9 +92,6 @@ SYM_CODE_START_LOCAL(mutate_to_vhe)msrhcr_el2,x0isb-//Doesn't do much on VHE, but still, worth a shot-init_el2_statevhe-//UsetheEL1allocatedstack,per-cpuoffsetmrsx0,sp_el1movsp,x0
Why do we need to touch pmscr_el1 at all? The SPE driver should take
care of
that, no? If you drop the pmscr_el1 accesses, I think you can drop the
pmbidr_el1 check as well.
That's definitely a brain fart, and is what we need on the nVHE path,
not here. Doing the same thing twice isn't exactly helpful.
And actually, then why even check dfr0? Doing the
bic for the mdcr_el1.e2pb bits is harmless.
quoted
+ 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
Doesn't this undo the setting of mdcr_el2.hpmn if SPE is not present or
unavailable? (This wouldn't be an issue if we removed the skip_spe
paths
altogether).
I don't think it does. We only clear the E2PB bits (harmless, as you
point
out above), and OR something that is either 0 (no SPE) or MDCR_EL2_TPMS.
In any case, the HPMN bits are preserved (having been set during the
nVHE
setup).
I think the following patch addresses the above issue, which I'll squash
with the original patch. Please shout if I missed anything.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-02-04 09:35:47
On Thu, Feb 04, 2021 at 09:30:08AM +0000, Marc Zyngier wrote:
Hi Will,
On 2021-02-03 21:13, Will Deacon wrote:
quoted
Hi Marc,
On Mon, Feb 01, 2021 at 11:56:22AM +0000, Marc Zyngier wrote:
quoted
There 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.
Signed-off-by: Marc Zyngier <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/hyp-stub.S | 28 +++++++++++++++++++++++++---
1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/kernel/hyp-stub.S
b/arch/arm64/kernel/hyp-stub.S
index 373ed2213e1d..6b5c73cf9d52 100644
@@ -92,9 +92,6 @@ SYM_CODE_START_LOCAL(mutate_to_vhe)msrhcr_el2,x0isb-//Doesn't do much on VHE, but still, worth a shot-init_el2_statevhe-//UsetheEL1allocatedstack,per-cpuoffsetmrsx0,sp_el1movsp,x0
Why do we need to touch pmscr_el1 at all? The SPE driver should take
care of
that, no? If you drop the pmscr_el1 accesses, I think you can drop the
pmbidr_el1 check as well.
That's definitely a brain fart, and is what we need on the nVHE path,
not here. Doing the same thing twice isn't exactly helpful.
quoted
And actually, then why even check dfr0? Doing the
bic for the mdcr_el1.e2pb bits is harmless.
quoted
+ 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
Doesn't this undo the setting of mdcr_el2.hpmn if SPE is not present or
unavailable? (This wouldn't be an issue if we removed the skip_spe paths
altogether).
I don't think it does. We only clear the E2PB bits (harmless, as you point
out above), and OR something that is either 0 (no SPE) or MDCR_EL2_TPMS.
In any case, the HPMN bits are preserved (having been set during the nVHE
setup).
Duh, OR not AND. Yes, sorry.
quoted hunk
I think the following patch addresses the above issue, which I'll squash
with the original patch. Please shout if I missed anything.
Thanks,
M.
Looks a tonne better, thanks! Be nice if somebody could test it for us.
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
Looks a tonne better, thanks! Be nice if somebody could test it for us.
SPE-equipped machines are the silicon equivalent of hen's teeth...
Alex, any chance you could give this a go?
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Hector Martin 'marcan' <hidden> Date: 2021-02-05 12:07:30
On 01/02/2021 20.56, Marc Zyngier wrote:
As 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).
Unfortunately, this is going to break on Apple SoCs, where it turns out
HCR_EL2.E2H is hard-wired to 1 - there is no nVHE mode. :(
>>> mrs(HCR_EL2) & (1<<34)
0x400000000
>>> msr(HCR_EL2, mrs(HCR_EL2) & ~(1<<34))
>>> mrs(HCR_EL2) & (1<<34)
0x400000000
--
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Will Deacon <will@kernel.org> Date: 2021-02-05 20:35:10
On Mon, Feb 01, 2021 at 11:56:28AM +0000, Marc Zyngier wrote:
quoted hunk
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 <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/head.S | 1 +
arch/arm64/kernel/idreg-override.c | 164 +++++++++++++++++++++++++++++
3 files changed, 166 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/idreg-override.c
I'm absolutely terrified of string parsing in C, but just wondering why you
only ignore literal spaces here. I _think_ the full-fat cmdline parsing uses
isspace() to delimit the options.
Would it be possible to reuse any of the logic over in parse_args() to avoid
having to roll this ourselves?
Will
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-05 20:37:24
On 2021-02-05 16:35, Will Deacon wrote:
On Mon, Feb 01, 2021 at 11:56:28AM +0000, Marc Zyngier wrote:
quoted
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 <maz@kernel.org>
Acked-by: David Brazdil <redacted>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
arch/arm64/kernel/Makefile | 2 +-
arch/arm64/kernel/head.S | 1 +
arch/arm64/kernel/idreg-override.c | 164
+++++++++++++++++++++++++++++
3 files changed, 166 insertions(+), 1 deletion(-)
create mode 100644 arch/arm64/kernel/idreg-override.c
I'm absolutely terrified of string parsing in C, but just wondering why
you
only ignore literal spaces here. I _think_ the full-fat cmdline parsing
uses
isspace() to delimit the options.
That's clearly an oversight, as I use a more complete set of characters
for the rest of the option splicing. I also think that with the way
things are now parsed (options being extracted early and trimmed),
we can drop this altogether.
Would it be possible to reuse any of the logic over in parse_args() to
avoid
having to roll this ourselves?
Maybe. I need to have a look.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Marc Zyngier <maz@kernel.org> Date: 2021-02-05 23:31:20
Hi Hector,
On 2021-02-05 12:01, Hector Martin 'marcan' wrote:
On 01/02/2021 20.56, Marc Zyngier wrote:
quoted
As 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).
Unfortunately, this is going to break on Apple SoCs, where it turns
out HCR_EL2.E2H is hard-wired to 1 - there is no nVHE mode. :(
#facepalm
Thanks for the heads up. That's a blatant violation of the architecture,
as the only fixed value allowed is 0. I guess it was tempting for them
to ignore about half of the architecture... Oh well.
Here's a terrible hack on top of this series. It really doesn't
play nicely with the rest of the override stuff, but that's the
least of your worries at this stage. I've boot-tested it in a model
with E2H artificially forced, and nothing caught fire. YMMV.
It also means that if/when we merge the support for this CPU,
CONFIG_ARM64_VHE will becomes more or less mandatory...
Please let me know if this helps.
Thanks,
M.
--
Jazz is not dead. It just smells funny...
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
From: Hector Martin 'marcan' <hidden> Date: 2021-02-06 14:31:44
On 05/02/2021 23.04, Marc Zyngier wrote:
#facepalm
Thanks for the heads up. That's a blatant violation of the architecture,
as the only fixed value allowed is 0. I guess it was tempting for them
to ignore about half of the architecture... Oh well.
Here's a terrible hack on top of this series. It really doesn't
play nicely with the rest of the override stuff, but that's the
least of your worries at this stage. I've boot-tested it in a model
with E2H artificially forced, and nothing caught fire. YMMV.
It also means that if/when we merge the support for this CPU,
CONFIG_ARM64_VHE will becomes more or less mandatory...
Please let me know if this helps.
Yup, works fine. Tested the patchset on top of our tree, breaks as
expected, adding this patch makes it boot again.
--
Hector Martin "marcan" (marcan@marcan.st)
Public Key: https://mrcn.st/pub
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel