* [PATCH 00/24] arm64: Decouple MTE code from KASAN support
@ 2026-11-07 15:36 Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE Pierre-Clément Tosi
0 siblings, 1 reply; 5+ messages in thread
From: Pierre-Clément Tosi @ 2026-11-07 15:36 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: Mark Rutland, Vincenzo Frascino, linux-arm-kernel, linux-kernel,
Peter Collingbourne, stable, Pierre-Clément Tosi, Shuah Khan,
linux-kselftest, Alexander Potapenko, Andrew Morton,
Andrey Konovalov, Andrey Ryabinin, Dmitry Vyukov, kasan-dev,
linux-mm
MTE is a hardware feature, KASAN is software infrastructure.
The direction of the dependency should be clear: KASAN uses MTE.
However, the code does not reflect this split: many mte_*() functions
are actually only intended for HW_TAGS such that there is no way to make
use of in-kernel MTE functionality without enabling KASAN. Furthermore,
there is a lot of unnecessary indirection in those functions, causing
duplication, code that is harder to follow than it should be, and making
it easier for subtle inconsistencies to hide.
Instead, this series aims to untangle the two into a set of reusable,
arch-level MTE functions and a thin wrapper around them that KASAN
needs. For non-KASAN MTE-related code, instead of attempting to reuse
KASAN functions, break out individual MTE primitives into KASAN-agnostic
functions and use them where needed by aligning in style with how other
features are supported e.g. during kernel entry/exit.
The result of this rework made some bugs and inefficiencies obvious so
I ordered the patches into 3 sets: first, bug fixes, then, functional
improvements, and finally the refactor. Specifically:
- patch 1 fixes a bug in the support for userspace MTE, with a kselftest
reproducer in patch 2
- patch 3 fixes an unsound inline asm statement
- patches 4-7 address inefficiencies in PSTATE.TCO-guarded sections, TCO
lazy clearing, and harden TTBR1 address categorization
- patches 9-12 rework MTE-specific code in arch-agnostic KASAN, with an
arch-level early refactor in patch 8 to keep those minimal
- patches 13-23 then proceed with the methodical untangling of MTE
from KASAN, leaving only a thin KASAN_HW_TAGS wrapper in <asm/kasan.h>
- patch 24 introduces a hidden Kconfig flag ARM64_MTE_KERNEL, to better
document in the code when logic is required for EL1 MTE, as opposed to
KASAN
This was tested on v7.4-rc1 and applies cleanly to arm64 for-next/core
at commit f46be4da2cbb ("selftests/arm64: GCS must not leak on a failed
clone3").
The following checkpatch.pl errors are consciously ignored:
- "WARNING: ... does MAINTAINERS need updating?" on patch 2 for the
new kselftest but selftests/arm64/ is already properly maintained
- "WARNING: Macros with flow control statements should be avoided" on
patch 5 but the new __raw_{get,put}_mem_tco() macros are intentionally
consistent in style with the pre-existing __raw_{get,put}_mem()
while the other warnings/error are false-positives I fix in [1] and [2].
[1]: https://lore.kernel.org/r/20261107-checkpatch-asm-complex_macro-v1-1-9a7b3c69fc28@google.com
[2]: https://lore.kernel.org/r/20261107-checkpatch-file_path_changes-v1-1-8b11814560d8@google.com
---
Pierre-Clément Tosi (24):
arm64: Fix lazy TCO clear when enabling user MTE
kselftest/arm64: Test lazy PSTATE.TCO handling
arm64: Fix volatility of IRG inline assembly
arm64: Skip TCO on privileged uaccess without kMTE
arm64: Check MTE once per fault-handling section
arm64: Harden is_ttbr1_addr() on tagged addresses
arm64: Skip redundant TCO clear post-kernel entry
arm64: Introduce mte_get_reset_tfsr() helpers
kasan: rework hw_{force=>flush}_async_tag_fault()
kasan: rework hw_{get=>set}_random_tag()
kasan: provide empty stub for kasan_report_async()
kasan: drop mte-kasan.h from arch-agnostic header
arm64: Introduce set_pstate_tco() helper macro
arm64: Add mte_{enter,exit}_*_{kernel,user}_mode()
arm64: Refactor and remove mte_disable_tco_entry()
arm64: Refactor KERNEL_GCR_EL1 out of <sysreg.h>
arm64: Introduce MTE & KASAN tag handling helpers
arm64: Inline and remove mte_check_tfsr_*()
arm64: Rework static branches for kernel MTE
arm64: Move MTE insn wrappers to <asm/mte-def.h>
arm64: Introduce mte_tag[_and_zero]_range()
arm64: Consolidate MTE-based KASAN in mte-kasan.h
arm64: Fold <asm/mte-kasan.h> into <asm/kasan.h>
arm64: Introduce CONFIG_ARM64_MTE_KERNEL
MAINTAINERS | 2 +-
arch/arm64/Kconfig | 8 +
arch/arm64/include/asm/kasan.h | 103 +++++++-
arch/arm64/include/asm/memory.h | 14 --
arch/arm64/include/asm/mte-def.h | 65 +++++
arch/arm64/include/asm/mte-kasan.h | 266 ---------------------
arch/arm64/include/asm/mte.h | 189 ++++++++++-----
arch/arm64/include/asm/processor.h | 6 +-
arch/arm64/include/asm/sysreg.h | 17 +-
arch/arm64/include/asm/uaccess.h | 106 +++++---
arch/arm64/include/asm/word-at-a-time.h | 22 +-
arch/arm64/kernel/entry-common.c | 58 ++++-
arch/arm64/kernel/entry.S | 3 +-
arch/arm64/kernel/mte.c | 72 +++---
arch/arm64/lib/strlen.S | 4 +-
arch/arm64/mm/copypage.c | 1 +
arch/arm64/mm/fault.c | 2 +-
include/linux/kasan.h | 8 +-
mm/kasan/hw_tags.c | 3 +-
mm/kasan/kasan.h | 14 +-
tools/testing/selftests/arm64/mte/.gitignore | 1 +
tools/testing/selftests/arm64/mte/check_lazy_tco.c | 152 ++++++++++++
22 files changed, 649 insertions(+), 467 deletions(-)
---
base-commit: 6628e7d4c6b25c8d18f1345e3a20d21829aae7e4
change-id: 20261107-mte-kasan-split-3632e818f997
Best regards,
--
Pierre-Clément Tosi <ptosi@google.com>
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE
2026-11-07 15:36 [PATCH 00/24] arm64: Decouple MTE code from KASAN support Pierre-Clément Tosi
@ 2026-11-07 15:36 ` Pierre-Clément Tosi
2026-11-10 18:33 ` Catalin Marinas
0 siblings, 1 reply; 5+ messages in thread
From: Pierre-Clément Tosi @ 2026-11-07 15:36 UTC (permalink / raw)
To: Catalin Marinas, Will Deacon
Cc: Mark Rutland, Vincenzo Frascino, linux-arm-kernel, linux-kernel,
Peter Collingbourne, stable, Pierre-Clément Tosi
On kernel entry from EL0 with HW KASAN inactive and user MTE disabled or
in async mode, mte_disable_tco_entry() leaves PSTATE.TCO set to avoid an
expensive write, as it assumes that EL1 tag checks are not needed.
However, if the thread is in the process of enabling sync or asymm MTE,
set_mte_ctrl() updates SCTLR_EL1.TCF0 without clearing PSTATE.TCO! As a
result, kernel uaccesses miss tag faults until the next context switch.
Clear TCO in set_mte_ctrl() immediately after setting the task's SCTLR.
Cc: Peter Collingbourne <peter@pcc.me.uk>
Cc: stable@vger.kernel.org
Fixes: 38ddf7dafaea ("arm64: mte: avoid clearing PSTATE.TCO on entry unless necessary")
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
---
arch/arm64/kernel/mte.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm64/kernel/mte.c b/arch/arm64/kernel/mte.c
index 31f5c6b0510e..d1dd9b80173a 100644
--- a/arch/arm64/kernel/mte.c
+++ b/arch/arm64/kernel/mte.c
@@ -409,6 +409,7 @@ long set_mte_ctrl(struct task_struct *task, unsigned long arg)
mte_update_sctlr_user(task);
mte_update_gcr_excl(task);
update_sctlr_el1(task->thread.sctlr_user);
+ mte_disable_tco_entry(task);
preempt_enable();
}
--
2.56.0.455.g6c5a503b38-goog
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE
2026-11-07 15:36 ` [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE Pierre-Clément Tosi
@ 2026-11-10 18:33 ` Catalin Marinas
2026-11-11 8:57 ` Pierre-Clément Tosi
0 siblings, 1 reply; 5+ messages in thread
From: Catalin Marinas @ 2026-11-10 18:33 UTC (permalink / raw)
To: Pierre-Clément Tosi
Cc: Will Deacon, Mark Rutland, Vincenzo Frascino, linux-arm-kernel,
linux-kernel, Peter Collingbourne, stable
On Sat, Nov 07, 2026 at 04:36:07PM +0100, Pierre-Clément Tosi wrote:
> On kernel entry from EL0 with HW KASAN inactive and user MTE disabled or
> in async mode, mte_disable_tco_entry() leaves PSTATE.TCO set to avoid an
> expensive write, as it assumes that EL1 tag checks are not needed.
>
> However, if the thread is in the process of enabling sync or asymm MTE,
> set_mte_ctrl() updates SCTLR_EL1.TCF0 without clearing PSTATE.TCO! As a
> result, kernel uaccesses miss tag faults until the next context switch.
Nit: next context switch or another syscall. I think this makes it
clearer that the only potential missed tag accesses after the prctl() is
a signal frame write as we don't have other uaccesses.
> Clear TCO in set_mte_ctrl() immediately after setting the task's SCTLR.
>
> Cc: Peter Collingbourne <peter@pcc.me.uk>
> Cc: stable@vger.kernel.org
> Fixes: 38ddf7dafaea ("arm64: mte: avoid clearing PSTATE.TCO on entry unless necessary")
> Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
The patch is correct but I wonder whether we need a cc stable.
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE
2026-11-10 18:33 ` Catalin Marinas
@ 2026-11-11 8:57 ` Pierre-Clément Tosi
2026-11-11 9:38 ` Peter Collingbourne
0 siblings, 1 reply; 5+ messages in thread
From: Pierre-Clément Tosi @ 2026-11-11 8:57 UTC (permalink / raw)
To: Catalin Marinas
Cc: Will Deacon, Mark Rutland, Vincenzo Frascino, linux-arm-kernel,
linux-kernel, Peter Collingbourne, stable
Hi Catalin,
On Tue, Nov 10, 2026 at 06:33:20PM +0000, Catalin Marinas wrote:
> On Sat, Nov 07, 2026 at 04:36:07PM +0100, Pierre-Clément Tosi wrote:
> > On kernel entry from EL0 with HW KASAN inactive and user MTE disabled or
> > in async mode, mte_disable_tco_entry() leaves PSTATE.TCO set to avoid an
> > expensive write, as it assumes that EL1 tag checks are not needed.
> >
> > However, if the thread is in the process of enabling sync or asymm MTE,
> > set_mte_ctrl() updates SCTLR_EL1.TCF0 without clearing PSTATE.TCO! As a
> > result, kernel uaccesses miss tag faults until the next context switch.
>
> Nit: next context switch or another syscall. I think this makes it
> clearer that the only potential missed tag accesses after the prctl() is
> a signal frame write as we don't have other uaccesses.
>
> > Clear TCO in set_mte_ctrl() immediately after setting the task's SCTLR.
> >
> > Cc: Peter Collingbourne <peter@pcc.me.uk>
> > Cc: stable@vger.kernel.org
> > Fixes: 38ddf7dafaea ("arm64: mte: avoid clearing PSTATE.TCO on entry unless necessary")
> > Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
>
> The patch is correct but I wonder whether we need a cc stable.
>
> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Thanks for your review.
I'm happy to drop the cc in the next version. The rationale was that this fixed
an unexpected userspace-visible kernel behavior and closed a window during which
tag checks were not performed, which _could_ be a concern when userspace enables
MTE for security. I can see how this doesn't make a strong case for backporting.
--
Pierre
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE
2026-11-11 8:57 ` Pierre-Clément Tosi
@ 2026-11-11 9:38 ` Peter Collingbourne
0 siblings, 0 replies; 5+ messages in thread
From: Peter Collingbourne @ 2026-11-11 9:38 UTC (permalink / raw)
To: Pierre-Clément Tosi
Cc: Catalin Marinas, Will Deacon, Mark Rutland, Vincenzo Frascino,
linux-arm-kernel, linux-kernel, stable
On Wed, Nov 11, 2026 at 12:57 AM Pierre-Clément Tosi <ptosi@google.com> wrote:
>
> Hi Catalin,
>
> On Tue, Nov 10, 2026 at 06:33:20PM +0000, Catalin Marinas wrote:
> > On Sat, Nov 07, 2026 at 04:36:07PM +0100, Pierre-Clément Tosi wrote:
> > > On kernel entry from EL0 with HW KASAN inactive and user MTE disabled or
> > > in async mode, mte_disable_tco_entry() leaves PSTATE.TCO set to avoid an
> > > expensive write, as it assumes that EL1 tag checks are not needed.
> > >
> > > However, if the thread is in the process of enabling sync or asymm MTE,
> > > set_mte_ctrl() updates SCTLR_EL1.TCF0 without clearing PSTATE.TCO! As a
> > > result, kernel uaccesses miss tag faults until the next context switch.
> >
> > Nit: next context switch or another syscall. I think this makes it
> > clearer that the only potential missed tag accesses after the prctl() is
> > a signal frame write as we don't have other uaccesses.
Or any other kernel entry such as signal delivery.
> >
> > > Clear TCO in set_mte_ctrl() immediately after setting the task's SCTLR.
> > >
> > > Cc: Peter Collingbourne <peter@pcc.me.uk>
> > > Cc: stable@vger.kernel.org
> > > Fixes: 38ddf7dafaea ("arm64: mte: avoid clearing PSTATE.TCO on entry unless necessary")
> > > Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
> >
> > The patch is correct but I wonder whether we need a cc stable.
> >
> > Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
>
> Thanks for your review.
>
> I'm happy to drop the cc in the next version. The rationale was that this fixed
> an unexpected userspace-visible kernel behavior and closed a window during which
> tag checks were not performed, which _could_ be a concern when userspace enables
> MTE for security. I can see how this doesn't make a strong case for backporting.
I don't think this needs a cc stable.
I'm also skeptical that this is worth "fixing" at all. All that this
patch does is move the TCO disable slightly earlier in a way that is
almost unobservable except by sending a signal to a process at the
right time. So this patch only has a useful effect if it would
otherwise be somehow possible to compromise a process by taking
advantage of the kernel's signal frame write. Even then it doesn't
really help mitigate anything, it just makes the window of opportunity
slightly smaller.
Peter
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-11-11 9:38 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-07 15:36 [PATCH 00/24] arm64: Decouple MTE code from KASAN support Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 01/24] arm64: Fix lazy TCO clear when enabling user MTE Pierre-Clément Tosi
2026-11-10 18:33 ` Catalin Marinas
2026-11-11 8:57 ` Pierre-Clément Tosi
2026-11-11 9:38 ` Peter Collingbourne
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox