kasan: support kasan.stacktrace for SW_TAGS
[linux-2.6-microblaze.git] / mm / kasan / tags.c
index a0524e0..dd929ab 100644 (file)
 #include "kasan.h"
 #include "../slab.h"
 
+enum kasan_arg_stacktrace {
+       KASAN_ARG_STACKTRACE_DEFAULT,
+       KASAN_ARG_STACKTRACE_OFF,
+       KASAN_ARG_STACKTRACE_ON,
+};
+
+static enum kasan_arg_stacktrace kasan_arg_stacktrace __initdata;
+
+/* Whether to collect alloc/free stack traces. */
+DEFINE_STATIC_KEY_TRUE(kasan_flag_stacktrace);
+
 /* Non-zero, as initial pointer values are 0. */
 #define STACK_RING_BUSY_PTR ((void *)1)
 
@@ -26,6 +37,38 @@ struct kasan_stack_ring stack_ring = {
        .lock = __RW_LOCK_UNLOCKED(stack_ring.lock)
 };
 
+/* kasan.stacktrace=off/on */
+static int __init early_kasan_flag_stacktrace(char *arg)
+{
+       if (!arg)
+               return -EINVAL;
+
+       if (!strcmp(arg, "off"))
+               kasan_arg_stacktrace = KASAN_ARG_STACKTRACE_OFF;
+       else if (!strcmp(arg, "on"))
+               kasan_arg_stacktrace = KASAN_ARG_STACKTRACE_ON;
+       else
+               return -EINVAL;
+
+       return 0;
+}
+early_param("kasan.stacktrace", early_kasan_flag_stacktrace);
+
+void __init kasan_init_tags(void)
+{
+       switch (kasan_arg_stacktrace) {
+       case KASAN_ARG_STACKTRACE_DEFAULT:
+               /* Default is specified by kasan_flag_stacktrace definition. */
+               break;
+       case KASAN_ARG_STACKTRACE_OFF:
+               static_branch_disable(&kasan_flag_stacktrace);
+               break;
+       case KASAN_ARG_STACKTRACE_ON:
+               static_branch_enable(&kasan_flag_stacktrace);
+               break;
+       }
+}
+
 static void save_stack_info(struct kmem_cache *cache, void *object,
                        gfp_t gfp_flags, bool is_free)
 {