Commit b3000e21 authored by Marc Zyngier's avatar Marc Zyngier Committed by Will Deacon
Browse files

arm64: Add the arm64.nosme command line option



In order to be able to completely disable SME even if the HW
seems to support it (most likely because the FW is broken),
move the SME setup into the EL2 finalisation block, and
use a new idreg override to deal with it.

Note that we also nuke id_aa64smfr0_el1 as a byproduct.

Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarMark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20220630160500.1536744-8-maz@kernel.org


Signed-off-by: default avatarWill Deacon <will@kernel.org>
parent 6ab7661e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -400,6 +400,9 @@
	arm64.nomte	[ARM64] Unconditionally disable Memory Tagging Extension
			support

	arm64.nosme	[ARM64] Unconditionally disable Scalable Matrix
			Extension support

	ataflop=	[HW,M68k]

	atarimouse=	[HW,MOUSE] Atari Mouse
+1 −0
Original line number Diff line number Diff line
@@ -909,6 +909,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1)

extern struct arm64_ftr_override id_aa64mmfr1_override;
extern struct arm64_ftr_override id_aa64pfr1_override;
extern struct arm64_ftr_override id_aa64smfr0_override;
extern struct arm64_ftr_override id_aa64isar1_override;
extern struct arm64_ftr_override id_aa64isar2_override;

+0 −45
Original line number Diff line number Diff line
@@ -143,50 +143,6 @@
.Lskip_sve_\@:
.endm

/* SME register access and priority mapping */
.macro __init_el2_nvhe_sme
	mrs	x1, id_aa64pfr1_el1
	ubfx	x1, x1, #ID_AA64PFR1_SME_SHIFT, #4
	cbz	x1, .Lskip_sme_\@

	bic	x0, x0, #CPTR_EL2_TSM		// Also disable SME traps
	msr	cptr_el2, x0			// Disable copro. traps to EL2
	isb

	mrs	x1, sctlr_el2
	orr	x1, x1, #SCTLR_ELx_ENTP2	// Disable TPIDR2 traps
	msr	sctlr_el2, x1
	isb

	mov	x1, #0				// SMCR controls

	mrs_s	x2, SYS_ID_AA64SMFR0_EL1
	ubfx	x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
	cbz	x2, .Lskip_sme_fa64_\@

	orr	x1, x1, SMCR_ELx_FA64_MASK
.Lskip_sme_fa64_\@:

	orr	x1, x1, #SMCR_ELx_LEN_MASK	// Enable full SME vector
	msr_s	SYS_SMCR_EL2, x1		// length for EL1.

	mrs_s	x1, SYS_SMIDR_EL1		// Priority mapping supported?
	ubfx    x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
	cbz     x1, .Lskip_sme_\@

	msr_s	SYS_SMPRIMAP_EL2, xzr		// Make all priorities equal

	mrs	x1, id_aa64mmfr1_el1		// HCRX_EL2 present?
	ubfx	x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
	cbz	x1, .Lskip_sme_\@

	mrs_s	x1, SYS_HCRX_EL2
	orr	x1, x1, #HCRX_EL2_SMPME_MASK	// Enable priority mapping
	msr_s	SYS_HCRX_EL2, x1

.Lskip_sme_\@:
.endm

/* Disable any fine grained traps */
.macro __init_el2_fgt
	mrs	x1, id_aa64mmfr0_el1
@@ -251,7 +207,6 @@
	__init_el2_nvhe_idregs
	__init_el2_nvhe_cptr
	__init_el2_nvhe_sve
	__init_el2_nvhe_sme
	__init_el2_fgt
	__init_el2_nvhe_prepare_eret
.endm
+3 −1
Original line number Diff line number Diff line
@@ -632,6 +632,7 @@ static const struct arm64_ftr_bits ftr_raz[] = {

struct arm64_ftr_override __ro_after_init id_aa64mmfr1_override;
struct arm64_ftr_override __ro_after_init id_aa64pfr1_override;
struct arm64_ftr_override __ro_after_init id_aa64smfr0_override;
struct arm64_ftr_override __ro_after_init id_aa64isar1_override;
struct arm64_ftr_override __ro_after_init id_aa64isar2_override;

@@ -672,7 +673,8 @@ static const struct __ftr_reg_entry {
	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1,
			       &id_aa64pfr1_override),
	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_id_aa64zfr0),
	ARM64_FTR_REG(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0),
	ARM64_FTR_REG_OVERRIDE(SYS_ID_AA64SMFR0_EL1, ftr_id_aa64smfr0,
			       &id_aa64smfr0_override),

	/* Op1 = 0, CRn = 0, CRm = 5 */
	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
+41 −0
Original line number Diff line number Diff line
@@ -98,6 +98,47 @@ SYM_CODE_START_LOCAL(elx_sync)
SYM_CODE_END(elx_sync)

SYM_CODE_START_LOCAL(__finalise_el2)
	check_override id_aa64pfr1 ID_AA64PFR1_SME_SHIFT .Linit_sme .Lskip_sme

.Linit_sme:	/* SME register access and priority mapping */
	mrs	x0, cptr_el2			// Disable SME traps
	bic	x0, x0, #CPTR_EL2_TSM
	msr	cptr_el2, x0
	isb

	mrs	x1, sctlr_el2
	orr	x1, x1, #SCTLR_ELx_ENTP2	// Disable TPIDR2 traps
	msr	sctlr_el2, x1
	isb

	mov	x1, #0				// SMCR controls

	mrs_s	x2, SYS_ID_AA64SMFR0_EL1
	ubfx	x2, x2, #ID_AA64SMFR0_FA64_SHIFT, #1 // Full FP in SM?
	cbz	x2, .Lskip_sme_fa64

	orr	x1, x1, SMCR_ELx_FA64_MASK
.Lskip_sme_fa64:

	orr	x1, x1, #SMCR_ELx_LEN_MASK	// Enable full SME vector
	msr_s	SYS_SMCR_EL2, x1		// length for EL1.

	mrs_s	x1, SYS_SMIDR_EL1		// Priority mapping supported?
	ubfx    x1, x1, #SMIDR_EL1_SMPS_SHIFT, #1
	cbz     x1, .Lskip_sme

	msr_s	SYS_SMPRIMAP_EL2, xzr		// Make all priorities equal

	mrs	x1, id_aa64mmfr1_el1		// HCRX_EL2 present?
	ubfx	x1, x1, #ID_AA64MMFR1_HCX_SHIFT, #4
	cbz	x1, .Lskip_sme

	mrs_s	x1, SYS_HCRX_EL2
	orr	x1, x1, #HCRX_EL2_SMPME_MASK	// Enable priority mapping
	msr_s	SYS_HCRX_EL2, x1

.Lskip_sme:

	// nVHE? No way! Give me the real thing!
	// Sanity check: MMU *must* be off
	mrs	x1, sctlr_el2
Loading