[PATCH 2/3] fork: skip MTE tagging for kernel stacks

Muhammad Usama Anjum
2026-03-19T11:50:17Z

The stack pointer always uses the match-all tag, so MTE never checks
tags on stack accesses. Tagging stack memory on every thread creation
is pure overhead.

- Pass __GFP_SKIP_KASAN in gfp_mask for vmalloc-backed stacks so the
vmalloc path skips HW tag setup (see previous patch).
- For the cached VMAP reuse path, skip kasan_unpoison_range() when HW
tags are enabled since the memory will only be accessed through the
match-all tagged SP.
- For the normal page allocator path, pass __GFP_SKIP_KASAN directly
to the page allocator.

Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
---
kernel/fork.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/kernel/fork.c b/kernel/fork.c
index bb0c2613a5604..2baf4db39b5a4 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -345,7 +345,8 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node)
}

/* Reset stack metadata. */
- kasan_unpoison_range(vm_area->addr, THREAD_SIZE);
+ if (!kasan_hw_tags_enabled())
+ kasan_unpoison_range(vm_area->addr, THREAD_SIZE);

stack = kasan_reset_tag(vm_area->addr);

@@ -358,7 +359,7 @@ static int alloc_thread_stack_node(struct task_struct *tsk, int node)
}

stack = __vmalloc_node(THREAD_SIZE, THREAD_ALIGN,
- GFP_VMAP_STACK,
+ GFP_VMAP_STACK | __GFP_SKIP_KASAN,
node, __builtin_return_address(0));
if (!stack)
return -ENOMEM;
@@ -410,7 +411,8 @@ static void thread_stack_delayed_free(struct task_struct *tsk)

static int alloc_thread_stack_node(struct task_struct *tsk, int node)
{
- struct page *page = alloc_pages_node(node, THREADINFO_GFP,
+ struct page *page = alloc_pages_node(node,
+ THREADINFO_GFP | __GFP_SKIP_KASAN,
THREAD_SIZE_ORDER);

if (likely(page)) {
--
2.47.3