path: root/mm/kasan
diff options
authorAndrey Konovalov <>2021-04-29 23:00:09 -0700
committerLinus Torvalds <>2021-04-30 11:20:41 -0700
commitd57a964e09c22441e9fb497d1d7a5c1983a5d1fb (patch)
treed0a38d8147486e6bd85cbd91d30e8171d443a764 /mm/kasan
parentda844b787245194cfd69f0f1d2fb1dd3640a8a6d (diff)
kasan, mm: integrate slab init_on_free with HW_TAGS
This change uses the previously added memory initialization feature of HW_TAGS KASAN routines for slab memory when init_on_free is enabled. With this change, memory initialization memset() is no longer called when both HW_TAGS KASAN and init_on_free are enabled. Instead, memory is initialized in KASAN runtime. For SLUB, the memory initialization memset() is moved into slab_free_hook() that currently directly follows the initialization loop. A new argument is added to slab_free_hook() that indicates whether to initialize the memory or not. To avoid discrepancies with which memory gets initialized that can be caused by future changes, both KASAN hook and initialization memset() are put together and a warning comment is added. Combining setting allocation tags with memory initialization improves HW_TAGS KASAN performance when init_on_free is enabled. Link: Signed-off-by: Andrey Konovalov <> Reviewed-by: Marco Elver <> Cc: Alexander Potapenko <> Cc: Andrey Ryabinin <> Cc: Branislav Rankov <> Cc: Catalin Marinas <> Cc: Christoph Lameter <> Cc: David Rientjes <> Cc: Dmitry Vyukov <> Cc: Evgenii Stepanov <> Cc: Joonsoo Kim <> Cc: Kevin Brodsky <> Cc: Pekka Enberg <> Cc: Peter Collingbourne <> Cc: Vincenzo Frascino <> Cc: Vlastimil Babka <> Cc: Will Deacon <> Signed-off-by: Andrew Morton <> Signed-off-by: Linus Torvalds <>
Diffstat (limited to 'mm/kasan')
1 files changed, 7 insertions, 6 deletions
diff --git a/mm/kasan/common.c b/mm/kasan/common.c
index ac0d4ed9c921..6bb87f2acd4e 100644
--- a/mm/kasan/common.c
+++ b/mm/kasan/common.c
@@ -322,8 +322,8 @@ void * __must_check __kasan_init_slab_obj(struct kmem_cache *cache,
return (void *)object;
-static inline bool ____kasan_slab_free(struct kmem_cache *cache,
- void *object, unsigned long ip, bool quarantine)
+static inline bool ____kasan_slab_free(struct kmem_cache *cache, void *object,
+ unsigned long ip, bool quarantine, bool init)
u8 tag;
void *tagged_object;
@@ -351,7 +351,7 @@ static inline bool ____kasan_slab_free(struct kmem_cache *cache,
kasan_poison(object, round_up(cache->object_size, KASAN_GRANULE_SIZE),
if ((IS_ENABLED(CONFIG_KASAN_GENERIC) && !quarantine))
return false;
@@ -362,9 +362,10 @@ static inline bool ____kasan_slab_free(struct kmem_cache *cache,
return kasan_quarantine_put(cache, object);
-bool __kasan_slab_free(struct kmem_cache *cache, void *object, unsigned long ip)
+bool __kasan_slab_free(struct kmem_cache *cache, void *object,
+ unsigned long ip, bool init)
- return ____kasan_slab_free(cache, object, ip, true);
+ return ____kasan_slab_free(cache, object, ip, true, init);
static inline bool ____kasan_kfree_large(void *ptr, unsigned long ip)
@@ -409,7 +410,7 @@ void __kasan_slab_free_mempool(void *ptr, unsigned long ip)
kasan_poison(ptr, page_size(page), KASAN_FREE_PAGE, false);
} else {
- ____kasan_slab_free(page->slab_cache, ptr, ip, false);
+ ____kasan_slab_free(page->slab_cache, ptr, ip, false, false);