kasan: introduce kasan_mempool_unpoison_pages
[linux-2.6-microblaze.git] / mm / kasan / tags.c
index 7dcfe34..c13b198 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/memblock.h>
 #include <linux/memory.h>
 #include <linux/mm.h>
+#include <linux/sched/clock.h>
+#include <linux/stackdepot.h>
 #include <linux/static_key.h>
 #include <linux/string.h>
 #include <linux/types.h>
@@ -92,16 +94,28 @@ void __init kasan_init_tags(void)
        }
 }
 
+#ifdef CONFIG_KASAN_EXTRA_INFO
+static void save_extra_info(struct kasan_stack_ring_entry *entry)
+{
+       u32 cpu = raw_smp_processor_id();
+       u64 ts_nsec = local_clock();
+
+       entry->cpu = cpu;
+       entry->timestamp = ts_nsec >> 3;
+}
+#endif /* CONFIG_KASAN_EXTRA_INFO */
+
 static void save_stack_info(struct kmem_cache *cache, void *object,
                        gfp_t gfp_flags, bool is_free)
 {
        unsigned long flags;
-       depot_stack_handle_t stack;
+       depot_stack_handle_t stack, old_stack;
        u64 pos;
        struct kasan_stack_ring_entry *entry;
        void *old_ptr;
 
-       stack = kasan_save_stack(gfp_flags, true);
+       stack = kasan_save_stack(gfp_flags,
+                       STACK_DEPOT_FLAG_CAN_ALLOC | STACK_DEPOT_FLAG_GET);
 
        /*
         * Prevent save_stack_info() from modifying stack ring
@@ -120,17 +134,22 @@ next:
        if (!try_cmpxchg(&entry->ptr, &old_ptr, STACK_RING_BUSY_PTR))
                goto next; /* Busy slot. */
 
-       WRITE_ONCE(entry->size, cache->object_size);
-       WRITE_ONCE(entry->pid, current->pid);
-       WRITE_ONCE(entry->stack, stack);
-       WRITE_ONCE(entry->is_free, is_free);
+       old_stack = entry->stack;
 
-       /*
-        * Paired with smp_load_acquire() in kasan_complete_mode_report_info().
-        */
-       smp_store_release(&entry->ptr, (s64)object);
+       entry->size = cache->object_size;
+       entry->pid = current->pid;
+       entry->stack = stack;
+       entry->is_free = is_free;
+#ifdef CONFIG_KASAN_EXTRA_INFO
+       save_extra_info(entry);
+#endif /* CONFIG_KASAN_EXTRA_INFO */
+
+       entry->ptr = object;
 
        read_unlock_irqrestore(&stack_ring.lock, flags);
+
+       if (old_stack)
+               stack_depot_put(old_stack);
 }
 
 void kasan_save_alloc_info(struct kmem_cache *cache, void *object, gfp_t flags)