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

Commit bd4fb6d2 authored by Will Deacon's avatar Will Deacon
Browse files

arm64: Add support for SB barrier and patch in over DSB; ISB sequences



We currently use a DSB; ISB sequence to inhibit speculation in set_fs().
Whilst this works for current CPUs, future CPUs may implement a new SB
barrier instruction which acts as an architected speculation barrier.

On CPUs that support it, patch in an SB; NOP sequence over the DSB; ISB
sequence and advertise the presence of the new instruction to userspace.

Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
parent 0b587c84
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -122,6 +122,19 @@
	hint	#20
	.endm

/*
 * Speculation barrier
 */
	.macro	sb
alternative_if_not ARM64_HAS_SB
	dsb	nsh
	isb
alternative_else
	SB_BARRIER_INSN
	nop
alternative_endif
	.endm

/*
 * Sanitise a 64-bit bounded index wrt speculation, returning zero if out
 * of bounds.
+4 −0
Original line number Diff line number Diff line
@@ -34,6 +34,10 @@
#define psb_csync()	asm volatile("hint #17" : : : "memory")
#define csdb()		asm volatile("hint #20" : : : "memory")

#define spec_bar()	asm volatile(ALTERNATIVE("dsb nsh\nisb\n",		\
						 SB_BARRIER_INSN"nop\n",	\
						 ARM64_HAS_SB))

#define mb()		dsb(sy)
#define rmb()		dsb(ld)
#define wmb()		dsb(st)
+2 −1
Original line number Diff line number Diff line
@@ -54,7 +54,8 @@
#define ARM64_HAS_CRC32				33
#define ARM64_SSBS				34
#define ARM64_WORKAROUND_1188873		35
#define ARM64_HAS_SB				36

#define ARM64_NCAPS				36
#define ARM64_NCAPS				37

#endif /* __ASM_CPUCAPS_H */
+6 −0
Original line number Diff line number Diff line
@@ -104,6 +104,11 @@
#define SET_PSTATE_UAO(x)		__emit_inst(0xd500401f | PSTATE_UAO | ((!!x) << PSTATE_Imm_shift))
#define SET_PSTATE_SSBS(x)		__emit_inst(0xd500401f | PSTATE_SSBS | ((!!x) << PSTATE_Imm_shift))

#define __SYS_BARRIER_INSN(CRm, op2, Rt) \
	__emit_inst(0xd5000000 | sys_insn(0, 3, 3, (CRm), (op2)) | ((Rt) & 0x1f))

#define SB_BARRIER_INSN			__SYS_BARRIER_INSN(0, 7, 31)

#define SYS_DC_ISW			sys_insn(1, 0, 7, 6, 2)
#define SYS_DC_CSW			sys_insn(1, 0, 7, 10, 2)
#define SYS_DC_CISW			sys_insn(1, 0, 7, 14, 2)
@@ -528,6 +533,7 @@
#define ID_AA64ISAR0_AES_SHIFT		4

/* id_aa64isar1 */
#define ID_AA64ISAR1_SB_SHIFT		36
#define ID_AA64ISAR1_LRCPC_SHIFT	20
#define ID_AA64ISAR1_FCMA_SHIFT		16
#define ID_AA64ISAR1_JSCVT_SHIFT	12
+1 −2
Original line number Diff line number Diff line
@@ -45,8 +45,7 @@ static inline void set_fs(mm_segment_t fs)
	 * Prevent a mispredicted conditional call to set_fs from forwarding
	 * the wrong address limit to access_ok under speculation.
	 */
	dsb(nsh);
	isb();
	spec_bar();

	/* On user-mode return, check fs is correct */
	set_thread_flag(TIF_FSCHECK);
Loading