Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions include/linux/bpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -1376,6 +1376,11 @@ struct bpf_tramp_image {
struct rcu_head rcu;
struct work_struct work;
};
#ifdef CONFIG_PREEMPTION
/* Programs called from this image must outlive deferred image freeing. */
struct bpf_prog *progs[BPF_MAX_TRAMP_LINKS];
int nr_progs;
#endif
};

struct bpf_trampoline {
Expand Down
20 changes: 20 additions & 0 deletions kernel/bpf/trampoline.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,13 @@ bpf_trampoline_get_progs(const struct bpf_trampoline *tr, int *total, bool *ip_a

static void bpf_tramp_image_free(struct bpf_tramp_image *im)
{
#ifdef CONFIG_PREEMPTION
int i;

for (i = 0; i < im->nr_progs; i++)
bpf_prog_put(im->progs[i]);
#endif

bpf_image_ksym_del(&im->ksym);
arch_free_bpf_trampoline(im->image, im->size);
bpf_jit_uncharge_modmem(im->size);
Expand Down Expand Up @@ -678,6 +685,9 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
u32 orig_flags = tr->flags;
bool ip_arg = false;
int err, total, size;
#ifdef CONFIG_PREEMPTION
int i, kind;
#endif

tnodes = bpf_trampoline_get_progs(tr, &total, &ip_arg);
if (IS_ERR(tnodes))
Expand Down Expand Up @@ -740,6 +750,16 @@ static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mut
goto out;
}

#ifdef CONFIG_PREEMPTION
for (kind = 0; kind < BPF_TRAMP_MAX; kind++)
for (i = 0; i < tnodes[kind].nr_nodes; i++) {
struct bpf_prog *prog = tnodes[kind].nodes[i]->link->prog;

bpf_prog_inc(prog);
im->progs[im->nr_progs++] = prog;
}
#endif

err = arch_prepare_bpf_trampoline(im, im->image, im->image + size,
&tr->func.model, tr->flags, tnodes,
tr->func.addr);
Expand Down
Loading