libbpf: Add support for kprobe session attach
Adding support to attach program in kprobe session mode with bpf_program__attach_kprobe_multi_opts function. Adding session bool to bpf_kprobe_multi_opts struct that allows to load and attach the bpf program via kprobe session. the attachment to create kprobe multi session. Also adding new program loader section that allows: SEC("kprobe.session/bpf_fentry_test*") and loads/attaches kprobe program as kprobe session. Signed-off-by: Jiri Olsa <jolsa@kernel.org> Signed-off-by: Andrii Nakryiko <andrii@kernel.org> Acked-by: Andrii Nakryiko <andrii@kernel.org> Link: https://lore.kernel.org/bpf/20240430112830.1184228-5-jolsa@kernel.org
This commit is contained in:
parent
5c919acef8
commit
2ca178f02b
3 changed files with 41 additions and 3 deletions
|
@ -766,6 +766,7 @@ int bpf_link_create(int prog_fd, int target_fd,
|
||||||
return libbpf_err(-EINVAL);
|
return libbpf_err(-EINVAL);
|
||||||
break;
|
break;
|
||||||
case BPF_TRACE_KPROBE_MULTI:
|
case BPF_TRACE_KPROBE_MULTI:
|
||||||
|
case BPF_TRACE_KPROBE_SESSION:
|
||||||
attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0);
|
attr.link_create.kprobe_multi.flags = OPTS_GET(opts, kprobe_multi.flags, 0);
|
||||||
attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0);
|
attr.link_create.kprobe_multi.cnt = OPTS_GET(opts, kprobe_multi.cnt, 0);
|
||||||
attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
|
attr.link_create.kprobe_multi.syms = ptr_to_u64(OPTS_GET(opts, kprobe_multi.syms, 0));
|
||||||
|
|
|
@ -9273,6 +9273,7 @@ static int attach_tp(const struct bpf_program *prog, long cookie, struct bpf_lin
|
||||||
static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_raw_tp(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_trace(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
|
static int attach_kprobe_session(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_lsm(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
static int attach_iter(const struct bpf_program *prog, long cookie, struct bpf_link **link);
|
||||||
|
@ -9289,6 +9290,7 @@ static const struct bpf_sec_def section_defs[] = {
|
||||||
SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
|
SEC_DEF("uretprobe.s+", KPROBE, 0, SEC_SLEEPABLE, attach_uprobe),
|
||||||
SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
SEC_DEF("kprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
||||||
SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
SEC_DEF("kretprobe.multi+", KPROBE, BPF_TRACE_KPROBE_MULTI, SEC_NONE, attach_kprobe_multi),
|
||||||
|
SEC_DEF("kprobe.session+", KPROBE, BPF_TRACE_KPROBE_SESSION, SEC_NONE, attach_kprobe_session),
|
||||||
SEC_DEF("uprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
SEC_DEF("uprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
||||||
SEC_DEF("uretprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
SEC_DEF("uretprobe.multi+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_NONE, attach_uprobe_multi),
|
||||||
SEC_DEF("uprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),
|
SEC_DEF("uprobe.multi.s+", KPROBE, BPF_TRACE_UPROBE_MULTI, SEC_SLEEPABLE, attach_uprobe_multi),
|
||||||
|
@ -11381,13 +11383,14 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||||
struct kprobe_multi_resolve res = {
|
struct kprobe_multi_resolve res = {
|
||||||
.pattern = pattern,
|
.pattern = pattern,
|
||||||
};
|
};
|
||||||
|
enum bpf_attach_type attach_type;
|
||||||
struct bpf_link *link = NULL;
|
struct bpf_link *link = NULL;
|
||||||
char errmsg[STRERR_BUFSIZE];
|
char errmsg[STRERR_BUFSIZE];
|
||||||
const unsigned long *addrs;
|
const unsigned long *addrs;
|
||||||
int err, link_fd, prog_fd;
|
int err, link_fd, prog_fd;
|
||||||
|
bool retprobe, session;
|
||||||
const __u64 *cookies;
|
const __u64 *cookies;
|
||||||
const char **syms;
|
const char **syms;
|
||||||
bool retprobe;
|
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
|
|
||||||
if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))
|
if (!OPTS_VALID(opts, bpf_kprobe_multi_opts))
|
||||||
|
@ -11426,6 +11429,12 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||||
}
|
}
|
||||||
|
|
||||||
retprobe = OPTS_GET(opts, retprobe, false);
|
retprobe = OPTS_GET(opts, retprobe, false);
|
||||||
|
session = OPTS_GET(opts, session, false);
|
||||||
|
|
||||||
|
if (retprobe && session)
|
||||||
|
return libbpf_err_ptr(-EINVAL);
|
||||||
|
|
||||||
|
attach_type = session ? BPF_TRACE_KPROBE_SESSION : BPF_TRACE_KPROBE_MULTI;
|
||||||
|
|
||||||
lopts.kprobe_multi.syms = syms;
|
lopts.kprobe_multi.syms = syms;
|
||||||
lopts.kprobe_multi.addrs = addrs;
|
lopts.kprobe_multi.addrs = addrs;
|
||||||
|
@ -11440,7 +11449,7 @@ bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||||
}
|
}
|
||||||
link->detach = &bpf_link__detach_fd;
|
link->detach = &bpf_link__detach_fd;
|
||||||
|
|
||||||
link_fd = bpf_link_create(prog_fd, 0, BPF_TRACE_KPROBE_MULTI, &lopts);
|
link_fd = bpf_link_create(prog_fd, 0, attach_type, &lopts);
|
||||||
if (link_fd < 0) {
|
if (link_fd < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
pr_warn("prog '%s': failed to attach: %s\n",
|
pr_warn("prog '%s': failed to attach: %s\n",
|
||||||
|
@ -11546,6 +11555,32 @@ static int attach_kprobe_multi(const struct bpf_program *prog, long cookie, stru
|
||||||
return libbpf_get_error(*link);
|
return libbpf_get_error(*link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int attach_kprobe_session(const struct bpf_program *prog, long cookie,
|
||||||
|
struct bpf_link **link)
|
||||||
|
{
|
||||||
|
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts, .session = true);
|
||||||
|
const char *spec;
|
||||||
|
char *pattern;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
*link = NULL;
|
||||||
|
|
||||||
|
/* no auto-attach for SEC("kprobe.session") */
|
||||||
|
if (strcmp(prog->sec_name, "kprobe.session") == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
spec = prog->sec_name + sizeof("kprobe.session/") - 1;
|
||||||
|
n = sscanf(spec, "%m[a-zA-Z0-9_.*?]", &pattern);
|
||||||
|
if (n < 1) {
|
||||||
|
pr_warn("kprobe session pattern is invalid: %s\n", pattern);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
*link = bpf_program__attach_kprobe_multi_opts(prog, pattern, &opts);
|
||||||
|
free(pattern);
|
||||||
|
return *link ? 0 : -errno;
|
||||||
|
}
|
||||||
|
|
||||||
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)
|
static int attach_uprobe_multi(const struct bpf_program *prog, long cookie, struct bpf_link **link)
|
||||||
{
|
{
|
||||||
char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
|
char *probe_type = NULL, *binary_path = NULL, *func_name = NULL;
|
||||||
|
|
|
@ -539,10 +539,12 @@ struct bpf_kprobe_multi_opts {
|
||||||
size_t cnt;
|
size_t cnt;
|
||||||
/* create return kprobes */
|
/* create return kprobes */
|
||||||
bool retprobe;
|
bool retprobe;
|
||||||
|
/* create session kprobes */
|
||||||
|
bool session;
|
||||||
size_t :0;
|
size_t :0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define bpf_kprobe_multi_opts__last_field retprobe
|
#define bpf_kprobe_multi_opts__last_field session
|
||||||
|
|
||||||
LIBBPF_API struct bpf_link *
|
LIBBPF_API struct bpf_link *
|
||||||
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
bpf_program__attach_kprobe_multi_opts(const struct bpf_program *prog,
|
||||||
|
|
Loading…
Add table
Reference in a new issue