diff options
Diffstat (limited to 'tools/lib/bpf/libbpf.c')
| -rw-r--r-- | tools/lib/bpf/libbpf.c | 85 | 
1 files changed, 41 insertions, 44 deletions
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 902f1ad5b7e6..9cb99d1e2385 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c @@ -187,42 +187,6 @@ const char *libbpf_version_string(void)  #undef __S  } -enum kern_feature_id { -	/* v4.14: kernel support for program & map names. */ -	FEAT_PROG_NAME, -	/* v5.2: kernel support for global data sections. */ -	FEAT_GLOBAL_DATA, -	/* BTF support */ -	FEAT_BTF, -	/* BTF_KIND_FUNC and BTF_KIND_FUNC_PROTO support */ -	FEAT_BTF_FUNC, -	/* BTF_KIND_VAR and BTF_KIND_DATASEC support */ -	FEAT_BTF_DATASEC, -	/* BTF_FUNC_GLOBAL is supported */ -	FEAT_BTF_GLOBAL_FUNC, -	/* BPF_F_MMAPABLE is supported for arrays */ -	FEAT_ARRAY_MMAP, -	/* kernel support for expected_attach_type in BPF_PROG_LOAD */ -	FEAT_EXP_ATTACH_TYPE, -	/* bpf_probe_read_{kernel,user}[_str] helpers */ -	FEAT_PROBE_READ_KERN, -	/* BPF_PROG_BIND_MAP is supported */ -	FEAT_PROG_BIND_MAP, -	/* Kernel support for module BTFs */ -	FEAT_MODULE_BTF, -	/* BTF_KIND_FLOAT support */ -	FEAT_BTF_FLOAT, -	/* BPF perf link support */ -	FEAT_PERF_LINK, -	/* BTF_KIND_DECL_TAG support */ -	FEAT_BTF_DECL_TAG, -	/* BTF_KIND_TYPE_TAG support */ -	FEAT_BTF_TYPE_TAG, -	__FEAT_CNT, -}; - -static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id); -  enum reloc_type {  	RELO_LD64,  	RELO_CALL, @@ -831,11 +795,36 @@ bpf_object__add_programs(struct bpf_object *obj, Elf_Data *sec_data,  	return 0;  } -static __u32 get_kernel_version(void) +__u32 get_kernel_version(void)  { +	/* On Ubuntu LINUX_VERSION_CODE doesn't correspond to info.release, +	 * but Ubuntu provides /proc/version_signature file, as described at +	 * https://ubuntu.com/kernel, with an example contents below, which we +	 * can use to get a proper LINUX_VERSION_CODE. +	 * +	 *   Ubuntu 5.4.0-12.15-generic 5.4.8 +	 * +	 * In the above, 5.4.8 is what kernel is actually expecting, while +	 * uname() call will return 5.4.0 in info.release. +	 */ +	const char *ubuntu_kver_file = "/proc/version_signature";  	__u32 major, minor, patch;  	struct utsname info; +	if (access(ubuntu_kver_file, R_OK) == 0) { +		FILE *f; + +		f = fopen(ubuntu_kver_file, "r"); +		if (f) { +			if (fscanf(f, "%*s %*s %d.%d.%d\n", &major, &minor, &patch) == 3) { +				fclose(f); +				return KERNEL_VERSION(major, minor, patch); +			} +			fclose(f); +		} +		/* something went wrong, fall back to uname() approach */ +	} +  	uname(&info);  	if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3)  		return 0; @@ -1201,12 +1190,10 @@ static struct bpf_object *bpf_object__new(const char *path,  	strcpy(obj->path, path);  	if (obj_name) { -		strncpy(obj->name, obj_name, sizeof(obj->name) - 1); -		obj->name[sizeof(obj->name) - 1] = 0; +		libbpf_strlcpy(obj->name, obj_name, sizeof(obj->name));  	} else {  		/* Using basename() GNU version which doesn't modify arg. */ -		strncpy(obj->name, basename((void *)path), -			sizeof(obj->name) - 1); +		libbpf_strlcpy(obj->name, basename((void *)path), sizeof(obj->name));  		end = strchr(obj->name, '.');  		if (end)  			*end = 0; @@ -1358,7 +1345,10 @@ static int bpf_object__check_endianness(struct bpf_object *obj)  static int  bpf_object__init_license(struct bpf_object *obj, void *data, size_t size)  { -	memcpy(obj->license, data, min(size, sizeof(obj->license) - 1)); +	/* libbpf_strlcpy() only copies first N - 1 bytes, so size + 1 won't +	 * go over allowed ELF data section buffer +	 */ +	libbpf_strlcpy(obj->license, data, min(size + 1, sizeof(obj->license)));  	pr_debug("license of %s is %s\n", obj->path, obj->license);  	return 0;  } @@ -4354,6 +4344,10 @@ bpf_object__probe_loading(struct bpf_object *obj)  	if (obj->gen_loader)  		return 0; +	ret = bump_rlimit_memlock(); +	if (ret) +		pr_warn("Failed to bump RLIMIT_MEMLOCK (err = %d), you might need to do it explicitly!\n", ret); +  	/* make sure basic loading works */  	ret = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, NULL, "GPL", insns, insn_cnt, NULL);  	if (ret < 0) @@ -4720,14 +4714,17 @@ static struct kern_feature_desc {  	[FEAT_BTF_TYPE_TAG] = {  		"BTF_KIND_TYPE_TAG support", probe_kern_btf_type_tag,  	}, +	[FEAT_MEMCG_ACCOUNT] = { +		"memcg-based memory accounting", probe_memcg_account, +	},  }; -static bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id) +bool kernel_supports(const struct bpf_object *obj, enum kern_feature_id feat_id)  {  	struct kern_feature_desc *feat = &feature_probes[feat_id];  	int ret; -	if (obj->gen_loader) +	if (obj && obj->gen_loader)  		/* To generate loader program assume the latest kernel  		 * to avoid doing extra prog_load, map_create syscalls.  		 */  | 
