OSDN Git Service

arm64: mte: Ensure TIF_MTE_ASYNC_FAULT is set atomically
authorCatalin Marinas <catalin.marinas@arm.com>
Fri, 9 Apr 2021 17:37:10 +0000 (18:37 +0100)
committerWill Deacon <will@kernel.org>
Mon, 12 Apr 2021 12:38:45 +0000 (13:38 +0100)
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: 637ec831ea4f ("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>
arch/arm64/Kconfig
arch/arm64/kernel/entry.S

index e4e1b65..dfdc3e0 100644 (file)
@@ -1406,10 +1406,13 @@ config ARM64_PAN
 config AS_HAS_LDAPR
        def_bool $(as-instr,.arch_extension rcpc)
 
+config AS_HAS_LSE_ATOMICS
+       def_bool $(as-instr,.arch_extension lse)
+
 config ARM64_LSE_ATOMICS
        bool
        default ARM64_USE_LSE_ATOMICS
-       depends on $(as-instr,.arch_extension lse)
+       depends on AS_HAS_LSE_ATOMICS
 
 config ARM64_USE_LSE_ATOMICS
        bool "Atomic instructions"
@@ -1666,6 +1669,7 @@ config ARM64_MTE
        default y
        depends on ARM64_AS_HAS_MTE && ARM64_TAGGED_ADDR_ABI
        depends on AS_HAS_ARMV8_5
+       depends on AS_HAS_LSE_ATOMICS
        # Required for tag checking in the uaccess routines
        depends on ARM64_PAN
        select ARCH_USES_HIGH_VMA_FLAGS
index a31a0a7..6acfc5e 100644 (file)
@@ -148,16 +148,18 @@ alternative_cb_end
        .endm
 
        /* 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
+       .arch_extension lse
 alternative_if_not ARM64_MTE
        b       1f
 alternative_else_nop_endif
        mrs_s   \tmp, SYS_TFSRE0_EL1
        tbz     \tmp, #SYS_TFSR_EL1_TF0_SHIFT, 1f
        /* Asynchronous TCF occurred for TTBR0 access, set the TI flag */
-       orr     \flgs, \flgs, #_TIF_MTE_ASYNC_FAULT
-       str     \flgs, [tsk, #TSK_TI_FLAGS]
+       mov     \tmp, #_TIF_MTE_ASYNC_FAULT
+       add     \ti_flags, tsk, #TSK_TI_FLAGS
+       stset   \tmp, [\ti_flags]
        msr_s   SYS_TFSRE0_EL1, xzr
 1:
 #endif
@@ -244,7 +246,7 @@ alternative_else_nop_endif
        disable_step_tsk x19, x20
 
        /* 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
 
        ptrauth_keys_install_kernel tsk, x20, x22, x23