From: "Pierre-Clément Tosi" <ptosi@google.com>
To: Catalin Marinas <catalin.marinas@arm.com>, Will Deacon <will@kernel.org>
Cc: "Mark Rutland" <mark.rutland@arm.com>,
"Vincenzo Frascino" <vincenzo.frascino@arm.com>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org,
"Pierre-Clément Tosi" <ptosi@google.com>
Subject: [PATCH 17/24] arm64: Introduce MTE & KASAN tag handling helpers
Date: Sat, 07 Nov 2026 16:36:23 +0100 [thread overview]
Message-ID: <20261107-mte-kasan-split-v1-17-d84ea5f30f94@google.com> (raw)
In-Reply-To: <20261107-mte-kasan-split-v1-0-d84ea5f30f94@google.com>
Introduce [__]mte_{tagged,tag_of}() helpers for MTE tags.
Use a naming convention which clearly indicates that the helpers are
dealing with the tag bits of the argument, as opposed to the tag value
actually associated in hardware with the memory the argument points to.
The get()/set() terminology may imply the latter, and actually is used
in that sense already e.g. mte_get_mem_tag() or mte_set_mem_tag_range().
Provide a const-compatible ("__"-prefixed) variant and type-checked
functions, these should provide compile-time validation (with zero
runtime overhead) of constant arguments.
Introduce [__]kasan_tag_{to,from}_mte() helpers for KASAN tags.
Here, the "__"-prefixed variants are asm-compatible.
Signed-off-by: Pierre-Clément Tosi <ptosi@google.com>
---
arch/arm64/include/asm/mte-def.h | 20 ++++++++++++++++++++
arch/arm64/include/asm/mte-kasan.h | 29 +++++++++++++++++++++--------
arch/arm64/mm/fault.c | 2 +-
3 files changed, 42 insertions(+), 9 deletions(-)
diff --git a/arch/arm64/include/asm/mte-def.h b/arch/arm64/include/asm/mte-def.h
index 14ee86b019c2..660948a3fa9c 100644
--- a/arch/arm64/include/asm/mte-def.h
+++ b/arch/arm64/include/asm/mte-def.h
@@ -15,4 +15,24 @@
#define __MTE_PREAMBLE ARM64_ASM_PREAMBLE ".arch_extension memtag\n"
+#ifndef __ASSEMBLER__
+
+#include <linux/bitfield.h>
+#include <linux/types.h>
+
+#define __mte_tag_of(addr) FIELD_GET(MTE_TAG_MASK, addr)
+#define __mte_tagged(addr, tag) u64_replace_bits(addr, tag, MTE_TAG_MASK)
+
+static __always_inline u8 mte_tag_of(const void *ptr)
+{
+ return __mte_tag_of((u64)ptr);
+}
+
+static __always_inline void *mte_tagged(const void *ptr, u8 tag)
+{
+ return (void *)__mte_tagged((u64)ptr, tag);
+}
+
+#endif /* __ASSEMBLER__ */
+
#endif /* __ASM_MTE_DEF_H */
diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h
index 6f63c788470a..24d5d9d6d04b 100644
--- a/arch/arm64/include/asm/mte-kasan.h
+++ b/arch/arm64/include/asm/mte-kasan.h
@@ -13,24 +13,40 @@
#include <asm/cputype.h>
#include <asm/mte-def.h>
+#define __KASAN_TAG_MTE_MASK GENMASK(MTE_TAG_SIZE - 1, 0)
/*
* KASAN always uses a whole byte for its tags. With CONFIG_KASAN_HW_TAGS it
* only uses tags in the range 0xF0-0xFF, which we map to MTE tags 0x0-0xF.
*/
+#define __kasan_tag_to_mte(tag) ((tag) & __KASAN_TAG_MTE_MASK)
+#define __kasan_tag_from_mte(tag) ((KASAN_TAG_MIN & ~__KASAN_TAG_MTE_MASK) | (tag))
+
#ifdef CONFIG_KASAN_HW_TAGS
-#define __MTE_TAG_MIN (KASAN_TAG_MIN & 0xf)
-#define __MTE_TAG_MAX (KASAN_TAG_MAX & 0xf)
-#define KASAN_GCR_INCL GENMASK(__MTE_TAG_MAX, __MTE_TAG_MIN)
+#define KASAN_GCR_INCL \
+ GENMASK(__kasan_tag_to_mte(KASAN_TAG_MAX), __kasan_tag_to_mte(KASAN_TAG_MIN))
#else
#define KASAN_GCR_INCL UL(0)
#endif
#ifndef __ASSEMBLER__
+#include <linux/bitfield.h>
#include <linux/types.h>
#include <asm/sysreg.h>
+#define KASAN_TAG_MTE_MASK GENMASK_U8(MTE_TAG_SIZE - 1, 0)
+
+static __always_inline u8 kasan_tag_to_mte(u8 tag)
+{
+ return u8_get_bits(tag, KASAN_TAG_MTE_MASK);
+}
+
+static __always_inline u8 kasan_tag_from_mte(u8 tag)
+{
+ return u8_replace_bits(KASAN_TAG_MIN, tag, KASAN_TAG_MTE_MASK);
+}
+
#ifdef CONFIG_KASAN_HW_TAGS
/* Whether the MTE asynchronous mode is enabled. */
@@ -71,10 +87,7 @@ static inline void mte_enable_tco(void)
static inline u8 mte_get_ptr_tag(void *ptr)
{
- /* Note: The format of KASAN tags is 0xF<x> */
- u8 tag = 0xF0 | (u8)(((u64)(ptr)) >> MTE_TAG_SHIFT);
-
- return tag;
+ return kasan_tag_from_mte(mte_tag_of(ptr));
}
/* Get allocation tag for the address. */
@@ -140,7 +153,7 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag,
dczid_bs = 4ul << (dczid & 0xf);
dczid_dzp = (dczid >> 4) & 1;
- curr = (u64)__tag_set(addr, tag);
+ curr = (u64)mte_tagged(addr, kasan_tag_to_mte(tag));
mask = dczid_bs - 1;
/* STG/STZG up to the end of the first block. */
end1 = curr | mask;
diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
index b22736853fcd..cf855aa1c30f 100644
--- a/arch/arm64/mm/fault.c
+++ b/arch/arm64/mm/fault.c
@@ -915,7 +915,7 @@ static int do_tag_check_fault(unsigned long far, unsigned long esr,
* Otherwise, bits 63:60 of FAR_EL1 are not UNKNOWN.
*/
if (!cpus_have_cap(ARM64_MTE_FAR))
- far = (__untagged_addr(far) & ~MTE_TAG_MASK) | (far & MTE_TAG_MASK);
+ far = __mte_tagged(__untagged_addr(far), __mte_tag_of(far));
do_bad_area(far, esr, regs);
return 0;
--
2.56.0.455.g6c5a503b38-goog
next prev parent reply other threads:[~2026-11-07 15:37 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
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-07 15:36 ` [PATCH 02/24] kselftest/arm64: Test lazy PSTATE.TCO handling Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 03/24] arm64: Fix volatility of IRG inline assembly Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 04/24] arm64: Skip TCO on privileged uaccess without kMTE Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 05/24] arm64: Check MTE once per fault-handling section Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 06/24] arm64: Harden is_ttbr1_addr() on tagged addresses Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 07/24] arm64: Skip redundant TCO clear post-kernel entry Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 08/24] arm64: Introduce mte_get_reset_tfsr() helpers Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 09/24] kasan: rework hw_{force=>flush}_async_tag_fault() Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 10/24] kasan: rework hw_{get=>set}_random_tag() Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 11/24] kasan: provide empty stub for kasan_report_async() Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 12/24] kasan: drop mte-kasan.h from arch-agnostic header Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 13/24] arm64: Introduce set_pstate_tco() helper macro Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 14/24] arm64: Add mte_{enter,exit}_*_{kernel,user}_mode() Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 16/24] arm64: Refactor KERNEL_GCR_EL1 out of <sysreg.h> Pierre-Clément Tosi
2026-11-07 15:36 ` Pierre-Clément Tosi [this message]
2026-11-07 15:36 ` [PATCH 19/24] arm64: Rework static branches for kernel MTE Pierre-Clément Tosi
2026-11-07 15:36 ` [PATCH 20/24] arm64: Move MTE insn wrappers to <asm/mte-def.h> Pierre-Clément Tosi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261107-mte-kasan-split-v1-17-d84ea5f30f94@google.com \
--to=ptosi@google.com \
--cc=catalin.marinas@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mark.rutland@arm.com \
--cc=vincenzo.frascino@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®