#endif /* CONFIG_PERF_EVENTS */
 
 static int bpf_raw_tp_link_attach(struct bpf_prog *prog,
-                                 const char __user *user_tp_name)
+                                 const char __user *user_tp_name, u64 cookie)
 {
        struct bpf_link_primer link_primer;
        struct bpf_raw_tp_link *link;
        bpf_link_init(&link->link, BPF_LINK_TYPE_RAW_TRACEPOINT,
                      &bpf_raw_tp_link_lops, prog);
        link->btp = btp;
+       link->cookie = cookie;
 
        err = bpf_link_prime(&link->link, &link_primer);
        if (err) {
        return err;
 }
 
-#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.prog_fd
+#define BPF_RAW_TRACEPOINT_OPEN_LAST_FIELD raw_tracepoint.cookie
 
 static int bpf_raw_tracepoint_open(const union bpf_attr *attr)
 {
        struct bpf_prog *prog;
+       void __user *tp_name;
+       __u64 cookie;
        int fd;
 
        if (CHECK_ATTR(BPF_RAW_TRACEPOINT_OPEN))
        if (IS_ERR(prog))
                return PTR_ERR(prog);
 
-       fd = bpf_raw_tp_link_attach(prog, u64_to_user_ptr(attr->raw_tracepoint.name));
+       tp_name = u64_to_user_ptr(attr->raw_tracepoint.name);
+       cookie = attr->raw_tracepoint.cookie;
+       fd = bpf_raw_tp_link_attach(prog, tp_name, cookie);
        if (fd < 0)
                bpf_prog_put(prog);
        return fd;
                        goto out;
                }
                if (prog->expected_attach_type == BPF_TRACE_RAW_TP)
-                       ret = bpf_raw_tp_link_attach(prog, NULL);
+                       ret = bpf_raw_tp_link_attach(prog, NULL, attr->link_create.tracing.cookie);
                else if (prog->expected_attach_type == BPF_TRACE_ITER)
                        ret = bpf_iter_link_attach(attr, uattr, prog);
                else if (prog->expected_attach_type == BPF_LSM_CGROUP)
 
                return &bpf_get_stackid_proto_raw_tp;
        case BPF_FUNC_get_stack:
                return &bpf_get_stack_proto_raw_tp;
+       case BPF_FUNC_get_attach_cookie:
+               return &bpf_get_attach_cookie_proto_tracing;
        default:
                return bpf_tracing_func_proto(func_id, prog);
        }
        case BPF_FUNC_get_func_arg_cnt:
                return bpf_prog_has_trampoline(prog) ? &bpf_get_func_arg_cnt_proto : NULL;
        case BPF_FUNC_get_attach_cookie:
+               if (prog->type == BPF_PROG_TYPE_TRACING &&
+                   prog->expected_attach_type == BPF_TRACE_RAW_TP)
+                       return &bpf_get_attach_cookie_proto_tracing;
                return bpf_prog_has_trampoline(prog) ? &bpf_get_attach_cookie_proto_tracing : NULL;
        default:
                fn = raw_tp_prog_func_proto(func_id, prog);
 void __bpf_trace_run(struct bpf_raw_tp_link *link, u64 *args)
 {
        struct bpf_prog *prog = link->link.prog;
+       struct bpf_run_ctx *old_run_ctx;
+       struct bpf_trace_run_ctx run_ctx;
 
        cant_sleep();
        if (unlikely(this_cpu_inc_return(*(prog->active)) != 1)) {
                bpf_prog_inc_misses_counter(prog);
                goto out;
        }
+
+       run_ctx.bpf_cookie = link->cookie;
+       old_run_ctx = bpf_set_run_ctx(&run_ctx.run_ctx);
+
        rcu_read_lock();
        (void) bpf_prog_run(prog, args);
        rcu_read_unlock();
+
+       bpf_reset_run_ctx(old_run_ctx);
 out:
        this_cpu_dec(*(prog->active));
 }