Commit 31a645ae authored by Hou Tao's avatar Hou Tao Committed by Alexei Starovoitov
Browse files

bpf: Factor out a helper to prepare trampoline for struct_ops prog



Factor out a helper bpf_struct_ops_prepare_trampoline() to prepare
trampoline for BPF_PROG_TYPE_STRUCT_OPS prog. It will be used by
.test_run callback in following patch.

Signed-off-by: default avatarHou Tao <houtao1@huawei.com>
Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
Acked-by: default avatarMartin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20211025064025.2567443-2-houtao1@huawei.com
parent 36e70b9b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1000,6 +1000,10 @@ bool bpf_struct_ops_get(const void *kdata);
void bpf_struct_ops_put(const void *kdata);
int bpf_struct_ops_map_sys_lookup_elem(struct bpf_map *map, void *key,
				       void *value);
int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_progs *tprogs,
				      struct bpf_prog *prog,
				      const struct btf_func_model *model,
				      void *image, void *image_end);
static inline bool bpf_try_module_get(const void *data, struct module *owner)
{
	if (owner == BPF_MODULE_OWNER)
+19 −10
Original line number Diff line number Diff line
@@ -312,6 +312,20 @@ static int check_zero_holes(const struct btf_type *t, void *data)
	return 0;
}

int bpf_struct_ops_prepare_trampoline(struct bpf_tramp_progs *tprogs,
				      struct bpf_prog *prog,
				      const struct btf_func_model *model,
				      void *image, void *image_end)
{
	u32 flags;

	tprogs[BPF_TRAMP_FENTRY].progs[0] = prog;
	tprogs[BPF_TRAMP_FENTRY].nr_progs = 1;
	flags = model->ret_size > 0 ? BPF_TRAMP_F_RET_FENTRY_RET : 0;
	return arch_prepare_bpf_trampoline(NULL, image, image_end,
					   model, flags, tprogs, NULL);
}

static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
					  void *value, u64 flags)
{
@@ -323,7 +337,7 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
	struct bpf_tramp_progs *tprogs = NULL;
	void *udata, *kdata;
	int prog_fd, err = 0;
	void *image;
	void *image, *image_end;
	u32 i;

	if (flags)
@@ -363,12 +377,12 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
	udata = &uvalue->data;
	kdata = &kvalue->data;
	image = st_map->image;
	image_end = st_map->image + PAGE_SIZE;

	for_each_member(i, t, member) {
		const struct btf_type *mtype, *ptype;
		struct bpf_prog *prog;
		u32 moff;
		u32 flags;

		moff = btf_member_bit_offset(t, member) / 8;
		ptype = btf_type_resolve_ptr(btf_vmlinux, member->type, NULL);
@@ -430,14 +444,9 @@ static int bpf_struct_ops_map_update_elem(struct bpf_map *map, void *key,
			goto reset_unlock;
		}

		tprogs[BPF_TRAMP_FENTRY].progs[0] = prog;
		tprogs[BPF_TRAMP_FENTRY].nr_progs = 1;
		flags = st_ops->func_models[i].ret_size > 0 ?
			BPF_TRAMP_F_RET_FENTRY_RET : 0;
		err = arch_prepare_bpf_trampoline(NULL, image,
						  st_map->image + PAGE_SIZE,
		err = bpf_struct_ops_prepare_trampoline(tprogs, prog,
							&st_ops->func_models[i],
						  flags, tprogs, NULL);
							image, image_end);
		if (err < 0)
			goto reset_unlock;