Merge 6617ae800c ("selftests/bpf: fix perf_event link info name_len assertion") into android15-6.6-lts

Steps on the way to 6.6.59

Change-Id: Id2c2e6abc9a25d381af527da047af101a07449b1
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2024-11-29 12:44:48 +00:00
commit d132b93edf
7 changed files with 111 additions and 44 deletions

View File

@ -765,7 +765,8 @@ struct bpf_raw_event_map *bpf_get_raw_tracepoint(const char *name);
void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp); void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp);
int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
u32 *fd_type, const char **buf, u32 *fd_type, const char **buf,
u64 *probe_offset, u64 *probe_addr); u64 *probe_offset, u64 *probe_addr,
unsigned long *missed);
int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog); int bpf_uprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prog);
#else #else
@ -805,7 +806,7 @@ static inline void bpf_put_raw_tracepoint(struct bpf_raw_event_map *btp)
static inline int bpf_get_perf_event_info(const struct perf_event *event, static inline int bpf_get_perf_event_info(const struct perf_event *event,
u32 *prog_id, u32 *fd_type, u32 *prog_id, u32 *fd_type,
const char **buf, u64 *probe_offset, const char **buf, u64 *probe_offset,
u64 *probe_addr) u64 *probe_addr, unsigned long *missed)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
@ -880,6 +881,7 @@ extern void perf_kprobe_destroy(struct perf_event *event);
extern int bpf_get_kprobe_info(const struct perf_event *event, extern int bpf_get_kprobe_info(const struct perf_event *event,
u32 *fd_type, const char **symbol, u32 *fd_type, const char **symbol,
u64 *probe_offset, u64 *probe_addr, u64 *probe_offset, u64 *probe_addr,
unsigned long *missed,
bool perf_type_tracepoint); bool perf_type_tracepoint);
#endif #endif
#ifdef CONFIG_UPROBE_EVENTS #ifdef CONFIG_UPROBE_EVENTS

View File

@ -6566,20 +6566,27 @@ struct bpf_link_info {
__aligned_u64 file_name; /* in/out */ __aligned_u64 file_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 offset; /* offset from file_name */ __u32 offset; /* offset from file_name */
__u64 cookie;
} uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */ } uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */
struct { struct {
__aligned_u64 func_name; /* in/out */ __aligned_u64 func_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 offset; /* offset from func_name */ __u32 offset; /* offset from func_name */
__u64 addr; __u64 addr;
__u64 missed;
__u64 cookie;
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */ } kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
struct { struct {
__aligned_u64 tp_name; /* in/out */ __aligned_u64 tp_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 :32;
__u64 cookie;
} tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */ } tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */
struct { struct {
__u64 config; __u64 config;
__u32 type; __u32 type;
__u32 :32;
__u64 cookie;
} event; /* BPF_PERF_EVENT_EVENT */ } event; /* BPF_PERF_EVENT_EVENT */
}; };
} perf_event; } perf_event;

View File

