kernel/bpf/bpf_struct_ops.c

Source file repositories/reference/linux-study-clean/kernel/bpf/bpf_struct_ops.c

File Facts

System
Linux kernel
Corpus path
kernel/bpf/bpf_struct_ops.c
Extension
.c
Size
40957 bytes
Lines
1530
Domain
Core OS
Bucket
Scheduler, Processes, Timers, Sync, And Syscalls
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct bpf_struct_ops_value {
	struct bpf_struct_ops_common_value common;
	char data[] ____cacheline_aligned_in_smp;
};

#define MAX_TRAMP_IMAGE_PAGES 8

struct bpf_struct_ops_map {
	struct bpf_map map;
	const struct bpf_struct_ops_desc *st_ops_desc;
	/* protect map_update */
	struct mutex lock;
	/* link has all the bpf_links that is populated
	 * to the func ptr of the kernel's struct
	 * (in kvalue.data).
	 */
	struct bpf_link **links;
	/* ksyms for bpf trampolines */
	struct bpf_ksym **ksyms;
	u32 funcs_cnt;
	u32 image_pages_cnt;
	/* image_pages is an array of pages that has all the trampolines
	 * that stores the func args before calling the bpf_prog.
	 */
	void *image_pages[MAX_TRAMP_IMAGE_PAGES];
	/* The owner moduler's btf. */
	struct btf *btf;
	/* uvalue->data stores the kernel struct
	 * (e.g. tcp_congestion_ops) that is more useful
	 * to userspace than the kvalue.  For example,
	 * the bpf_prog's id is stored instead of the kernel
	 * address of a func ptr.
	 */
	struct bpf_struct_ops_value *uvalue;
	/* kvalue.data stores the actual kernel's struct
	 * (e.g. tcp_congestion_ops) that will be
	 * registered to the kernel subsystem.
	 */
	struct bpf_struct_ops_value kvalue;
};

struct bpf_struct_ops_link {
	struct bpf_link link;
	struct bpf_map __rcu *map;
	wait_queue_head_t wait_hup;
};

static DEFINE_MUTEX(update_mutex);

#define VALUE_PREFIX "bpf_struct_ops_"
#define VALUE_PREFIX_LEN (sizeof(VALUE_PREFIX) - 1)

const struct bpf_verifier_ops bpf_struct_ops_verifier_ops = {
};

const struct bpf_prog_ops bpf_struct_ops_prog_ops = {
#ifdef CONFIG_NET
	.test_run = bpf_struct_ops_test_run,
#endif
};

BTF_ID_LIST(st_ops_ids)
BTF_ID(struct, module)
BTF_ID(struct, bpf_struct_ops_common_value)

enum {
	IDX_MODULE_ID,
	IDX_ST_OPS_COMMON_VALUE_ID,
};

extern struct btf *btf_vmlinux;

static bool is_valid_value_type(struct btf *btf, s32 value_id,
				const struct btf_type *type,
				const char *value_name)
{
	const struct btf_type *common_value_type;
	const struct btf_member *member;
	const struct btf_type *vt, *mt;

	vt = btf_type_by_id(btf, value_id);
	if (btf_vlen(vt) != 2) {
		pr_warn("The number of %s's members should be 2, but we get %d\n",
			value_name, btf_vlen(vt));
		return false;
	}
	member = btf_type_member(vt);
	mt = btf_type_by_id(btf, member->type);
	common_value_type = btf_type_by_id(btf_vmlinux,
					   st_ops_ids[IDX_ST_OPS_COMMON_VALUE_ID]);

Annotation

Implementation Notes