Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

arm64: add MTE supported check to thread switching and syscall entry/exit

This lets us avoid doing unnecessary work on hardware that does not
support MTE, and will allow us to freely use MTE instructions in the
code called by mte_thread_switch().

Since this would mean that we do a redundant check in
mte_check_tfsr_el1(), remove it and add two checks now required in its
callers. This also avoids an unnecessary DSB+ISB sequence on the syscall
exit path for hardware not supporting MTE.

Fixes: 65812c6921cc ("arm64: mte: Enable async tag check fault")
Cc: <stable@vger.kernel.org> # 5.13.x
Signed-off-by: Peter Collingbourne <pcc@google.com>
Link: https://linux-review.googlesource.com/id/I02fd000d1ef2c86c7d2952a7f099b254ec227a5d
Link: https://lore.kernel.org/r/20210915190336.398390-1-pcc@google.com
[catalin.marinas@arm.com: adjust the commit log slightly]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Peter Collingbourne and committed by
Catalin Marinas
8c8a3b5b 9fcb2e93

+10 -6
+6
arch/arm64/include/asm/mte.h
··· 99 99 100 100 static inline void mte_check_tfsr_entry(void) 101 101 { 102 + if (!system_supports_mte()) 103 + return; 104 + 102 105 mte_check_tfsr_el1(); 103 106 } 104 107 105 108 static inline void mte_check_tfsr_exit(void) 106 109 { 110 + if (!system_supports_mte()) 111 + return; 112 + 107 113 /* 108 114 * The asynchronous faults are sync'ed automatically with 109 115 * TFSR_EL1 on kernel entry but for exit an explicit dsb()
+4 -6
arch/arm64/kernel/mte.c
··· 142 142 #ifdef CONFIG_KASAN_HW_TAGS 143 143 void mte_check_tfsr_el1(void) 144 144 { 145 - u64 tfsr_el1; 146 - 147 - if (!system_supports_mte()) 148 - return; 149 - 150 - tfsr_el1 = read_sysreg_s(SYS_TFSR_EL1); 145 + u64 tfsr_el1 = read_sysreg_s(SYS_TFSR_EL1); 151 146 152 147 if (unlikely(tfsr_el1 & SYS_TFSR_EL1_TF1)) { 153 148 /* ··· 194 199 195 200 void mte_thread_switch(struct task_struct *next) 196 201 { 202 + if (!system_supports_mte()) 203 + return; 204 + 197 205 mte_update_sctlr_user(next); 198 206 199 207 /*