On 2025-09-06 at 19:18:33 +0200, Andrey Konovalov wrote: >On Mon, Aug 25, 2025 at 10:27 PM Maciej Wieczor-Retman ><maciej.wieczor-retman@xxxxxxxxx> wrote: >> >> KASAN's tag-based mode defines multiple special tag values. They're >> reserved for: >> - Native kernel value. On arm64 it's 0xFF and it causes an early return >> in the tag checking function. >> - Invalid value. 0xFE marks an area as freed / unallocated. It's also >> the value that is used to initialize regions of shadow memory. >> - Max value. 0xFD is the highest value that can be randomly generated >> for a new tag. >> >> Metadata macro is also defined: >> - Tag width equal to 8. >> >> Tag-based mode on x86 is going to use 4 bit wide tags so all the above >> values need to be changed accordingly. >> >> Make native kernel tag arch specific for x86 and arm64. >> >> Replace hardcoded kernel tag value and tag width with macros in KASAN's >> non-arch specific code. >> >> Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@xxxxxxxxx> >> --- >> Changelog v5: >> - Move KASAN_TAG_MIN to the arm64 kasan-tags.h for the hardware KASAN >> mode case. >> >> Changelog v4: >> - Move KASAN_TAG_MASK to kasan-tags.h. >> >> Changelog v2: >> - Remove risc-v from the patch. >> >> MAINTAINERS | 2 +- >> arch/arm64/include/asm/kasan-tags.h | 13 +++++++++++++ >> arch/arm64/include/asm/kasan.h | 4 ---- >> arch/x86/include/asm/kasan-tags.h | 9 +++++++++ >> include/linux/kasan-tags.h | 10 +++++++++- >> include/linux/kasan.h | 4 +++- >> include/linux/mm.h | 6 +++--- >> include/linux/mmzone.h | 1 - >> include/linux/page-flags-layout.h | 9 +-------- >> 9 files changed, 39 insertions(+), 19 deletions(-) >> create mode 100644 arch/arm64/include/asm/kasan-tags.h >> create mode 100644 arch/x86/include/asm/kasan-tags.h >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index fed6cd812d79..788532771832 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -13176,7 +13176,7 @@ L: kasan-dev@xxxxxxxxxxxxxxxx >> S: Maintained >> B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management >> F: Documentation/dev-tools/kasan.rst >> -F: arch/*/include/asm/*kasan.h >> +F: arch/*/include/asm/*kasan*.h >> F: arch/*/mm/kasan_init* >> F: include/linux/kasan*.h >> F: lib/Kconfig.kasan >> diff --git a/arch/arm64/include/asm/kasan-tags.h b/arch/arm64/include/asm/kasan-tags.h >> new file mode 100644 >> index 000000000000..152465d03508 >> --- /dev/null >> +++ b/arch/arm64/include/asm/kasan-tags.h >> @@ -0,0 +1,13 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +#ifndef __ASM_KASAN_TAGS_H >> +#define __ASM_KASAN_TAGS_H >> + >> +#define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ >> + >> +#define KASAN_TAG_WIDTH 8 >> + >> +#ifdef CONFIG_KASAN_HW_TAGS >> +#define KASAN_TAG_MIN 0xF0 /* minimum value for random tags */ >> +#endif >> + >> +#endif /* ASM_KASAN_TAGS_H */ >> diff --git a/arch/arm64/include/asm/kasan.h b/arch/arm64/include/asm/kasan.h >> index 4ab419df8b93..d2841e0fb908 100644 >> --- a/arch/arm64/include/asm/kasan.h >> +++ b/arch/arm64/include/asm/kasan.h >> @@ -7,10 +7,6 @@ >> #include <linux/linkage.h> >> #include <asm/memory.h> >> >> -#ifdef CONFIG_KASAN_HW_TAGS >> -#define KASAN_TAG_MIN 0xF0 /* minimum value for random tags */ >> -#endif >> - >> #define arch_kasan_set_tag(addr, tag) __tag_set(addr, tag) >> #define arch_kasan_reset_tag(addr) __tag_reset(addr) >> #define arch_kasan_get_tag(addr) __tag_get(addr) >> diff --git a/arch/x86/include/asm/kasan-tags.h b/arch/x86/include/asm/kasan-tags.h >> new file mode 100644 >> index 000000000000..68ba385bc75c >> --- /dev/null >> +++ b/arch/x86/include/asm/kasan-tags.h >> @@ -0,0 +1,9 @@ >> +/* SPDX-License-Identifier: GPL-2.0 */ >> +#ifndef __ASM_KASAN_TAGS_H >> +#define __ASM_KASAN_TAGS_H >> + >> +#define KASAN_TAG_KERNEL 0xF /* native kernel pointers tag */ >> + >> +#define KASAN_TAG_WIDTH 4 >> + >> +#endif /* ASM_KASAN_TAGS_H */ >> diff --git a/include/linux/kasan-tags.h b/include/linux/kasan-tags.h >> index e07c896f95d3..fe80fa8f3315 100644 >> --- a/include/linux/kasan-tags.h >> +++ b/include/linux/kasan-tags.h >> @@ -2,7 +2,15 @@ >> #ifndef _LINUX_KASAN_TAGS_H >> #define _LINUX_KASAN_TAGS_H >> >> -#include <asm/kasan.h> >> +#if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS) >> +#include <asm/kasan-tags.h> >> +#endif >> + >> +#ifndef KASAN_TAG_WIDTH >> +#define KASAN_TAG_WIDTH 0 >> +#endif >> + >> +#define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1) >> >> #ifndef KASAN_TAG_KERNEL >> #define KASAN_TAG_KERNEL 0xFF /* native kernel pointers tag */ >> diff --git a/include/linux/kasan.h b/include/linux/kasan.h >> index b396feca714f..54481f8c30c5 100644 >> --- a/include/linux/kasan.h >> +++ b/include/linux/kasan.h >> @@ -40,7 +40,9 @@ typedef unsigned int __bitwise kasan_vmalloc_flags_t; >> >> #ifdef CONFIG_KASAN_SW_TAGS >> /* This matches KASAN_TAG_INVALID. */ >> -#define KASAN_SHADOW_INIT 0xFE >> +#ifndef KASAN_SHADOW_INIT > >Do we need this ifndef? I just checked and you're right, it's not needed. I think it might have been a leftover of my dense mode code. > >> +#define KASAN_SHADOW_INIT KASAN_TAG_INVALID >> +#endif >> #else >> #define KASAN_SHADOW_INIT 0 >> #endif >> diff --git a/include/linux/mm.h b/include/linux/mm.h >> index 1ae97a0b8ec7..bb494cb1d5af 100644 >> --- a/include/linux/mm.h >> +++ b/include/linux/mm.h >> @@ -1692,7 +1692,7 @@ static inline u8 page_kasan_tag(const struct page *page) >> >> if (kasan_enabled()) { >> tag = (page->flags >> KASAN_TAG_PGSHIFT) & KASAN_TAG_MASK; >> - tag ^= 0xff; >> + tag ^= KASAN_TAG_KERNEL; >> } >> >> return tag; >> @@ -1705,7 +1705,7 @@ static inline void page_kasan_tag_set(struct page *page, u8 tag) >> if (!kasan_enabled()) >> return; >> >> - tag ^= 0xff; >> + tag ^= KASAN_TAG_KERNEL; >> old_flags = READ_ONCE(page->flags); >> do { >> flags = old_flags; >> @@ -1724,7 +1724,7 @@ static inline void page_kasan_tag_reset(struct page *page) >> >> static inline u8 page_kasan_tag(const struct page *page) >> { >> - return 0xff; >> + return KASAN_TAG_KERNEL; >> } >> >> static inline void page_kasan_tag_set(struct page *page, u8 tag) { } >> diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h >> index 0c5da9141983..c139fb3d862d 100644 >> --- a/include/linux/mmzone.h >> +++ b/include/linux/mmzone.h >> @@ -1166,7 +1166,6 @@ static inline bool zone_is_empty(struct zone *zone) >> #define NODES_MASK ((1UL << NODES_WIDTH) - 1) >> #define SECTIONS_MASK ((1UL << SECTIONS_WIDTH) - 1) >> #define LAST_CPUPID_MASK ((1UL << LAST_CPUPID_SHIFT) - 1) >> -#define KASAN_TAG_MASK ((1UL << KASAN_TAG_WIDTH) - 1) > >So we cannot define this here because of include dependencies? Having >this value defined here would look cleaner. > >Otherwise, let's add a comment here with a reference to where this >value is defined. I'll retest with a couple of configs but I removed this change and everything compile fine. Thanks for noticing that > >> #define ZONEID_MASK ((1UL << ZONEID_SHIFT) - 1) >> >> static inline enum zone_type page_zonenum(const struct page *page) >> diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-layout.h >> index 760006b1c480..b2cc4cb870e0 100644 >> --- a/include/linux/page-flags-layout.h >> +++ b/include/linux/page-flags-layout.h >> @@ -3,6 +3,7 @@ >> #define PAGE_FLAGS_LAYOUT_H >> >> #include <linux/numa.h> >> +#include <linux/kasan-tags.h> >> #include <generated/bounds.h> >> >> /* >> @@ -72,14 +73,6 @@ >> #define NODE_NOT_IN_PAGE_FLAGS 1 >> #endif >> >> -#if defined(CONFIG_KASAN_SW_TAGS) >> -#define KASAN_TAG_WIDTH 8 >> -#elif defined(CONFIG_KASAN_HW_TAGS) >> -#define KASAN_TAG_WIDTH 4 > >This case is removed here but not added to arch/arm64/include/asm/kasan-tags.h. Right, I'll correct that. > > >> -#else >> -#define KASAN_TAG_WIDTH 0 >> -#endif >> - >> #ifdef CONFIG_NUMA_BALANCING >> #define LAST__PID_SHIFT 8 >> #define LAST__PID_MASK ((1 << LAST__PID_SHIFT)-1) >> -- >> 2.50.1 >> -- Kind regards Maciej Wieczór-Retman