#include <linux/sched.h>
 #include <linux/sched/task_stack.h>
 #include <linux/slab.h>
+#include <linux/spinlock.h>
 #include <linux/stackdepot.h>
 #include <linux/stacktrace.h>
 #include <linux/string.h>
        struct kasan_free_meta *free_meta;
 
        alloc_meta = kasan_get_alloc_meta(cache, object);
-       if (alloc_meta)
+       if (alloc_meta) {
                __memset(alloc_meta, 0, sizeof(*alloc_meta));
+
+               /*
+                * Temporarily disable KASAN bug reporting to allow instrumented
+                * raw_spin_lock_init to access aux_lock, which resides inside
+                * of a redzone.
+                */
+               kasan_disable_current();
+               raw_spin_lock_init(&alloc_meta->aux_lock);
+               kasan_enable_current();
+       }
        free_meta = kasan_get_free_meta(cache, object);
        if (free_meta)
                __memset(free_meta, 0, sizeof(*free_meta));
        struct kmem_cache *cache;
        struct kasan_alloc_meta *alloc_meta;
        void *object;
+       depot_stack_handle_t new_handle, old_handle;
+       unsigned long flags;
 
        if (is_kfence_address(addr) || !slab)
                return;
        if (!alloc_meta)
                return;
 
-       stack_depot_put(alloc_meta->aux_stack[1]);
+       new_handle = kasan_save_stack(0, depot_flags);
+
+       /*
+        * Temporarily disable KASAN bug reporting to allow instrumented
+        * spinlock functions to access aux_lock, which resides inside of a
+        * redzone.
+        */
+       kasan_disable_current();
+       raw_spin_lock_irqsave(&alloc_meta->aux_lock, flags);
+       old_handle = alloc_meta->aux_stack[1];
        alloc_meta->aux_stack[1] = alloc_meta->aux_stack[0];
-       alloc_meta->aux_stack[0] = kasan_save_stack(0, depot_flags);
+       alloc_meta->aux_stack[0] = new_handle;
+       raw_spin_unlock_irqrestore(&alloc_meta->aux_lock, flags);
+       kasan_enable_current();
+
+       stack_depot_put(old_handle);
 }
 
 void kasan_record_aux_stack(void *addr)
 
 #include <linux/kasan.h>
 #include <linux/kasan-tags.h>
 #include <linux/kfence.h>
+#include <linux/spinlock.h>
 #include <linux/stackdepot.h>
 
 #if defined(CONFIG_KASAN_SW_TAGS) || defined(CONFIG_KASAN_HW_TAGS)
 struct kasan_alloc_meta {
        struct kasan_track alloc_track;
        /* Free track is stored in kasan_free_meta. */
+       /*
+        * aux_lock protects aux_stack from accesses from concurrent
+        * kasan_record_aux_stack calls. It is a raw spinlock to avoid sleeping
+        * on RT kernels, as kasan_record_aux_stack_noalloc can be called from
+        * non-sleepable contexts.
+        */
+       raw_spinlock_t aux_lock;
        depot_stack_handle_t aux_stack[2];
 };