Merge tag 'gpio-updates-for-v5.15' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / kernel / trace / trace_uprobe.c
index 9b50869..225ce56 100644 (file)
@@ -83,10 +83,6 @@ static struct trace_uprobe *to_trace_uprobe(struct dyn_event *ev)
        for_each_dyn_event(dpos)                \
                if (is_trace_uprobe(dpos) && (pos = to_trace_uprobe(dpos)))
 
-#define SIZEOF_TRACE_UPROBE(n)                         \
-       (offsetof(struct trace_uprobe, tp.args) +       \
-       (sizeof(struct probe_arg) * (n)))
-
 static int register_uprobe_event(struct trace_uprobe *tu);
 static int unregister_uprobe_event(struct trace_uprobe *tu);
 
@@ -217,9 +213,10 @@ static unsigned long translate_user_vaddr(unsigned long file_offset)
 
 /* 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;
 
        /* 1st stage: get value from context */
@@ -340,7 +337,7 @@ alloc_trace_uprobe(const char *group, const char *event, int nargs, bool is_ret)
        struct trace_uprobe *tu;
        int ret;
 
-       tu = kzalloc(SIZEOF_TRACE_UPROBE(nargs), GFP_KERNEL);
+       tu = kzalloc(struct_size(tu, tp.args, nargs), GFP_KERNEL);
        if (!tu)
                return ERR_PTR(-ENOMEM);
 
@@ -393,6 +390,10 @@ static int unregister_trace_uprobe(struct trace_uprobe *tu)
        if (trace_probe_has_sibling(&tu->tp))
                goto unreg;
 
+       /* If there's a reference to the dynamic event */
+       if (trace_event_dyn_busy(trace_probe_event_call(&tu->tp)))
+               return -EBUSY;
+
        ret = unregister_uprobe_event(tu);
        if (ret)
                return ret;
@@ -455,7 +456,7 @@ static int append_trace_uprobe(struct trace_uprobe *tu, struct trace_uprobe *to)
        /* Append to existing event */
        ret = trace_probe_append(&tu->tp, &to->tp);
        if (!ret)
-               dyn_event_add(&tu->devent);
+               dyn_event_add(&tu->devent, trace_probe_event_call(&tu->tp));
 
        return ret;
 }
@@ -514,11 +515,15 @@ static int register_trace_uprobe(struct trace_uprobe *tu)
 
        ret = register_uprobe_event(tu);
        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;
        }
 
-       dyn_event_add(&tu->devent);
+       dyn_event_add(&tu->devent, trace_probe_event_call(&tu->tp));
 
 end:
        mutex_unlock(&event_mutex);
@@ -536,6 +541,7 @@ static int __trace_uprobe_create(int argc, const char **argv)
        const char *event = NULL, *group = UPROBE_EVENT_SYSTEM;
        char *arg, *filename, *rctr, *rctr_end, *tmp;
        char buf[MAX_EVENT_NAME_LEN];
+       enum probe_print_type ptype;
        struct path path;
        unsigned long offset, ref_ctr_offset;
        bool is_return = false;
@@ -680,21 +686,15 @@ static int __trace_uprobe_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(&tu->tp, i, tmp,
+               ret = traceprobe_parse_probe_arg(&tu->tp, i, argv[i],
                                        is_return ? TPARG_FL_RETURN : 0);
-               kfree(tmp);
                if (ret)
                        goto error;
        }
 
-       ret = traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu));
+       ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
+       ret = traceprobe_set_print_fmt(&tu->tp, ptype);
        if (ret < 0)
                goto error;
 
@@ -1585,6 +1585,7 @@ struct trace_event_call *
 create_local_trace_uprobe(char *name, unsigned long offs,
                          unsigned long ref_ctr_offset, bool is_return)
 {
+       enum probe_print_type ptype;
        struct trace_uprobe *tu;
        struct path path;
        int ret;
@@ -1619,7 +1620,8 @@ create_local_trace_uprobe(char *name, unsigned long offs,
        tu->filename = kstrdup(name, GFP_KERNEL);
        init_trace_event_call(tu);
 
-       if (traceprobe_set_print_fmt(&tu->tp, is_ret_probe(tu)) < 0) {
+       ptype = is_ret_probe(tu) ? PROBE_PRINT_RETURN : PROBE_PRINT_NORMAL;
+       if (traceprobe_set_print_fmt(&tu->tp, ptype) < 0) {
                ret = -ENOMEM;
                goto error;
        }