[PATCH 14/24] arm64: Add mte_{enter,exit}_*_{kernel,user}_mode()

From: Pierre-Clément Tosi

Date: Sat Nov 07 2026 - 10:51:43 EST


Abstract away and consolidate MTE switching code by aligning with the
concepts and naming from entry-common.c, similarly to the SME routines.

Define the helpers in entry-common.c, conveniently grouped for more
straightforward enter-exit logic pair evaluation.

Signed-off-by: Pierre-Clément Tosi <ptosi@xxxxxxxxxx>
---
arch/arm64/kernel/entry-common.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c
index 11d3f888fcd8..fbf9bafc6962 100644
--- a/arch/arm64/kernel/entry-common.c
+++ b/arch/arm64/kernel/entry-common.c
@@ -25,6 +25,7 @@
#include <asm/irq_regs.h>
#include <asm/kprobes.h>
#include <asm/mmu.h>
+#include <asm/mte.h>
#include <asm/percpu.h>
#include <asm/processor.h>
#include <asm/sdei.h>
@@ -68,6 +69,27 @@ static __always_inline void irqentry_exit_pcpu_adjust(struct pt_regs *regs)
pt_regs_write_reg(regs, reg_addr, addr);
}

+static __always_inline void mte_enter_from_kernel_mode(void)
+{
+ mte_check_tfsr_entry();
+ mte_disable_tco_entry(current);
+}
+
+static __always_inline void mte_exit_to_kernel_mode(void)
+{
+ mte_check_tfsr_exit();
+}
+
+static __always_inline void mte_enter_from_user_mode(void)
+{
+ mte_disable_tco_entry(current);
+}
+
+static __always_inline void mte_exit_to_user_mode(void)
+{
+ mte_check_tfsr_exit();
+}
+
/*
* Handle IRQ/context state management when entering from kernel mode.
* Before this function is called it is not safe to call regular kernel code,
@@ -78,8 +100,7 @@ static noinstr irqentry_state_t arm64_enter_from_kernel_mode(struct pt_regs *reg
irqentry_state_t state;

state = irqentry_enter_from_kernel_mode(regs);
- mte_check_tfsr_entry();
- mte_disable_tco_entry(current);
+ mte_enter_from_kernel_mode();

return state;
}
@@ -94,7 +115,7 @@ static void noinstr __arm64_exit_to_kernel_mode(struct pt_regs *regs,
{
local_daif_mask();
irqentry_exit_pcpu_adjust(regs);
- mte_check_tfsr_exit();
+ mte_exit_to_kernel_mode();
irqentry_exit_to_kernel_mode_after_preempt(regs, state);
}

@@ -123,7 +144,7 @@ static void noinstr arm64_exit_to_kernel_mode(struct pt_regs *regs,
static __always_inline void arm64_syscall_enter_from_user_mode(struct pt_regs *regs)
{
enter_from_user_mode(regs);
- mte_disable_tco_entry(current);
+ mte_enter_from_user_mode();
sme_enter_from_user_mode();
}

@@ -136,7 +157,7 @@ static __always_inline void arm64_enter_from_user_mode(struct pt_regs *regs)
{
enter_from_user_mode(regs);
rseq_note_user_irq_entry();
- mte_disable_tco_entry(current);
+ mte_enter_from_user_mode();
sme_enter_from_user_mode();
}

@@ -146,7 +167,7 @@ static __always_inline void arm64_syscall_exit_to_user_mode(struct pt_regs *regs
syscall_exit_to_user_mode_prepare(regs);
local_daif_mask();
sme_exit_to_user_mode();
- mte_check_tfsr_exit();
+ mte_exit_to_user_mode();
exit_to_user_mode();
}

@@ -161,7 +182,7 @@ static __always_inline void arm64_exit_to_user_mode(struct pt_regs *regs)
irqentry_exit_to_user_mode_prepare(regs);
local_daif_mask();
sme_exit_to_user_mode();
- mte_check_tfsr_exit();
+ mte_exit_to_user_mode();
exit_to_user_mode();
}


--
2.56.0.455.g6c5a503b38-goog