Skip to content

Commit abed79e

Browse files
Delyan KratunovKernel Patches Daemon
authored andcommitted
bpf: allow sleepable uprobe programs to attach
uprobe and kprobe programs have the same program type, KPROBE, which is currently not allowed to load sleepable programs. To avoid adding a new UPROBE type, we instead allow sleepable KPROBE programs to load and defer the is-it-actually-a-uprobe-program check to attachment time, where we're already validating the corresponding perf_event. A corollary of this patch is that you can now load a sleepable kprobe program but cannot attach it. Signed-off-by: Delyan Kratunov <delyank@fb.com> Acked-by: Andrii Nakryiko <andrii@kernel.org>
1 parent 6218f81 commit abed79e

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

kernel/bpf/verifier.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14570,8 +14570,8 @@ static int check_attach_btf_id(struct bpf_verifier_env *env)
1457014570
}
1457114571

1457214572
if (prog->aux->sleepable && prog->type != BPF_PROG_TYPE_TRACING &&
14573-
prog->type != BPF_PROG_TYPE_LSM) {
14574-
verbose(env, "Only fentry/fexit/fmod_ret and lsm programs can be sleepable\n");
14573+
prog->type != BPF_PROG_TYPE_LSM && prog->type != BPF_PROG_TYPE_KPROBE) {
14574+
verbose(env, "Only fentry/fexit/fmod_ret, lsm, and kprobe/uprobe programs can be sleepable\n");
1457514575
return -EINVAL;
1457614576
}
1457714577

kernel/events/core.c

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10069,26 +10069,30 @@ static inline bool perf_event_is_tracing(struct perf_event *event)
1006910069
int perf_event_set_bpf_prog(struct perf_event *event, struct bpf_prog *prog,
1007010070
u64 bpf_cookie)
1007110071
{
10072-
bool is_kprobe, is_tracepoint, is_syscall_tp;
10072+
bool is_kprobe, is_uprobe, is_tracepoint, is_syscall_tp;
1007310073

1007410074
if (!perf_event_is_tracing(event))
1007510075
return perf_event_set_bpf_handler(event, prog, bpf_cookie);
1007610076

10077-
is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_UKPROBE;
10077+
is_kprobe = event->tp_event->flags & TRACE_EVENT_FL_KPROBE;
10078+
is_uprobe = event->tp_event->flags & TRACE_EVENT_FL_UPROBE;
1007810079
is_tracepoint = event->tp_event->flags & TRACE_EVENT_FL_TRACEPOINT;
1007910080
is_syscall_tp = is_syscall_trace_event(event->tp_event);
10080-
if (!is_kprobe && !is_tracepoint && !is_syscall_tp)
10081+
if (!is_kprobe && !is_uprobe && !is_tracepoint && !is_syscall_tp)
1008110082
/* bpf programs can only be attached to u/kprobe or tracepoint */
1008210083
return -EINVAL;
1008310084

10084-
if ((is_kprobe && prog->type != BPF_PROG_TYPE_KPROBE) ||
10085+
if (((is_kprobe || is_uprobe) && prog->type != BPF_PROG_TYPE_KPROBE) ||
1008510086
(is_tracepoint && prog->type != BPF_PROG_TYPE_TRACEPOINT) ||
1008610087
(is_syscall_tp && prog->type != BPF_PROG_TYPE_TRACEPOINT))
1008710088
return -EINVAL;
1008810089

10090+
if (prog->type == BPF_PROG_TYPE_KPROBE && prog->aux->sleepable && !is_uprobe)
10091+
/* only uprobe programs are allowed to be sleepable */
10092+
return -EINVAL;
10093+
1008910094
/* Kprobe override only works for kprobes, not uprobes. */
10090-
if (prog->kprobe_override &&
10091-
!(event->tp_event->flags & TRACE_EVENT_FL_KPROBE))
10095+
if (prog->kprobe_override && !is_kprobe)
1009210096
return -EINVAL;
1009310097

1009410098
if (is_tracepoint || is_syscall_tp) {

0 commit comments

Comments
 (0)