From nobody Fri Jun 12 18:33:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id CA4213DB964 for ; Wed, 13 May 2026 10:58:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669887; cv=none; b=bON643uzHrwlaPmIsajznjqBrqusEccE1Zfg6vTfuinKdrhygxU8f0cPVs6CskesWzOoD0EA/VBpwjzxaXn7IORoYGvhe1PajuclyqnWfL5OuYDFpKvF9Pin+3aLEPxfwJw9YHy3WEXmuYdVP8XjK8hk0UGboYFdY/hlukA7A9Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669887; c=relaxed/simple; bh=XRXFMW82MTJcynAAttMY00dBFajezS7qCJhkkN3XZNs=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=aiq6PRDAkaCyXCImb7LSktb6dy7vgWPE+4dGKVmYm8eplUn0wUOE+sDgZVH0VXMBTagCz9oDOMJ341Gr3IvRP+t/91+drLqhdJOGXSqYRek4fFLYhYoSSoSUGoU4OR6OXEuc4h/zmdqzQ4ZaBrfywj/xDf5N6l8kEXT33tvieos= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=K57lqIma; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="K57lqIma" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id A85C01C14; Wed, 13 May 2026 03:57:59 -0700 (PDT) Received: from a080796.blr.arm.com (a080796.arm.com [10.164.21.51]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 989C23F7B4; Wed, 13 May 2026 03:57:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1778669884; bh=XRXFMW82MTJcynAAttMY00dBFajezS7qCJhkkN3XZNs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K57lqImajoAQF8JERG+bA2jfqFK2fCcPAdfcdLC95ysF8I8LFcnqCi1X9m2ihyO/c GZ7Qu80Q6sdhjqcQPbS4G33bKzFAsKi6k8PWwxXmxtMzufCC8iIw8LnAGzR8zn7piE PmpCzLyDmCnlx40u/j867YiA/tti1xTdnAHFepfg= From: Dev Jain To: akpm@linux-foundation.org, vbabka@kernel.org, harry@kernel.org, ryabinin.a.a@gmail.com Cc: Dev Jain , surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, hao.li@linux.dev, cl@gentwo.org, rientjes@google.com, roman.gushchin@linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, glider@google.com, andreyknvl@gmail.com, dvyukov@google.com, vincenzo.frascino@arm.com, kasan-dev@googlegroups.com, ryan.roberts@arm.com, anshuman.khandual@arm.com, catalin.marinas@arm.com Subject: [PATCH 1/3] mm/slub: hw_tags: skip page-allocator unpoisoning on slab allocation Date: Wed, 13 May 2026 16:27:32 +0530 Message-Id: <20260513105734.3380544-2-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260513105734.3380544-1-dev.jain@arm.com> References: <20260513105734.3380544-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When a new slab page is allocated, the buddy will unpoison the page. Then slab immediately poisons the page via kasan_poison_slab(). This is wasted work. Similar to what is done in vmalloc currently, use GFP_SKIP_KASAN (hw tags flag only) to skip unpoisoning of the slab page. Signed-off-by: Dev Jain --- mm/page_alloc.c | 2 +- mm/slub.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 227d58dc3de6..c3a69913aaa9 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -7723,7 +7723,7 @@ struct page *alloc_frozen_pages_nolock_noprof(gfp_t g= fp_flags, int nid, unsigned struct alloc_context ac =3D { }; struct page *page; =20 - VM_WARN_ON_ONCE(gfp_flags & ~__GFP_ACCOUNT); + VM_WARN_ON_ONCE(gfp_flags & ~(__GFP_ACCOUNT | __GFP_SKIP_KASAN)); /* * In PREEMPT_RT spin_trylock() will call raw_spin_lock() which is * unsafe in NMI. If spin_trylock() is called from hard IRQ the current diff --git a/mm/slub.c b/mm/slub.c index 0baa906f39ab..da3520769d1f 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3269,9 +3269,16 @@ static inline struct slab *alloc_slab_page(gfp_t fla= gs, int node, struct slab *slab; unsigned int order =3D oo_order(oo); =20 + /* + * New slab pages are immediately poisoned by kasan_poison_slab() + * before any object is handed out, so page allocator unpoisoning + * is wasted work for HW_TAGS KASAN. + */ + flags |=3D __GFP_SKIP_KASAN; + if (unlikely(!allow_spin)) - page =3D alloc_frozen_pages_nolock(0/* __GFP_COMP is implied */, - node, order); + page =3D alloc_frozen_pages_nolock(__GFP_SKIP_KASAN, + node, order); else if (node =3D=3D NUMA_NO_NODE) page =3D alloc_frozen_pages(flags, order); else --=20 2.43.0 From nobody Fri Jun 12 18:33:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 744D13DB964 for ; Wed, 13 May 2026 10:58:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669895; cv=none; b=WTfSHjknSe8uP4F7MVtrU7/W3ZdLi1x3v2BNStHj55SLmk/9pomt3rcNPaSTT21q1QtGwWVnv3xjtxfYW6DSlFjbZnOA8ars8PNL8M92pRObm60If2pnSOIlf1R4gx1Tl1qUICHpZmto+UxphJhVhJOEycFyLLJrp8iqGBhRegw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669895; c=relaxed/simple; bh=UMZExYTByTd2BljtAfXzMdW/HfNhKp7vgZPFf8/fELI=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rPK3kjQ8T9Ayip0NYstzeU71ib/83HWH0RxSTWRlRMcLXuYEzUmDOpdT0MSY34p9xbV3BdM+Bpr4IDX4Z71tisIHpWAr0pCxcOXgLLw/45OwgzNGO4IFjsxeTjCdByQe0Qr+t9jE9nXMYNaq6bkZy/gvkUZ7kKKi4O1RfmlGC3M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=LWTIVeba; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="LWTIVeba" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9CD311655; Wed, 13 May 2026 03:58:07 -0700 (PDT) Received: from a080796.blr.arm.com (a080796.arm.com [10.164.21.51]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 8C1663F7B4; Wed, 13 May 2026 03:58:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1778669892; bh=UMZExYTByTd2BljtAfXzMdW/HfNhKp7vgZPFf8/fELI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LWTIVebaAkxUiz6Ypc/nwhKXXYiVbwwureTaFhfH7dbOIpEc+nYYeo+zc801vuxMy RmlcFHKnZihIT4l9XvEk50zD2PzaDEaXDSiSoFhfTupL8odzR7FtEveJZP5JRNbzCg 6PpOlut0cqx1FC/G6RUnMV+cRVb3OTnynKZ3ugRE= From: Dev Jain To: akpm@linux-foundation.org, vbabka@kernel.org, harry@kernel.org, ryabinin.a.a@gmail.com Cc: Dev Jain , surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, hao.li@linux.dev, cl@gentwo.org, rientjes@google.com, roman.gushchin@linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, glider@google.com, andreyknvl@gmail.com, dvyukov@google.com, vincenzo.frascino@arm.com, kasan-dev@googlegroups.com, ryan.roberts@arm.com, anshuman.khandual@arm.com, catalin.marinas@arm.com Subject: [PATCH 2/3] kasan: avoid re-poisoning tag-based kmalloc redzones Date: Wed, 13 May 2026 16:27:33 +0530 Message-Id: <20260513105734.3380544-3-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260513105734.3380544-1-dev.jain@arm.com> References: <20260513105734.3380544-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When we allocate object from slab, kasan will unpoison the entire object. In case of allocation from kmalloc caches, the actual allocation size request can be less than the size of the kmalloc cache. kasan poisons the bytes following allocation size up till object size to catch OOB. We can do this operation in one shot: while unpoisoning the object upon allocation, only unpoison up till allocation size bytes, so that the bytes following that up till object size remain poisoned. Currently when we free an object into the slab, we use KASAN_SLAB_FREE for poisoning, and use KASAN_SLAB_REDZONE for poisoning the tail end. For tag-based kasan, these two are equal, as opposed to generic kasan. So we make this optimization only for tag-based kasan. Signed-off-by: Dev Jain --- include/linux/kasan.h | 17 +++++++++---- mm/kasan/common.c | 55 +++++++++++++++++++++++++++++++++---------- mm/slub.c | 11 +++++---- 3 files changed, 61 insertions(+), 22 deletions(-) diff --git a/include/linux/kasan.h b/include/linux/kasan.h index bf233bde68c7..fd7c1f5f9fd6 100644 --- a/include/linux/kasan.h +++ b/include/linux/kasan.h @@ -102,6 +102,12 @@ static inline bool kasan_has_integrated_init(void) return kasan_hw_tags_enabled(); } =20 +static inline bool kasan_has_tag_based_kmalloc_redzones(void) +{ + return kasan_enabled() && + (IS_ENABLED(CONFIG_KASAN_SW_TAGS) || kasan_hw_tags_enabled()); +} + #ifdef CONFIG_KASAN void __kasan_unpoison_range(const void *addr, size_t size); static __always_inline void kasan_unpoison_range(const void *addr, size_t = size) @@ -244,13 +250,14 @@ static __always_inline void kasan_kfree_large(void *p= tr) __kasan_kfree_large(ptr, _RET_IP_); } =20 -void * __must_check __kasan_slab_alloc(struct kmem_cache *s, - void *object, gfp_t flags, bool init); +void * __must_check __kasan_slab_alloc(struct kmem_cache *s, void *object, + size_t size, gfp_t flags, bool init); static __always_inline void * __must_check kasan_slab_alloc( - struct kmem_cache *s, void *object, gfp_t flags, bool init) + struct kmem_cache *s, void *object, size_t size, + gfp_t flags, bool init) { if (kasan_enabled()) - return __kasan_slab_alloc(s, object, flags, init); + return __kasan_slab_alloc(s, object, size, flags, init); return object; } =20 @@ -437,7 +444,7 @@ static inline bool kasan_slab_free(struct kmem_cache *s= , void *object, } static inline void kasan_kfree_large(void *ptr) {} static inline void *kasan_slab_alloc(struct kmem_cache *s, void *object, - gfp_t flags, bool init) + size_t size, gfp_t flags, bool init) { return object; } diff --git a/mm/kasan/common.c b/mm/kasan/common.c index b7d05c2a6d93..9a4db9c21aaf 100644 --- a/mm/kasan/common.c +++ b/mm/kasan/common.c @@ -326,14 +326,25 @@ void __kasan_kfree_large(void *ptr, unsigned long ip) /* The object will be poisoned by kasan_poison_pages(). */ } =20 +static inline size_t slab_unpoison_size(struct kmem_cache *cache, size_t s= ize) +{ + if (kasan_has_tag_based_kmalloc_redzones() && is_kmalloc_cache(cache)) + return min_t(size_t, size, cache->object_size); + + return cache->object_size; +} + static inline void unpoison_slab_object(struct kmem_cache *cache, void *ob= ject, - gfp_t flags, bool init) + size_t size, gfp_t flags, bool init) { /* - * Unpoison the whole object. For kmalloc() allocations, - * poison_kmalloc_redzone() will do precise poisoning. + * For tag-based modes, kmalloc redzones all use the same invalid tag. + * Keep the tail poisoned and only unpoison the requested allocation + * size. Generic KASAN keeps distinct shadow values for free objects and + * redzones, so it still unpoisons the whole object and later poisons + * the precise redzone. */ - kasan_unpoison(object, cache->object_size, init); + kasan_unpoison(object, slab_unpoison_size(cache, size), init); =20 /* Save alloc info (if possible) for non-kmalloc() allocations. */ if (kasan_stack_collection_enabled() && !is_kmalloc_cache(cache)) @@ -341,7 +352,8 @@ static inline void unpoison_slab_object(struct kmem_cac= he *cache, void *object, } =20 void * __must_check __kasan_slab_alloc(struct kmem_cache *cache, - void *object, gfp_t flags, bool init) + void *object, size_t size, + gfp_t flags, bool init) { u8 tag; void *tagged_object; @@ -363,11 +375,18 @@ void * __must_check __kasan_slab_alloc(struct kmem_ca= che *cache, tagged_object =3D set_tag(object, tag); =20 /* Unpoison the object and save alloc info for non-kmalloc() allocations.= */ - unpoison_slab_object(cache, tagged_object, flags, init); + unpoison_slab_object(cache, tagged_object, size, flags, init); =20 return tagged_object; } =20 +static inline void save_kmalloc_alloc_info(struct kmem_cache *cache, + void *object, gfp_t flags) +{ + if (kasan_stack_collection_enabled() && is_kmalloc_cache(cache)) + kasan_save_alloc_info(cache, object, flags); +} + static inline void poison_kmalloc_redzone(struct kmem_cache *cache, const void *object, size_t size, gfp_t flags) { @@ -394,8 +413,7 @@ static inline void poison_kmalloc_redzone(struct kmem_c= ache *cache, * Save alloc info (if possible) for kmalloc() allocations. * This also rewrites the alloc info when called from kasan_krealloc(). */ - if (kasan_stack_collection_enabled() && is_kmalloc_cache(cache)) - kasan_save_alloc_info(cache, (void *)object, flags); + save_kmalloc_alloc_info(cache, (void *)object, flags); =20 } =20 @@ -411,8 +429,14 @@ void * __must_check __kasan_kmalloc(struct kmem_cache = *cache, const void *object if (is_kfence_address(object)) return (void *)object; =20 - /* The object has already been unpoisoned by kasan_slab_alloc(). */ - poison_kmalloc_redzone(cache, object, size, flags); + /* + * For tag-based modes, the object has already been precisely + * unpoisoned by kasan_slab_alloc(). The tail remains poisoned. + */ + if (kasan_has_tag_based_kmalloc_redzones()) + save_kmalloc_alloc_info(cache, (void *)object, flags); + else + poison_kmalloc_redzone(cache, object, size, flags); =20 /* Keep the tag that was set by kasan_slab_alloc(). */ return (void *)object; @@ -561,11 +585,16 @@ void __kasan_mempool_unpoison_object(void *ptr, size_= t size, unsigned long ip) return; =20 /* Unpoison the object and save alloc info for non-kmalloc() allocations.= */ - unpoison_slab_object(slab->slab_cache, ptr, flags, false); + unpoison_slab_object(slab->slab_cache, ptr, size, flags, false); =20 /* Poison the redzone and save alloc info for kmalloc() allocations. */ - if (is_kmalloc_cache(slab->slab_cache)) - poison_kmalloc_redzone(slab->slab_cache, ptr, size, flags); + if (is_kmalloc_cache(slab->slab_cache)) { + if (kasan_has_tag_based_kmalloc_redzones()) + save_kmalloc_alloc_info(slab->slab_cache, ptr, flags); + else + poison_kmalloc_redzone(slab->slab_cache, ptr, size, + flags); + } } =20 bool __kasan_check_byte(const void *address, unsigned long ip) diff --git a/mm/slub.c b/mm/slub.c index da3520769d1f..15144b2e078c 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -4550,8 +4550,9 @@ bool slab_post_alloc_hook(struct kmem_cache *s, struc= t list_lru *lru, * replacement of current poisoning under certain debug option, and * won't break other sanity checks. */ - if (kmem_cache_debug_flags(s, SLAB_STORE_USER | SLAB_RED_ZONE) && - (s->flags & SLAB_KMALLOC)) + if ((s->flags & SLAB_KMALLOC) && + (kmem_cache_debug_flags(s, SLAB_STORE_USER | SLAB_RED_ZONE) || + kasan_has_tag_based_kmalloc_redzones())) zero_size =3D orig_size; =20 /* @@ -4573,7 +4574,8 @@ bool slab_post_alloc_hook(struct kmem_cache *s, struc= t list_lru *lru, * As p[i] might get tagged, memset and kmemleak hook come after KASAN. */ for (i =3D 0; i < size; i++) { - p[i] =3D kasan_slab_alloc(s, p[i], init_flags, kasan_init); + p[i] =3D kasan_slab_alloc(s, p[i], orig_size, init_flags, + kasan_init); if (p[i] && init && (!kasan_init || !kasan_has_integrated_init())) memset(p[i], 0, zero_size); @@ -7615,7 +7617,8 @@ static void early_kmem_cache_node_alloc(int node) #ifdef CONFIG_SLUB_DEBUG init_object(kmem_cache_node, n, SLUB_RED_ACTIVE); #endif - n =3D kasan_slab_alloc(kmem_cache_node, n, GFP_KERNEL, false); + n =3D kasan_slab_alloc(kmem_cache_node, n, kmem_cache_node->object_size, + GFP_KERNEL, false); slab->freelist =3D get_freepointer(kmem_cache_node, n); slab->inuse =3D 1; kmem_cache_node->per_node[node].node =3D n; --=20 2.43.0 From nobody Fri Jun 12 18:33:16 2026 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 68FB83FB06D for ; Wed, 13 May 2026 10:58:21 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669902; cv=none; b=pveoyS2NXwaSeTcjX231jg6aGUfSjIo5atOWmt42WFp3wSEUEpWkMzi26ijE1gUyVne6IxyB+oD6szEzLzviNCIMMI6ubQG3auf6vsYA/UI8AJVgeUPJaU/Ix0UDeXNHcyzZhKN/S9wRms9hmY0lvYuMN9YrhyGa7/5ZI25NLK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778669902; c=relaxed/simple; bh=NamPXilA4rJjOKvo9OhmxYnQOChROKpr703f2A0MNL4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=RlFQWpd71kK1R6A/10xdDlH3LA//hRyKIyqTpdcDQQFS+PII4joeqKFNGF9UeSZpbWTdfo5k2b14fcldvT+z3lq+Tv27JG0xMenlB/ai+f02Zk/3A9BEuS7BQn4jdLzx9eBe5rRl3K/jS/8g1eQx0gx4be2kHx9DGNvPGkMxdB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b=CE69JfQI; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=arm.com header.i=@arm.com header.b="CE69JfQI" Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 819D71655; Wed, 13 May 2026 03:58:15 -0700 (PDT) Received: from a080796.blr.arm.com (a080796.arm.com [10.164.21.51]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id 7F7CE3F7B4; Wed, 13 May 2026 03:58:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=arm.com; s=foss; t=1778669900; bh=NamPXilA4rJjOKvo9OhmxYnQOChROKpr703f2A0MNL4=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CE69JfQIYQBEbu15G/3hwUd6A94Vi6U3OZgYwEH3fIYGXOB6hXHTmAVZn517eNaQt 0azC9G0CuuL874A8WC3Kuk3SB1PLbFN9Nd41oo/Xc3QKCJU0pPNtp+o2wngGg93l1c N1LhWHOd7Z/DT787YvXTGTmcgY8n8OtAJ50VR88U= From: Dev Jain To: akpm@linux-foundation.org, vbabka@kernel.org, harry@kernel.org, ryabinin.a.a@gmail.com Cc: Dev Jain , surenb@google.com, mhocko@suse.com, jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com, hao.li@linux.dev, cl@gentwo.org, rientjes@google.com, roman.gushchin@linux.dev, linux-mm@kvack.org, linux-kernel@vger.kernel.org, glider@google.com, andreyknvl@gmail.com, dvyukov@google.com, vincenzo.frascino@arm.com, kasan-dev@googlegroups.com, ryan.roberts@arm.com, anshuman.khandual@arm.com, catalin.marinas@arm.com Subject: [PATCH 3/3] vmalloc: hw_tags: optimize vmalloc redzoning Date: Wed, 13 May 2026 16:27:34 +0530 Message-Id: <20260513105734.3380544-4-dev.jain@arm.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20260513105734.3380544-1-dev.jain@arm.com> References: <20260513105734.3380544-1-dev.jain@arm.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" If the allocation size is less than a page, vmalloc first unpoisons the entire page, then poisons the tail with KASAN_TAG_INVALID (for hw tags), to catch OOB. Instead, unpoison the allocation length, and then poison the tail, saving some work. Signed-off-by: Dev Jain --- mm/kasan/hw_tags.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/mm/kasan/hw_tags.c b/mm/kasan/hw_tags.c index cbef5e450954..7c94f71b5f12 100644 --- a/mm/kasan/hw_tags.c +++ b/mm/kasan/hw_tags.c @@ -364,9 +364,6 @@ void *__kasan_unpoison_vmalloc(const void *start, unsig= ned long size, tag =3D (flags & KASAN_VMALLOC_KEEP_TAG) ? get_tag(start) : kasan_random_= tag(); start =3D set_tag(start, tag); =20 - /* Unpoison and initialize memory up to size. */ - kasan_unpoison(start, size, flags & KASAN_VMALLOC_INIT); - /* * Explicitly poison and initialize the in-page vmalloc() redzone. * Unlike software KASAN modes, hardware tag-based KASAN doesn't @@ -375,8 +372,14 @@ void *__kasan_unpoison_vmalloc(const void *start, unsi= gned long size, redzone_start =3D round_up((unsigned long)start + size, KASAN_GRANULE_SIZE); redzone_size =3D round_up(redzone_start, PAGE_SIZE) - redzone_start; - kasan_poison((void *)redzone_start, redzone_size, KASAN_TAG_INVALID, - flags & KASAN_VMALLOC_INIT); + + /* Unpoison and initialize memory before the redzone. */ + kasan_unpoison(start, redzone_start - (unsigned long)start, + flags & KASAN_VMALLOC_INIT); + + if (redzone_size) + kasan_poison((void *)redzone_start, redzone_size, + KASAN_TAG_INVALID, flags & KASAN_VMALLOC_INIT); =20 /* * Set per-page tag flags to allow accessing physical memory for the --=20 2.43.0