@ -3440,26 +3440,34 @@ static void bpf_perf_link_dealloc(struct bpf_link *link)
} }
static int bpf_perf_link_fill_common(const struct perf_event *event, static int bpf_perf_link_fill_common(const struct perf_event *event,
char __user *uname, u32 ulen, char __user *uname, u32 *ulenp,
u64 *probe_offset, u64 *probe_addr, u64 *probe_offset, u64 *probe_addr,
u32 *fd_type) u32 *fd_type, unsigned long *missed)
{ {
const char *buf; const char *buf;
u32 prog_id; u32 prog_id, ulen;
size_t len; size_t len;
int err; int err;
ulen = *ulenp;
if (!ulen ^ !uname) if (!ulen ^ !uname)
return -EINVAL; return -EINVAL;
err = bpf_get_perf_event_info(event, &prog_id, fd_type, &buf, err = bpf_get_perf_event_info(event, &prog_id, fd_type, &buf,
probe_offset, probe_addr); probe_offset, probe_addr, missed);
if (err) if (err)
return err; return err;
if (!uname)
return 0;
if (buf) { if (buf) {
len = strlen(buf); len = strlen(buf);
*ulenp = len + 1;
} else {
*ulenp = 1;
}
if (!uname)
return 0;
if (buf) {
err = bpf_copy_to_user(uname, buf, ulen, len); err = bpf_copy_to_user(uname, buf, ulen, len);
if (err) if (err)
return err; return err;
@ -3476,6 +3484,7 @@ static int bpf_perf_link_fill_common(const struct perf_event *event,
static int bpf_perf_link_fill_kprobe(const struct perf_event *event, static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
struct bpf_link_info *info) struct bpf_link_info *info)
{ {
unsigned long missed;
char __user *uname; char __user *uname;
u64 addr, offset; u64 addr, offset;
u32 ulen, type; u32 ulen, type;
@ -3483,19 +3492,21 @@ static int bpf_perf_link_fill_kprobe(const struct perf_event *event,
uname = u64_to_user_ptr(info->perf_event.kprobe.func_name); uname = u64_to_user_ptr(info->perf_event.kprobe.func_name);
ulen = info->perf_event.kprobe.name_len; ulen = info->perf_event.kprobe.name_len;
err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr, err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,
&type); &type, &missed);
if (err) if (err)
return err; return err;
if (type == BPF_FD_TYPE_KRETPROBE) if (type == BPF_FD_TYPE_KRETPROBE)
info->perf_event.type = BPF_PERF_EVENT_KRETPROBE; info->perf_event.type = BPF_PERF_EVENT_KRETPROBE;
else else
info->perf_event.type = BPF_PERF_EVENT_KPROBE; info->perf_event.type = BPF_PERF_EVENT_KPROBE;
info->perf_event.kprobe.name_len = ulen;
info->perf_event.kprobe.offset = offset; info->perf_event.kprobe.offset = offset;
info->perf_event.kprobe.missed = missed;
if (!kallsyms_show_value(current_cred())) if (!kallsyms_show_value(current_cred()))
addr = 0; addr = 0;
info->perf_event.kprobe.addr = addr; info->perf_event.kprobe.addr = addr;
info->perf_event.kprobe.cookie = event->bpf_cookie;
return 0; return 0;
} }
#endif #endif
@ -3511,8 +3522,8 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
uname = u64_to_user_ptr(info->perf_event.uprobe.file_name); uname = u64_to_user_ptr(info->perf_event.uprobe.file_name);
ulen = info->perf_event.uprobe.name_len; ulen = info->perf_event.uprobe.name_len;
err = bpf_perf_link_fill_common(event, uname, ulen, &offset, &addr, err = bpf_perf_link_fill_common(event, uname, &ulen, &offset, &addr,
&type); &type, NULL);
if (err) if (err)
return err; return err;
@ -3520,7 +3531,9 @@ static int bpf_perf_link_fill_uprobe(const struct perf_event *event,
info->perf_event.type = BPF_PERF_EVENT_URETPROBE; info->perf_event.type = BPF_PERF_EVENT_URETPROBE;
else else
info->perf_event.type = BPF_PERF_EVENT_UPROBE; info->perf_event.type = BPF_PERF_EVENT_UPROBE;
info->perf_event.uprobe.name_len = ulen;
info->perf_event.uprobe.offset = offset; info->perf_event.uprobe.offset = offset;
info->perf_event.uprobe.cookie = event->bpf_cookie;
return 0; return 0;
} }
#endif #endif
@ -3544,11 +3557,18 @@ static int bpf_perf_link_fill_tracepoint(const struct perf_event *event,
{ {
char __user *uname; char __user *uname;
u32 ulen; u32 ulen;
int err;
uname = u64_to_user_ptr(info->perf_event.tracepoint.tp_name); uname = u64_to_user_ptr(info->perf_event.tracepoint.tp_name);
ulen = info->perf_event.tracepoint.name_len; ulen = info->perf_event.tracepoint.name_len;
err = bpf_perf_link_fill_common(event, uname, &ulen, NULL, NULL, NULL, NULL);
if (err)
return err;
info->perf_event.type = BPF_PERF_EVENT_TRACEPOINT; info->perf_event.type = BPF_PERF_EVENT_TRACEPOINT;
return bpf_perf_link_fill_common(event, uname, ulen, NULL, NULL, NULL); info->perf_event.tracepoint.name_len = ulen;
info->perf_event.tracepoint.cookie = event->bpf_cookie;
return 0;
} }
static int bpf_perf_link_fill_perf_event(const struct perf_event *event, static int bpf_perf_link_fill_perf_event(const struct perf_event *event,
@ -3556,6 +3576,7 @@ static int bpf_perf_link_fill_perf_event(const struct perf_event *event,
{ {
info->perf_event.event.type = event->attr.type; info->perf_event.event.type = event->attr.type;
info->perf_event.event.config = event->attr.config; info->perf_event.event.config = event->attr.config;
info->perf_event.event.cookie = event->bpf_cookie;
info->perf_event.type = BPF_PERF_EVENT_EVENT; info->perf_event.type = BPF_PERF_EVENT_EVENT;
return 0; return 0;
} }
@ -4895,7 +4916,7 @@ static int bpf_task_fd_query(const union bpf_attr *attr,
err = bpf_get_perf_event_info(event, &prog_id, &fd_type, err = bpf_get_perf_event_info(event, &prog_id, &fd_type,
&buf, &probe_offset, &buf, &probe_offset,
&probe_addr); &probe_addr, NULL);
if (!err) if (!err)
err = bpf_task_fd_query_copy(attr, uattr, prog_id, err = bpf_task_fd_query_copy(attr, uattr, prog_id,
fd_type, buf, fd_type, buf,

View File

@ -2388,7 +2388,8 @@ int bpf_probe_unregister(struct bpf_raw_event_map *btp, struct bpf_prog *prog)
int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id, int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
u32 *fd_type, const char **buf, u32 *fd_type, const char **buf,
u64 *probe_offset, u64 *probe_addr) u64 *probe_offset, u64 *probe_addr,
unsigned long *missed)
{ {
bool is_tracepoint, is_syscall_tp; bool is_tracepoint, is_syscall_tp;
struct bpf_prog *prog; struct bpf_prog *prog;
@ -2423,7 +2424,7 @@ int bpf_get_perf_event_info(const struct perf_event *event, u32 *prog_id,
#ifdef CONFIG_KPROBE_EVENTS #ifdef CONFIG_KPROBE_EVENTS
if (flags & TRACE_EVENT_FL_KPROBE) if (flags & TRACE_EVENT_FL_KPROBE)
err = bpf_get_kprobe_info(event, fd_type, buf, err = bpf_get_kprobe_info(event, fd_type, buf,
probe_offset, probe_addr, probe_offset, probe_addr, missed,
event->attr.type == PERF_TYPE_TRACEPOINT); event->attr.type == PERF_TYPE_TRACEPOINT);
#endif #endif
#ifdef CONFIG_UPROBE_EVENTS #ifdef CONFIG_UPROBE_EVENTS

View File

@ -1249,6 +1249,12 @@ static const struct file_operations kprobe_events_ops = {
.write = probes_write, .write = probes_write,
}; };
static unsigned long trace_kprobe_missed(struct trace_kprobe *tk)
{
return trace_kprobe_is_return(tk) ?
tk->rp.kp.nmissed + tk->rp.nmissed : tk->rp.kp.nmissed;
}
/* Probes profiling interfaces */ /* Probes profiling interfaces */
static int probes_profile_seq_show(struct seq_file *m, void *v) static int probes_profile_seq_show(struct seq_file *m, void *v)
{ {
@ -1260,8 +1266,7 @@ static int probes_profile_seq_show(struct seq_file *m, void *v)
return 0; return 0;
tk = to_trace_kprobe(ev); tk = to_trace_kprobe(ev);
nmissed = trace_kprobe_is_return(tk) ? nmissed = trace_kprobe_missed(tk);
tk->rp.kp.nmissed + tk->rp.nmissed : tk->rp.kp.nmissed;
seq_printf(m, " %-44s %15lu %15lu\n", seq_printf(m, " %-44s %15lu %15lu\n",
trace_probe_name(&tk->tp), trace_probe_name(&tk->tp),
trace_kprobe_nhit(tk), trace_kprobe_nhit(tk),
@ -1607,7 +1612,8 @@ NOKPROBE_SYMBOL(kretprobe_perf_func);
int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type, int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
const char **symbol, u64 *probe_offset, const char **symbol, u64 *probe_offset,
u64 *probe_addr, bool perf_type_tracepoint) u64 *probe_addr, unsigned long *missed,
bool perf_type_tracepoint)
{ {
const char *pevent = trace_event_name(event->tp_event); const char *pevent = trace_event_name(event->tp_event);
const char *group = event->tp_event->class->system; const char *group = event->tp_event->class->system;
@ -1626,6 +1632,8 @@ int bpf_get_kprobe_info(const struct perf_event *event, u32 *fd_type,
*probe_addr = kallsyms_show_value(current_cred()) ? *probe_addr = kallsyms_show_value(current_cred()) ?
(unsigned long)tk->rp.kp.addr : 0; (unsigned long)tk->rp.kp.addr : 0;
*symbol = tk->symbol; *symbol = tk->symbol;
if (missed)
*missed = trace_kprobe_missed(tk);
return 0; return 0;
} }
#endif /* CONFIG_PERF_EVENTS */ #endif /* CONFIG_PERF_EVENTS */

View File

@ -6559,20 +6559,27 @@ struct bpf_link_info {
__aligned_u64 file_name; /* in/out */ __aligned_u64 file_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 offset; /* offset from file_name */ __u32 offset; /* offset from file_name */
__u64 cookie;
} uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */ } uprobe; /* BPF_PERF_EVENT_UPROBE, BPF_PERF_EVENT_URETPROBE */
struct { struct {
__aligned_u64 func_name; /* in/out */ __aligned_u64 func_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 offset; /* offset from func_name */ __u32 offset; /* offset from func_name */
__u64 addr; __u64 addr;
__u64 missed;
__u64 cookie;
} kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */ } kprobe; /* BPF_PERF_EVENT_KPROBE, BPF_PERF_EVENT_KRETPROBE */
struct { struct {
__aligned_u64 tp_name; /* in/out */ __aligned_u64 tp_name; /* in/out */
__u32 name_len; __u32 name_len;
__u32 :32;
__u64 cookie;
} tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */ } tracepoint; /* BPF_PERF_EVENT_TRACEPOINT */
struct { struct {
__u64 config; __u64 config;
__u32 type; __u32 type;
__u32 :32;
__u64 cookie;
} event; /* BPF_PERF_EVENT_EVENT */ } event; /* BPF_PERF_EVENT_EVENT */
}; };
} perf_event; } perf_event;

View File

@ -30,6 +30,8 @@ static noinline void uprobe_func(void)
asm volatile (""); asm volatile ("");
} }
#define PERF_EVENT_COOKIE 0xdeadbeef
static int verify_perf_link_info(int fd, enum bpf_perf_event_type type, long addr, static int verify_perf_link_info(int fd, enum bpf_perf_event_type type, long addr,
ssize_t offset, ssize_t entry_offset) ssize_t offset, ssize_t entry_offset)
{ {
@ -61,8 +63,11 @@ again:
ASSERT_EQ(info.perf_event.kprobe.addr, addr + entry_offset, ASSERT_EQ(info.perf_event.kprobe.addr, addr + entry_offset,
"kprobe_addr"); "kprobe_addr");
ASSERT_EQ(info.perf_event.kprobe.cookie, PERF_EVENT_COOKIE, "kprobe_cookie");
ASSERT_EQ(info.perf_event.kprobe.name_len, strlen(KPROBE_FUNC) + 1,
"name_len");
if (!info.perf_event.kprobe.func_name) { if (!info.perf_event.kprobe.func_name) {
ASSERT_EQ(info.perf_event.kprobe.name_len, 0, "name_len");
info.perf_event.kprobe.func_name = ptr_to_u64(&buf); info.perf_event.kprobe.func_name = ptr_to_u64(&buf);
info.perf_event.kprobe.name_len = sizeof(buf); info.perf_event.kprobe.name_len = sizeof(buf);
goto again; goto again;
@ -73,13 +78,16 @@ again:
ASSERT_EQ(err, 0, "cmp_kprobe_func_name"); ASSERT_EQ(err, 0, "cmp_kprobe_func_name");
break; break;
case BPF_PERF_EVENT_TRACEPOINT: case BPF_PERF_EVENT_TRACEPOINT:
ASSERT_EQ(info.perf_event.tracepoint.name_len, strlen(TP_NAME) + 1,
"name_len");
if (!info.perf_event.tracepoint.tp_name) { if (!info.perf_event.tracepoint.tp_name) {
ASSERT_EQ(info.perf_event.tracepoint.name_len, 0, "name_len");
info.perf_event.tracepoint.tp_name = ptr_to_u64(&buf); info.perf_event.tracepoint.tp_name = ptr_to_u64(&buf);
info.perf_event.tracepoint.name_len = sizeof(buf); info.perf_event.tracepoint.name_len = sizeof(buf);
goto again; goto again;
} }
ASSERT_EQ(info.perf_event.tracepoint.cookie, PERF_EVENT_COOKIE, "tracepoint_cookie");
err = strncmp(u64_to_ptr(info.perf_event.tracepoint.tp_name), TP_NAME, err = strncmp(u64_to_ptr(info.perf_event.tracepoint.tp_name), TP_NAME,
strlen(TP_NAME)); strlen(TP_NAME));
ASSERT_EQ(err, 0, "cmp_tp_name"); ASSERT_EQ(err, 0, "cmp_tp_name");
@ -88,13 +96,16 @@ again:
case BPF_PERF_EVENT_URETPROBE: case BPF_PERF_EVENT_URETPROBE:
ASSERT_EQ(info.perf_event.uprobe.offset, offset, "uprobe_offset"); ASSERT_EQ(info.perf_event.uprobe.offset, offset, "uprobe_offset");
ASSERT_EQ(info.perf_event.uprobe.name_len, strlen(UPROBE_FILE) + 1,
"name_len");
if (!info.perf_event.uprobe.file_name) { if (!info.perf_event.uprobe.file_name) {
ASSERT_EQ(info.perf_event.uprobe.name_len, 0, "name_len");
info.perf_event.uprobe.file_name = ptr_to_u64(&buf); info.perf_event.uprobe.file_name = ptr_to_u64(&buf);
info.perf_event.uprobe.name_len = sizeof(buf); info.perf_event.uprobe.name_len = sizeof(buf);
goto again; goto again;
} }
ASSERT_EQ(info.perf_event.uprobe.cookie, PERF_EVENT_COOKIE, "uprobe_cookie");
err = strncmp(u64_to_ptr(info.perf_event.uprobe.file_name), UPROBE_FILE, err = strncmp(u64_to_ptr(info.perf_event.uprobe.file_name), UPROBE_FILE,
strlen(UPROBE_FILE)); strlen(UPROBE_FILE));
ASSERT_EQ(err, 0, "cmp_file_name"); ASSERT_EQ(err, 0, "cmp_file_name");
@ -138,16 +149,17 @@ static void test_kprobe_fill_link_info(struct test_fill_link_info *skel,
DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts, DECLARE_LIBBPF_OPTS(bpf_kprobe_opts, opts,
.attach_mode = PROBE_ATTACH_MODE_LINK, .attach_mode = PROBE_ATTACH_MODE_LINK,
.retprobe = type == BPF_PERF_EVENT_KRETPROBE, .retprobe = type == BPF_PERF_EVENT_KRETPROBE,
.bpf_cookie = PERF_EVENT_COOKIE,
); );
ssize_t entry_offset = 0; ssize_t entry_offset = 0;
struct bpf_link *link;
int link_fd, err; int link_fd, err;
skel->links.kprobe_run = bpf_program__attach_kprobe_opts(skel->progs.kprobe_run, link = bpf_program__attach_kprobe_opts(skel->progs.kprobe_run, KPROBE_FUNC, &opts);
KPROBE_FUNC, &opts); if (!ASSERT_OK_PTR(link, "attach_kprobe"))
if (!ASSERT_OK_PTR(skel->links.kprobe_run, "attach_kprobe"))
return; return;
link_fd = bpf_link__fd(skel->links.kprobe_run); link_fd = bpf_link__fd(link);
if (!invalid) { if (!invalid) {
/* See also arch_adjust_kprobe_addr(). */ /* See also arch_adjust_kprobe_addr(). */
if (skel->kconfig->CONFIG_X86_KERNEL_IBT) if (skel->kconfig->CONFIG_X86_KERNEL_IBT)
@ -157,39 +169,48 @@ static void test_kprobe_fill_link_info(struct test_fill_link_info *skel,
} else { } else {
kprobe_fill_invalid_user_buffer(link_fd); kprobe_fill_invalid_user_buffer(link_fd);
} }
bpf_link__detach(skel->links.kprobe_run); bpf_link__destroy(link);
} }
static void test_tp_fill_link_info(struct test_fill_link_info *skel) static void test_tp_fill_link_info(struct test_fill_link_info *skel)
{ {
DECLARE_LIBBPF_OPTS(bpf_tracepoint_opts, opts,
.bpf_cookie = PERF_EVENT_COOKIE,
);
struct bpf_link *link;
int link_fd, err; int link_fd, err;
skel->links.tp_run = bpf_program__attach_tracepoint(skel->progs.tp_run, TP_CAT, TP_NAME); link = bpf_program__attach_tracepoint_opts(skel->progs.tp_run, TP_CAT, TP_NAME, &opts);
if (!ASSERT_OK_PTR(skel->links.tp_run, "attach_tp")) if (!ASSERT_OK_PTR(link, "attach_tp"))
return; return;
link_fd = bpf_link__fd(skel->links.tp_run); link_fd = bpf_link__fd(link);
err = verify_perf_link_info(link_fd, BPF_PERF_EVENT_TRACEPOINT, 0, 0, 0); err = verify_perf_link_info(link_fd, BPF_PERF_EVENT_TRACEPOINT, 0, 0, 0);
ASSERT_OK(err, "verify_perf_link_info"); ASSERT_OK(err, "verify_perf_link_info");
bpf_link__detach(skel->links.tp_run); bpf_link__destroy(link);
} }
static void test_uprobe_fill_link_info(struct test_fill_link_info *skel, static void test_uprobe_fill_link_info(struct test_fill_link_info *skel,
enum bpf_perf_event_type type) enum bpf_perf_event_type type)
{ {
DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, opts,
.retprobe = type == BPF_PERF_EVENT_URETPROBE,
.bpf_cookie = PERF_EVENT_COOKIE,
);
struct bpf_link *link;
int link_fd, err; int link_fd, err;
skel->links.uprobe_run = bpf_program__attach_uprobe(skel->progs.uprobe_run, link = bpf_program__attach_uprobe_opts(skel->progs.uprobe_run,
type == BPF_PERF_EVENT_URETPROBE,
0, /* self pid */ 0, /* self pid */
UPROBE_FILE, uprobe_offset); UPROBE_FILE, uprobe_offset,
if (!ASSERT_OK_PTR(skel->links.uprobe_run, "attach_uprobe")) &opts);
if (!ASSERT_OK_PTR(link, "attach_uprobe"))
return; return;
link_fd = bpf_link__fd(skel->links.uprobe_run); link_fd = bpf_link__fd(link);
err = verify_perf_link_info(link_fd, type, 0, uprobe_offset, 0); err = verify_perf_link_info(link_fd, type, 0, uprobe_offset, 0);
ASSERT_OK(err, "verify_perf_link_info"); ASSERT_OK(err, "verify_perf_link_info");
bpf_link__detach(skel->links.uprobe_run); bpf_link__destroy(link);
} }
static int verify_kmulti_link_info(int fd, bool retprobe) static int verify_kmulti_link_info(int fd, bool retprobe)
@ -278,24 +299,24 @@ static void test_kprobe_multi_fill_link_info(struct test_fill_link_info *skel,
bool retprobe, bool invalid) bool retprobe, bool invalid)
{ {
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts); LIBBPF_OPTS(bpf_kprobe_multi_opts, opts);
struct bpf_link *link;
int link_fd, err; int link_fd, err;
opts.syms = kmulti_syms; opts.syms = kmulti_syms;
opts.cnt = KMULTI_CNT; opts.cnt = KMULTI_CNT;
opts.retprobe = retprobe; opts.retprobe = retprobe;
skel->links.kmulti_run = bpf_program__attach_kprobe_multi_opts(skel->progs.kmulti_run, link = bpf_program__attach_kprobe_multi_opts(skel->progs.kmulti_run, NULL, &opts);
NULL, &opts); if (!ASSERT_OK_PTR(link, "attach_kprobe_multi"))
if (!ASSERT_OK_PTR(skel->links.kmulti_run, "attach_kprobe_multi"))
return; return;
link_fd = bpf_link__fd(skel->links.kmulti_run); link_fd = bpf_link__fd(link);
if (!invalid) { if (!invalid) {
err = verify_kmulti_link_info(link_fd, retprobe); err = verify_kmulti_link_info(link_fd, retprobe);
ASSERT_OK(err, "verify_kmulti_link_info"); ASSERT_OK(err, "verify_kmulti_link_info");
} else { } else {
verify_kmulti_invalid_user_buffer(link_fd); verify_kmulti_invalid_user_buffer(link_fd);
} }
bpf_link__detach(skel->links.kmulti_run); bpf_link__destroy(link);
} }
void test_fill_link_info(void) void test_fill_link_info(void)