Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6044ba2f authored by Will Deacon's avatar Will Deacon Committed by Mayank Grover
Browse files

arm64: cpufeature: Detect SSBS and advertise to userspace



Armv8.5 introduces a new PSTATE bit known as Speculative Store Bypass
Safe (SSBS) which can be used as a mitigation against Spectre variant 4.

Additionally, a CPU may provide instructions to manipulate PSTATE.SSBS
directly, so that userspace can toggle the SSBS control without trapping
to the kernel.

This patch probes for the existence of SSBS and advertise the new instructions
to userspace if they exist.

Change-Id: Ieeb4f8d70afcc1d610716f0d1306a73093ff2660
Reviewed-by: default avatarSuzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
Git-commit: d71be2b6c0e19180b5f80a6d42039cc074a693a2
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[neeraju@codeaurora: Resolve trivial merge conflicts]
Signed-off-by: default avatarNeeraj Upadhyay <neeraju@codeaurora.org>
[groverm@codeaurora: Resolve merge conflicts]
Signed-off-by: default avatarMayank Grover <groverm@codeaurora.org>
parent f7bb6f3a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -46,7 +46,8 @@
#define ARM64_HW_DBM				26
#define ARM64_SSBD				27
#define ARM64_MISMATCHED_CACHE_TYPE		28
#define ARM64_SSBS				29

#define ARM64_NCAPS				29
#define ARM64_NCAPS				30

#endif /* __ASM_CPUCAPS_H */
+8 −0
Original line number Diff line number Diff line
@@ -301,6 +301,7 @@
#define SYS_ICH_LR15_EL2		__SYS__LR8_EL2(7)

/* Common SCTLR_ELx flags. */
#define SCTLR_ELx_DSSBS	(1UL << 44)
#define SCTLR_ELx_EE    (1 << 25)
#define SCTLR_ELx_I	(1 << 12)
#define SCTLR_ELx_SA	(1 << 3)
@@ -361,6 +362,13 @@
#define ID_AA64PFR0_EL0_64BIT_ONLY	0x1
#define ID_AA64PFR0_EL0_32BIT_64BIT	0x2

/* id_aa64pfr1 */
#define ID_AA64PFR1_SSBS_SHIFT		4

#define ID_AA64PFR1_SSBS_PSTATE_NI	0
#define ID_AA64PFR1_SSBS_PSTATE_ONLY	1
#define ID_AA64PFR1_SSBS_PSTATE_INSNS	2

/* id_aa64mmfr0 */
#define ID_AA64MMFR0_TGRAN4_SHIFT	28
#define ID_AA64MMFR0_TGRAN64_SHIFT	24
+1 −0
Original line number Diff line number Diff line
@@ -42,5 +42,6 @@
#define HWCAP_SM4		(1 << 19)
#define HWCAP_ASIMDDP		(1 << 20)
#define HWCAP_SHA512		(1 << 21)
#define HWCAP_SSBS		(1 << 22)

#endif /* _UAPI__ASM_HWCAP_H */
+17 −2
Original line number Diff line number Diff line
@@ -142,6 +142,11 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr0[] = {
	ARM64_FTR_END,
};

static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR1_SSBS_SHIFT, 4, ID_AA64PFR1_SSBS_PSTATE_NI),
	ARM64_FTR_END,
};

static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = {
	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN4_SHIFT, 4, ID_AA64MMFR0_TGRAN4_NI),
	S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_EXACT, ID_AA64MMFR0_TGRAN64_SHIFT, 4, ID_AA64MMFR0_TGRAN64_NI),
@@ -341,7 +346,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_raz),
	ARM64_FTR_REG(SYS_ID_AA64PFR1_EL1, ftr_id_aa64pfr1),
	ARM64_FTR_REG(SYS_ID_AA64ZFR0_EL1, ftr_raz),

	/* Op1 = 0, CRn = 0, CRm = 5 */
	ARM64_FTR_REG(SYS_ID_AA64DFR0_EL1, ftr_id_aa64dfr0),
@@ -609,7 +615,6 @@ void update_cpu_features(int cpu,

	/*
	 * EL3 is not our concern.
	 * ID_AA64PFR1 is currently RES0.
	 */
	taint |= check_update_ftr_reg(SYS_ID_AA64PFR0_EL1, cpu,
				      info->reg_id_aa64pfr0, boot->reg_id_aa64pfr0);
@@ -1111,6 +1116,15 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
		.enable = cpu_enable_hw_dbm,
	},
#endif
	{
		.desc = "Speculative Store Bypassing Safe (SSBS)",
		.capability = ARM64_SSBS,
		.matches = has_cpuid_feature,
		.sys_reg = SYS_ID_AA64PFR1_EL1,
		.field_pos = ID_AA64PFR1_SSBS_SHIFT,
		.sign = FTR_UNSIGNED,
		.min_field_value = ID_AA64PFR1_SSBS_PSTATE_ONLY,
	},
	{},
};

@@ -1148,6 +1162,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = {
	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_JSCVT_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_JSCVT),
	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_FCMA_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_FCMA),
	HWCAP_CAP(SYS_ID_AA64ISAR1_EL1, ID_AA64ISAR1_LRCPC_SHIFT, FTR_UNSIGNED, 1, CAP_HWCAP, HWCAP_LRCPC),
	HWCAP_CAP(SYS_ID_AA64PFR1_EL1, ID_AA64PFR1_SSBS_SHIFT, FTR_UNSIGNED, ID_AA64PFR1_SSBS_PSTATE_INSNS, CAP_HWCAP, HWCAP_SSBS),
	{},
};

+1 −0
Original line number Diff line number Diff line
@@ -81,6 +81,7 @@ static const char *const hwcap_str[] = {
	"sm4",
	"asimddp",
	"sha512",
	"ssbs",
	NULL
};