Merge tag 'pm-5.15-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-microblaze.git] / kernel / trace / trace_kprobe.c
index ea6178c..3a64ba4 100644 (file)
@@ -80,10 +80,6 @@ static struct trace_kprobe *to_trace_kprobe(struct dyn_event *ev)
        for_each_dyn_event(dpos)                \
                if (is_trace_kprobe(dpos) && (pos = to_trace_kprobe(dpos)))
 
-#define SIZEOF_TRACE_KPROBE(n)                         \
-       (offsetof(struct trace_kprobe, tp.args) +       \
-       (sizeof(struct probe_arg) * (n)))
-
 static nokprobe_inline bool trace_kprobe_is_return(struct trace_kprobe *tk)
 {
        return tk->rp.handler != NULL;
@@ -265,7 +261,7 @@ static struct trace_kprobe *alloc_trace_kprobe(const char *group,
        struct trace_kprobe *tk;
        int ret = -ENOMEM;
 
-       tk = kzalloc(SIZEOF_TRACE_KPROBE(nargs), GFP_KERNEL);
+       tk = kzalloc(struct_size(tk, tp.args, nargs), GFP_KERNEL);
        if (!tk)
                return ERR_PTR(ret);
 
@@ -543,6 +539,10 @@ static int unregister_trace_kprobe(struct trace_kprobe *tk)
        if (trace_probe_is_enabled(&tk->tp))
                return -EBUSY;
 
+       /* If there's a reference to the dynamic event */
+       if (trace_event_dyn_busy(trace_probe_event_call(&tk->tp)))
+               return -EBUSY;
+
        /* Will fail if probe is being used by ftrace or perf */
        if (unregister_kprobe_event(tk))
                return -EBUSY;
@@ -618,7 +618,7 @@ static int append_trace_kprobe(struct trace_kprobe *tk, struct trace_kprobe *to)
        if (ret)
                trace_probe_unlink(&tk->tp);
        else
-               dyn_event_add(&tk->devent);
+               dyn_event_add(&tk->devent, trace_probe_event_call(&tk->tp));
 
        return ret;
 }
@@ -647,7 +647,11 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
        /* Register new event */
        ret = register_kprobe_event(tk);
        if (ret) {
-               pr_warn("Failed to register probe event(%d)\n", ret);
+               if (ret == -EEXIST) {
+                       trace_probe_log_set_index(0);
+                       trace_probe_log_err(0, EVENT_EXIST);
+               } else
+                       pr_warn("Failed to register probe event(%d)\n", ret);
                goto end;
        }
 
@@ -661,7 +665,7 @@ static int register_trace_kprobe(struct trace_kprobe *tk)
        if (ret < 0)
                unregister_kprobe_event(tk);
        else
-               dyn_event_add(&tk->devent);
+               dyn_event_add(&tk->devent, trace_probe_event_call(&tk->tp));
 
 end:
        mutex_unlock(&event_mutex);
@@ -703,14 +707,6 @@ static struct notifier_block trace_kprobe_module_nb = {
        .priority = 1   /* Invoked after kprobe module callback */
 };
 
-/* Convert certain expected symbols into '_' when generating event names */
-static inline void sanitize_event_name(char *name)
-{
-       while (*name++ != '\0')
-               if (*name == ':' || *name == '.')
-                       *name = '_';
-}
-
 static int __trace_kprobe_create(int argc, const char *argv[])
 {
        /*
@@ -742,6 +738,7 @@ static int __trace_kprobe_create(int argc, const char *argv[])
        bool is_return = false;
        char *symbol = NULL, *tmp = NULL;
        const char *event = NULL, *group = KPROBE_EVENT_SYSTEM;
+       enum probe_print_type ptype;
        int maxactive = 0;
        long offset = 0;
        void *addr = NULL;
@@ -869,20 +866,14 @@ static int __trace_kprobe_create(int argc, const char *argv[])
 
        /* parse arguments */
        for (i = 0; i < argc && i < MAX_TRACE_ARGS; i++) {
-               tmp = kstrdup(argv[i], GFP_KERNEL);
-               if (!tmp) {
-                       ret = -ENOMEM;
-                       goto error;
-               }
-
                trace_probe_log_set_index(i + 2);
-               ret = traceprobe_parse_probe_arg(&tk->tp, i, tmp, flags);
-               kfree(tmp);
+               ret = traceprobe_parse_probe_arg(&tk->tp, i, argv[i], flags);
                if (ret)
                        goto error;     /* This can be -ENOMEM */
        }
 
-       ret = traceprobe_set_print_fmt(&tk->tp, is_return);
+       ptype = is_return ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
+       ret = traceprobe_set_print_fmt(&tk->tp, ptype);
        if (ret < 0)
                goto error;
 
@@ -1330,9 +1321,10 @@ probe_mem_read(void *dest, void *src, size_t size)
 
 /* Note that we don't verify it, since the code does not come from user space */
 static int
-process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
+process_fetch_insn(struct fetch_insn *code, void *rec, void *dest,
                   void *base)
 {
+       struct pt_regs *regs = rec;
        unsigned long val;
 
 retry:
@@ -1806,6 +1798,7 @@ struct trace_event_call *
 create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
                          bool is_return)
 {
+       enum probe_print_type ptype;
        struct trace_kprobe *tk;
        int ret;
        char *event;
@@ -1829,7 +1822,9 @@ create_local_trace_kprobe(char *func, void *addr, unsigned long offs,
 
        init_trace_event_call(tk);
 
-       if (traceprobe_set_print_fmt(&tk->tp, trace_kprobe_is_return(tk)) < 0) {
+       ptype = trace_kprobe_is_return(tk) ?
+               PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
+       if (traceprobe_set_print_fmt(&tk->tp, ptype) < 0) {
                ret = -ENOMEM;
                goto error;
        }