[glibc/arm/malloc-mte-v1] malloc: Remove code conditional on USE_MTAG
Yury Khrustalev via Glibc-cvs <[email protected]> Thu, 7 May 2026 12:45:14 +0000 (GMT)
| Newsgroups | gmane.comp.lib.glibc.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=f33b8e0df533eb5b55c4ee8f1944a4b52a846f6a commit f33b8e0df533eb5b55c4ee8f1944a4b52a846f6a Author: Yury Khrustalev <[email protected]> Date: Wed Apr 22 10:51:24 2026 +0100 malloc: Remove code conditional on USE_MTAG Further malloc refactoring related to memory tagging. Remove code that was only compiled when macro USE_MTAG was defined except for the AArch64-specific assembly MTE code that is going to be compiled unconditionally from now on. As a result, we change 'mtag_mmap_flags' to 'extra_mmap_prot' that is now always defined. Change of the name due to this being used as part of PROT options in mmap syscalls rather than part of flags. Remove 'mtag_enabled' that would become compile-time false. Also remove any code that would never be compiled when 'mtag_enabled' is false. Diff: --- malloc/arena.c | 18 +------ malloc/malloc-check.c | 10 ---- malloc/malloc.c | 73 ++------------------------ sysdeps/aarch64/__mtag_tag_region.S | 3 -- sysdeps/aarch64/__mtag_tag_zero_region.S | 3 -- sysdeps/aarch64/cpu-features.h | 3 +- sysdeps/aarch64/libc-mtag.h | 5 +- sysdeps/unix/sysv/linux/aarch64/cpu-features.c | 28 ---------- 8 files changed, 8 insertions(+), 135 deletions(-) diff --git a/malloc/arena.c b/malloc/arena.c index ddde32c712..023cb3ba06 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -252,20 +252,6 @@ __ptmalloc_init (void) tcache_key_initialize (); #endif -#ifdef USE_MTAG - if ((TUNABLE_GET_FULL (glibc, mem, tagging, int32_t, NULL) & 1) != 0) - { - /* If the tunable says that we should be using tagged memory - and that morecore does not support tagged regions, then - disable it. */ - if (__MTAG_SBRK_UNTAGGED) - __always_fail_morecore = true; - - mtag_enabled = true; - mtag_mmap_flags = __MTAG_MMAP_FLAGS; - } -#endif - #if defined SHARED && IS_IN (libc) /* In case this libc copy is in a non-default namespace, never use brk. Likewise if dlopened from statically linked program. The @@ -417,7 +403,7 @@ alloc_new_heap (size_t size, size_t top_pad, size_t pagesize, } } } - if (__mprotect (p2, size, mtag_mmap_flags | PROT_READ | PROT_WRITE) != 0) + if (__mprotect (p2, size, extra_mmap_prot | PROT_READ | PROT_WRITE) != 0) { __munmap (p2, max_size); return NULL; @@ -471,7 +457,7 @@ grow_heap (heap_info *h, long diff) { if (__mprotect ((char *) h + h->mprotect_size, (unsigned long) new_size - h->mprotect_size, - mtag_mmap_flags | PROT_READ | PROT_WRITE) != 0) + extra_mmap_prot | PROT_READ | PROT_WRITE) != 0) return -2; h->mprotect_size = new_size; diff --git a/malloc/malloc-check.c b/malloc/malloc-check.c index 49b623df12..ae5025d69a 100644 --- a/malloc/malloc-check.c +++ b/malloc/malloc-check.c @@ -217,11 +217,6 @@ free_check (void *mem) int err = errno; - /* Quickly check that the freed pointer matches the tag for the memory. - This gives a useful double-free detection. */ - if (__glibc_unlikely (mtag_enabled)) - *(volatile char *)mem; - __libc_lock_lock (main_arena.mutex); p = mem2chunk_check (mem, NULL); if (!p) @@ -263,11 +258,6 @@ realloc_check (void *oldmem, size_t bytes) return NULL; } - /* Quickly check that the freed pointer matches the tag for the memory. - This gives a useful double-free detection. */ - if (__glibc_unlikely (mtag_enabled)) - *(volatile char *)oldmem; - __libc_lock_lock (main_arena.mutex); const mchunkptr oldp = mem2chunk_check (oldmem, &magic_p); __libc_lock_unlock (main_arena.mutex); diff --git a/malloc/malloc.c b/malloc/malloc.c index 9944290239..d1f452500e 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -405,27 +405,17 @@ verify (PTRDIFF_MAX <= SIZE_MAX / 2); tagging is not enabled, it simply returns the original pointer. */ -#ifdef USE_MTAG -static bool mtag_enabled = false; -static int mtag_mmap_flags = 0; -#else -# define mtag_enabled false -# define mtag_mmap_flags 0 -#endif +static int extra_mmap_prot = 0; static __always_inline void * tag_region (void *ptr, size_t size) { - if (__glibc_unlikely (mtag_enabled)) - return __libc_mtag_tag_region (ptr, size); return ptr; } static __always_inline void * tag_new_zero_region (void *ptr, size_t size) { - if (__glibc_unlikely (mtag_enabled)) - return __libc_mtag_tag_zero_region (__libc_mtag_new_tag (ptr), size); return memset (ptr, 0, size); } @@ -436,8 +426,6 @@ tag_new_usable (void *ptr); static __always_inline void * tag_at (void *ptr) { - if (__glibc_unlikely (mtag_enabled)) - return __libc_mtag_address_get_tag (ptr); return ptr; } @@ -1261,23 +1249,6 @@ checked_request2size (size_t req) __nonnull (1) { if (__glibc_unlikely (req > PTRDIFF_MAX)) return SIZE_MAX; - - /* When using tagged memory, we cannot share the end of the user - block with the header for the next chunk, so ensure that we - allocate blocks that are rounded up to the granule size. Take - care not to overflow from close to MAX_SIZE_T to a small - number. Ideally, this would be part of request2size(), but that - must be a macro that produces a compile time constant if passed - a constant literal. */ - if (__glibc_unlikely (mtag_enabled)) - { - /* Ensure this is not evaluated if !mtag_enabled, see gcc PR 99551. */ - asm (""); - - req = (req + (__MTAG_GRANULE_SIZE - 1)) & - ~(size_t)(__MTAG_GRANULE_SIZE - 1); - } - return request2size (req); } @@ -1380,25 +1351,11 @@ checked_request2size (size_t req) __nonnull (1) /* This is the size of the real usable data in the chunk. Not valid for dumped heap chunks. */ -#define memsize(p) \ - (__MTAG_GRANULE_SIZE > SIZE_SZ && __glibc_unlikely (mtag_enabled) ? \ - chunksize (p) - CHUNK_HDR_SZ : \ - chunksize (p) - CHUNK_HDR_SZ + SIZE_SZ) - -/* If memory tagging is enabled the layout changes to accommodate the granule - size, this is wasteful for small allocations so not done by default. - Both the chunk header and user data has to be granule aligned. */ -_Static_assert (__MTAG_GRANULE_SIZE <= CHUNK_HDR_SZ, - "memory tagging is not supported with large granule."); +#define memsize(p) (chunksize (p) - CHUNK_HDR_SZ + SIZE_SZ) static __always_inline void * tag_new_usable (void *ptr) { - if (__glibc_unlikely (mtag_enabled) && ptr) - { - mchunkptr cp = mem2chunk(ptr); - ptr = __libc_mtag_tag_region (__libc_mtag_new_tag (ptr), memsize (cp)); - } return ptr; } @@ -2235,7 +2192,7 @@ sysmalloc_mmap (INTERNAL_SIZE_T nb, size_t pagesize, int extra_flags) size_t size = ALIGN_UP (nb + padding + CHUNK_HDR_SZ, pagesize); char *mm = (char *) MMAP (NULL, size, - mtag_mmap_flags | PROT_READ | PROT_WRITE, + extra_mmap_prot | PROT_READ | PROT_WRITE, extra_flags); if (mm == MAP_FAILED) return mm; @@ -2276,7 +2233,7 @@ sysmalloc_mmap_fallback (size_t *s, size_t size, size_t minsize, size = minsize; char *mbrk = (char *) (MMAP (NULL, size, - mtag_mmap_flags | PROT_READ | PROT_WRITE, + extra_mmap_prot | PROT_READ | PROT_WRITE, extra_flags)); if (mbrk == MAP_FAILED) return MAP_FAILED; @@ -3303,11 +3260,6 @@ __libc_free_core (void *mem) if (mem == NULL) /* free(0) has no effect */ return; - /* Quickly check that the freed pointer matches the tag for the memory. - This gives a useful double-free detection. */ - if (__glibc_unlikely (mtag_enabled)) - *(volatile char *)mem; - p = mem2chunk (mem); /* Mark the chunk as belonging to the library again. */ @@ -3375,11 +3327,6 @@ __libc_realloc_core (void *oldmem, size_t bytes) } #endif - /* Perform a quick check to ensure that the pointer's tag matches the - memory's tag. */ - if (__glibc_unlikely (mtag_enabled)) - *(volatile char*) oldmem; - /* chunk corresponding to oldmem */ const mchunkptr oldp = mem2chunk (oldmem); @@ -3686,12 +3633,6 @@ __libc_calloc2 (size_t sz) p = mem2chunk (mem); - /* If we are using memory tagging, then we need to set the tags - regardless of MORECORE_CLEARS, so we zero the whole block while - doing so. */ - if (__glibc_unlikely (mtag_enabled)) - return tag_new_zero_region (mem, memsize (p)); - csz = chunksize (p); /* Two optional cases in which clearing not necessary */ @@ -3738,9 +3679,6 @@ __libc_calloc_core (size_t n, size_t elem_size) if (tcache->entries[tc_idx] != NULL) { void *mem = tcache_get (tc_idx); - if (__glibc_unlikely (mtag_enabled)) - return tag_new_zero_region (mem, memsize (mem2chunk (mem))); - return clear_memory ((INTERNAL_SIZE_T *) mem, tidx2usize (tc_idx)); } } @@ -3750,9 +3688,6 @@ __libc_calloc_core (size_t n, size_t elem_size) void *mem = tcache_get_large (tc_idx, nb); if (mem != NULL) { - if (__glibc_unlikely (mtag_enabled)) - return tag_new_zero_region (mem, memsize (mem2chunk (mem))); - return memset (mem, 0, memsize (mem2chunk (mem))); } } diff --git a/sysdeps/aarch64/__mtag_tag_region.S b/sysdeps/aarch64/__mtag_tag_region.S index bad3193bfe..85e330812e 100644 --- a/sysdeps/aarch64/__mtag_tag_region.S +++ b/sysdeps/aarch64/__mtag_tag_region.S @@ -18,8 +18,6 @@ #include <sysdep.h> -#ifdef USE_MTAG - /* Assumptions: * * ARMv8-a, AArch64, MTE, LP64 ABI. @@ -107,4 +105,3 @@ L(no_zva_loop): ret END (__libc_mtag_tag_region) -#endif /* USE_MTAG */ diff --git a/sysdeps/aarch64/__mtag_tag_zero_region.S b/sysdeps/aarch64/__mtag_tag_zero_region.S index 3bc6e7301f..1a84b3e4d4 100644 --- a/sysdeps/aarch64/__mtag_tag_zero_region.S +++ b/sysdeps/aarch64/__mtag_tag_zero_region.S @@ -18,8 +18,6 @@ #include <sysdep.h> -#ifdef USE_MTAG - /* Assumptions: * * ARMv8-a, AArch64, MTE, LP64 ABI. @@ -107,4 +105,3 @@ L(no_zva_loop): ret END (__libc_mtag_tag_zero_region) -#endif /* USE_MTAG */ diff --git a/sysdeps/aarch64/cpu-features.h b/sysdeps/aarch64/cpu-features.h index d6367a4596..f414060066 100644 --- a/sysdeps/aarch64/cpu-features.h +++ b/sysdeps/aarch64/cpu-features.h @@ -64,8 +64,7 @@ struct cpu_features uint64_t midr_el1; unsigned zva_size; bool bti; - /* Currently, the GLIBC memory tagging tunable only defines 8 bits. */ - uint8_t mte_state; + uint8_t reserved; bool sve; bool unused; bool mops; diff --git a/sysdeps/aarch64/libc-mtag.h b/sysdeps/aarch64/libc-mtag.h index 1d7368b806..663b866bf8 100644 --- a/sysdeps/aarch64/libc-mtag.h +++ b/sysdeps/aarch64/libc-mtag.h @@ -19,10 +19,7 @@ #ifndef _AARCH64_LIBC_MTAG_H #define _AARCH64_LIBC_MTAG_H 1 -#ifndef USE_MTAG -/* Generic bindings for systems that do not support memory tagging. */ -#include_next "libc-mtag.h" -#else +#if 0 /* Used to ensure additional alignment when objects need to have distinct tags. */ diff --git a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c index 36bd72bb12..cda1f82948 100644 --- a/sysdeps/unix/sysv/linux/aarch64/cpu-features.c +++ b/sysdeps/unix/sysv/linux/aarch64/cpu-features.c @@ -20,7 +20,6 @@ #include <cpu-features.h> #include <sys/auxv.h> #include <elf/dl-hwcaps.h> -#include <sys/prctl.h> #include <sys/utsname.h> #include <dl-tunables-parse.h> #include <dl-symbol-redir-ifunc.h> @@ -96,33 +95,6 @@ init_cpu_features (struct cpu_features *cpu_features) if (cpu_features->bti) GLRO (dl_aarch64_bti) = TUNABLE_GET (glibc, cpu, aarch64_bti, uint64_t, 0); - /* Setup memory tagging support if the HW and kernel support it, and if - the user has requested it. */ - cpu_features->mte_state = 0; - -#ifdef USE_MTAG - int mte_state = TUNABLE_GET (glibc, mem, tagging, unsigned, 0); - cpu_features->mte_state = (GLRO (dl_hwcap2) & HWCAP2_MTE) ? mte_state : 0; - /* If we lack the MTE feature, disable the tunable, since it will - otherwise cause instructions that won't run on this CPU to be used. */ - TUNABLE_SET (glibc, mem, tagging, cpu_features->mte_state); - - if (cpu_features->mte_state & 4) - /* Enable choosing system-preferred faulting mode. */ - __prctl (PR_SET_TAGGED_ADDR_CTRL, - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | PR_MTE_TCF_ASYNC - | MTE_ALLOWED_TAGS), - 0, 0, 0); - else if (cpu_features->mte_state & 2) - __prctl (PR_SET_TAGGED_ADDR_CTRL, - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_SYNC | MTE_ALLOWED_TAGS), - 0, 0, 0); - else if (cpu_features->mte_state) - __prctl (PR_SET_TAGGED_ADDR_CTRL, - (PR_TAGGED_ADDR_ENABLE | PR_MTE_TCF_ASYNC | MTE_ALLOWED_TAGS), - 0, 0, 0); -#endif - /* Check if SVE is supported. */ cpu_features->sve = GLRO (dl_hwcap) & HWCAP_SVE;