forked from Minki/linux
arm64: mte: Ensure TIF_MTE_ASYNC_FAULT is set atomically
The entry from EL0 code checks the TFSRE0_EL1 register for any
asynchronous tag check faults in user space and sets the
TIF_MTE_ASYNC_FAULT flag. This is not done atomically, potentially
racing with another CPU calling set_tsk_thread_flag().
Replace the non-atomic ORR+STR with an STSET instruction. While STSET
requires ARMv8.1 and an assembler that understands LSE atomics, the MTE
feature is part of ARMv8.5 and already requires an updated assembler.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Fixes: 637ec831ea
("arm64: mte: Handle synchronous and asynchronous tag check faults")
Cc: <stable@vger.kernel.org> # 5.10.x
Reported-by: Will Deacon <will@kernel.org>
Cc: Will Deacon <will@kernel.org>
Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Link: https://lore.kernel.org/r/20210409173710.18582-1-catalin.marinas@arm.com
Signed-off-by: Will Deacon <will@kernel.org>
This commit is contained in:
parent
185f2e5f51
commit
2decad92f4
@ -1406,10 +1406,13 @@ config ARM64_PAN
|
|||||||
config AS_HAS_LDAPR
|
config AS_HAS_LDAPR
|
||||||
def_bool $(as-instr,.arch_extension rcpc)
|
def_bool $(as-instr,.arch_extension rcpc)
|
||||||
|
|
||||||
|
config AS_HAS_LSE_ATOMICS
|
||||||
|
def_bool $(as-instr,.arch_extension lse)
|
||||||
|
|
||||||
config ARM64_LSE_ATOMICS
|
config ARM64_LSE_ATOMICS
|
||||||
bool
|
bool
|
||||||
default ARM64_USE_LSE_ATOMICS
|
default ARM64_USE_LSE_ATOMICS
|
||||||
depends on $(as-instr,.arch_extension lse)
|
depends on AS_HAS_LSE_ATOMICS
|
||||||
|
|
||||||
config ARM64_USE_LSE_ATOMICS
|
config ARM64_USE_LSE_ATOMICS
|
||||||
bool "Atomic instructions"
|
bool "Atomic instructions"
|
||||||
@ -1666,6 +1669,7 @@ config ARM64_MTE
|
|||||||
default y
|
default y
|
||||||
depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI
|
depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI
|
||||||
depends on AS_HAS_ARMV8_5
|
depends on AS_HAS_ARMV8_5
|
||||||
|
depends on AS_HAS_LSE_ATOMICS
|
||||||
# Required for tag checking in the uaccess routines
|
# Required for tag checking in the uaccess routines
|
||||||
depends on ARM64_PAN
|
depends on ARM64_PAN
|
||||||
select ARCH_USES_HIGH_VMA_FLAGS
|
select ARCH_USES_HIGH_VMA_FLAGS
|
||||||
|
@ -148,16 +148,18 @@ alternative_cb_end
|
|||||||
.endm
|
.endm
|
||||||
|
|
||||||
/* Check for MTE asynchronous tag check faults */
|
/* Check for MTE asynchronous tag check faults */
|
||||||
.macro check_mte_async_tcf, flgs, tmp
|
.macro check_mte_async_tcf, tmp, ti_flags
|
||||||
#ifdef CONFIG_ARM64_MTE
|
#ifdef CONFIG_ARM64_MTE
|
||||||
|
.arch_extension lse
|
||||||
alternative_if_not ARM64_MTE
|
alternative_if_not ARM64_MTE
|
||||||
b 1f
|
b 1f
|
||||||
alternative_else_nop_endif
|
alternative_else_nop_endif
|
||||||
mrs_s \tmp, SYS_TFSRE0_EL1
|
mrs_s \tmp, SYS_TFSRE0_EL1
|
||||||
tbz \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
|
tbz \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
|
||||||
/* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
|
/* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
|
||||||
orr \flgs, \flgs, #_TIF_MTE_ASYNC_FAULT
|
mov \tmp, #_TIF_MTE_ASYNC_FAULT
|
||||||
str \flgs, [tsk, #TSK_TI_FLAGS]
|
add \ti_flags, tsk, #TSK_TI_FLAGS
|
||||||
|
stset \tmp, [\ti_flags]
|
||||||
msr_s SYS_TFSRE0_EL1, xzr
|
msr_s SYS_TFSRE0_EL1, xzr
|
||||||
1:
|
1:
|
||||||
#endif
|
#endif
|
||||||
@ -244,7 +246,7 @@ alternative_else_nop_endif
|
|||||||
disable_step_tsk x19, x20
|
disable_step_tsk x19, x20
|
||||||
|
|
||||||
/* Check for asynchronous tag check faults in user space */
|
/* Check for asynchronous tag check faults in user space */
|
||||||
check_mte_async_tcf x19, x22
|
check_mte_async_tcf x22, x23
|
||||||
apply_ssbd 1, x22, x23
|
apply_ssbd 1, x22, x23
|
||||||
|
|
||||||
ptrauth_keys_install_kernel tsk, x20, x22, x23
|
ptrauth_keys_install_kernel tsk, x20, x22, x23
|
||||||
|
Loading…
Reference in New Issue
Block a user