* [PATCH v4 1/3] vmalloc: add __GFP_SKIP_KASAN support
2026-04-29 10:27 [PATCH v4 0/3] kasan: hw_tags: Disable tagging for stack and page-tables Dev Jain
@ 2026-04-29 10:27 ` Dev Jain
2026-04-29 14:42 ` Catalin Marinas
2026-04-29 10:27 ` [PATCH v4 2/3] kasan: skip HW tagging for all kernel thread stacks Dev Jain
2026-04-29 10:27 ` [PATCH v4 3/3] mm: skip KASAN tagging for page-allocated page tables Dev Jain
2 siblings, 1 reply; 6+ messages in thread
From: Dev Jain @ 2026-04-29 10:27 UTC (permalink / raw)
To: akpm, david, urezki, kees, mingo, peterz, juri.lelli,
vincent.guittot, arnd
Cc: Muhammad Usama Anjum, ljs, Liam.Howlett, vbabka, rppt, surenb,
mhocko, linux-mm, linux-kernel, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, kprateek.nayak, tglx,
mathieu.desnoyers, linux-arch, ryan.roberts, catalin.marinas,
Dev Jain
From: Muhammad Usama Anjum <usama.anjum@arm.com>
For allocations that will be accessed only with match-all pointers
(e.g., kernel stacks), setting tags is wasted work. If the caller
already set __GFP_SKIP_KASAN, skip tag setting of vmalloc pages.
Before this patch, __GFP_SKIP_KASAN wasn't being used with vmalloc
APIs. So it wasn't being checked. Now its being checked and acted
upon. Other KASAN modes are unchanged because __GFP_SKIP_KASAN is
ignored for them in the page allocator, and in vmalloc too we ignore
this flag for them.
This is a preparatory patch for optimizing kernel stack allocations.
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Co-developed-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Co-developed-by: Dev Jain <dev.jain@arm.com>
Signed-off-by: Dev Jain <dev.jain@arm.com>
---
include/linux/gfp_types.h | 6 +++---
mm/vmalloc.c | 13 +++++++++----
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h
index 6c75df30a281d..c2bd723c8ec62 100644
--- a/include/linux/gfp_types.h
+++ b/include/linux/gfp_types.h
@@ -281,9 +281,9 @@ enum {
*
* %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation.
* Used for userspace and vmalloc pages; the latter are unpoisoned by
- * kasan_unpoison_vmalloc instead. For userspace pages, results in
- * poisoning being skipped as well, see should_skip_kasan_poison for
- * details. Only effective in HW_TAGS mode.
+ * kasan_unpoison_vmalloc instead. If passed to vmalloc, kasan_unpoison_vmalloc
+ * is skipped too. For userspace pages, results in poisoning being skipped as
+ * well, see should_skip_kasan_poison for details. Only effective in HW_TAGS mode.
*/
#define __GFP_NOWARN ((__force gfp_t)___GFP_NOWARN)
#define __GFP_COMP ((__force gfp_t)___GFP_COMP)
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index aa08651ec0df6..708ccac293cef 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -3939,7 +3939,7 @@ static void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
__GFP_NOFAIL | __GFP_ZERO |\
__GFP_NORETRY | __GFP_RETRY_MAYFAIL |\
GFP_NOFS | GFP_NOIO | GFP_KERNEL_ACCOUNT |\
- GFP_USER | __GFP_NOLOCKDEP)
+ GFP_USER | __GFP_NOLOCKDEP | __GFP_SKIP_KASAN)
static gfp_t vmalloc_fix_flags(gfp_t flags)
{
@@ -3980,6 +3980,9 @@ static gfp_t vmalloc_fix_flags(gfp_t flags)
*
* %__GFP_NOWARN can be used to suppress failure messages.
*
+ * %__GFP_SKIP_KASAN can be used to skip unpoisoning of mapped pages
+ * (when prot=%PAGE_KERNEL).
+ *
* Can not be called from interrupt nor NMI contexts.
* Return: the address of the area or %NULL on failure
*/
@@ -3993,6 +3996,7 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
kasan_vmalloc_flags_t kasan_flags = KASAN_VMALLOC_NONE;
unsigned long original_align = align;
unsigned int shift = PAGE_SHIFT;
+ bool skip_vmalloc_kasan = kasan_hw_tags_enabled() && (gfp_mask & __GFP_SKIP_KASAN);
if (WARN_ON_ONCE(!size))
return NULL;
@@ -4023,7 +4027,7 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
again:
area = __get_vm_area_node(size, align, shift, VM_ALLOC |
VM_UNINITIALIZED | vm_flags, start, end, node,
- gfp_mask, caller);
+ gfp_mask & ~__GFP_SKIP_KASAN, caller);
if (!area) {
bool nofail = gfp_mask & __GFP_NOFAIL;
warn_alloc(gfp_mask, NULL,
@@ -4041,7 +4045,7 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
* kasan_unpoison_vmalloc().
*/
if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL)) {
- if (kasan_hw_tags_enabled()) {
+ if (kasan_hw_tags_enabled() && !skip_vmalloc_kasan) {
/*
* Modify protection bits to allow tagging.
* This must be done before mapping.
@@ -4078,7 +4082,8 @@ void *__vmalloc_node_range_noprof(unsigned long size, unsigned long align,
(gfp_mask & __GFP_SKIP_ZERO))
kasan_flags |= KASAN_VMALLOC_INIT;
/* KASAN_VMALLOC_PROT_NORMAL already set if required. */
- area->addr = kasan_unpoison_vmalloc(area->addr, size, kasan_flags);
+ if (!skip_vmalloc_kasan)
+ area->addr = kasan_unpoison_vmalloc(area->addr, size, kasan_flags);
/*
* In this function, newly allocated vm_struct has VM_UNINITIALIZED
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v4 2/3] kasan: skip HW tagging for all kernel thread stacks
2026-04-29 10:27 [PATCH v4 0/3] kasan: hw_tags: Disable tagging for stack and page-tables Dev Jain
2026-04-29 10:27 ` [PATCH v4 1/3] vmalloc: add __GFP_SKIP_KASAN support Dev Jain
@ 2026-04-29 10:27 ` Dev Jain
2026-04-29 14:43 ` Catalin Marinas
2026-04-29 10:27 ` [PATCH v4 3/3] mm: skip KASAN tagging for page-allocated page tables Dev Jain
2 siblings, 1 reply; 6+ messages in thread
From: Dev Jain @ 2026-04-29 10:27 UTC (permalink / raw)
To: akpm, david, urezki, kees, mingo, peterz, juri.lelli,
vincent.guittot, arnd
Cc: Muhammad Usama Anjum, ljs, Liam.Howlett, vbabka, rppt, surenb,
mhocko, linux-mm, linux-kernel, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, kprateek.nayak, tglx,
mathieu.desnoyers, linux-arch, ryan.roberts, catalin.marinas,
Dev Jain
From: Muhammad Usama Anjum <usama.anjum@arm.com>
HW-tag KASAN never checks kernel stacks because stack pointers carry the
match-all tag, so setting/poisoning tags is pure overhead.
- Add __GFP_SKIP_KASAN to THREADINFO_GFP so every stack allocator that
uses it skips tagging (fork path plus arch users)
- Add __GFP_SKIP_KASAN to GFP_VMAP_STACK for the fork-specific vmap
stacks.
- When reusing cached vmap stacks, skip kasan_unpoison_range() if HW tags
are enabled.
Software KASAN is unchanged; this only affects tag-based KASAN.
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Signed-off-by: Dev Jain <dev.jain@arm.com>
---
include/linux/thread_info.h | 2 +-
kernel/fork.c | 5 +++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/linux/thread_info.h b/include/linux/thread_info.h
index 051e429026904..307b8390fc670 100644
--- a/include/linux/thread_info.h
+++ b/include/linux/thread_info.h
@@ -92,7 +92,7 @@ static inline long set_restart_fn(struct restart_block *restart,
#define THREAD_ALIGN THREAD_SIZE
#endif
-#define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO)
+#define THREADINFO_GFP (GFP_KERNEL_ACCOUNT | __GFP_ZERO | __GFP_SKIP_KASAN)
/*
* flag set/clear/test wrappers
diff --git a/kernel/fork.c b/kernel/fork.c
index f1ad69c6dc2d4..0d97fd71d7f60 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -204,7 +204,7 @@ static DEFINE_PER_CPU(struct vm_struct *, cached_stacks[NR_CACHED_STACKS]);
* accounting is performed by the code assigning/releasing stacks to tasks.
* We need a zeroed memory without __GFP_ACCOUNT.
*/
-#define GFP_VMAP_STACK (GFP_KERNEL | __GFP_ZERO)
+#define GFP_VMAP_STACK (GFP_KERNEL | __GFP_ZERO | __GFP_SKIP_KASAN)
struct vm_stack {
struct rcu_head rcu;
@@ -342,7 +342,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);
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH v4 3/3] mm: skip KASAN tagging for page-allocated page tables
2026-04-29 10:27 [PATCH v4 0/3] kasan: hw_tags: Disable tagging for stack and page-tables Dev Jain
2026-04-29 10:27 ` [PATCH v4 1/3] vmalloc: add __GFP_SKIP_KASAN support Dev Jain
2026-04-29 10:27 ` [PATCH v4 2/3] kasan: skip HW tagging for all kernel thread stacks Dev Jain
@ 2026-04-29 10:27 ` Dev Jain
2 siblings, 0 replies; 6+ messages in thread
From: Dev Jain @ 2026-04-29 10:27 UTC (permalink / raw)
To: akpm, david, urezki, kees, mingo, peterz, juri.lelli,
vincent.guittot, arnd
Cc: Muhammad Usama Anjum, ljs, Liam.Howlett, vbabka, rppt, surenb,
mhocko, linux-mm, linux-kernel, dietmar.eggemann, rostedt,
bsegall, mgorman, vschneid, kprateek.nayak, tglx,
mathieu.desnoyers, linux-arch, ryan.roberts, catalin.marinas,
Dev Jain
From: Muhammad Usama Anjum <usama.anjum@arm.com>
Page tables are always accessed via the linear mapping with a match-all
tag, so HW-tag KASAN never checks them. For page-allocated tables (PTEs
and PGDs etc), avoid the tag setup and poisoning overhead by using
__GFP_SKIP_KASAN. SLUB-backed page tables are unchanged for now. (They
aren't widely used and require more SLUB related skip logic. Leave it
later.)
Reviewed-by: Ryan Roberts <ryan.roberts@arm.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Signed-off-by: Muhammad Usama Anjum <usama.anjum@arm.com>
Signed-off-by: Dev Jain <dev.jain@arm.com>
---
include/asm-generic/pgalloc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/asm-generic/pgalloc.h b/include/asm-generic/pgalloc.h
index 57137d3ac1592..051aa1331051c 100644
--- a/include/asm-generic/pgalloc.h
+++ b/include/asm-generic/pgalloc.h
@@ -4,7 +4,7 @@
#ifdef CONFIG_MMU
-#define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO)
+#define GFP_PGTABLE_KERNEL (GFP_KERNEL | __GFP_ZERO | __GFP_SKIP_KASAN)
#define GFP_PGTABLE_USER (GFP_PGTABLE_KERNEL | __GFP_ACCOUNT)
/**
--
2.34.1
^ permalink raw reply related [flat|nested] 6+ messages in thread