Skip to content

Commit 5929a16

Browse files
Tao ChenKernel Patches Daemon
authored andcommitted
libbpf: Add libbpf_probe_bpf_kfunc API
Similarly to libbpf_probe_bpf_helper, the libbpf_probe_bpf_kfunc used to test the availability of the different eBPF kfuncs on the current system. Cc: Tao Chen <[email protected]> Reviewed-by: Jiri Olsa <[email protected]> Reviewed-by: Eduard Zingerman <[email protected]> Signed-off-by: Tao Chen <[email protected]>
1 parent e8bb0c3 commit 5929a16

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

tools/lib/bpf/libbpf.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1680,7 +1680,24 @@ LIBBPF_API int libbpf_probe_bpf_map_type(enum bpf_map_type map_type, const void
16801680
*/
16811681
LIBBPF_API int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type,
16821682
enum bpf_func_id helper_id, const void *opts);
1683-
1683+
/**
1684+
* @brief **libbpf_probe_bpf_kfunc()** detects if host kernel supports the
1685+
* use of a given BPF kfunc from specified BPF program type.
1686+
* @param prog_type BPF program type used to check the support of BPF kfunc
1687+
* @param kfunc_id The btf ID of BPF kfunc to check support for
1688+
* @param btf_fd The module BTF FD, if kfunc is defined in kernel module,
1689+
* btf_fd is used to point to module's BTF, which is >= 0, and < 0 means kfunc
1690+
* defined in vmlinux.
1691+
* @param opts reserved for future extensibility, should be NULL
1692+
* @return 1, if given combination of program type and kfunc is supported; 0,
1693+
* if the combination is not supported; negative error code if feature
1694+
* detection for provided input arguments failed or can't be performed
1695+
*
1696+
* Make sure the process has required set of CAP_* permissions (or runs as
1697+
* root) when performing feature checking.
1698+
*/
1699+
LIBBPF_API int libbpf_probe_bpf_kfunc(enum bpf_prog_type prog_type,
1700+
int kfunc_id, int btf_fd, const void *opts);
16841701
/**
16851702
* @brief **libbpf_num_possible_cpus()** is a helper function to get the
16861703
* number of possible CPUs that the host kernel supports and expects.

tools/lib/bpf/libbpf.map

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,4 +438,5 @@ LIBBPF_1.6.0 {
438438
bpf_linker__new_fd;
439439
btf__add_decl_attr;
440440
btf__add_type_attr;
441+
libbpf_probe_bpf_kfunc;
441442
} LIBBPF_1.5.0;

tools/lib/bpf/libbpf_probes.c

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,57 @@ static bool can_probe_prog_type(enum bpf_prog_type prog_type)
431431
return true;
432432
}
433433

434+
int libbpf_probe_bpf_kfunc(enum bpf_prog_type prog_type, int kfunc_id, int btf_fd,
435+
const void *opts)
436+
{
437+
struct bpf_insn insns[] = {
438+
BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, BPF_PSEUDO_KFUNC_CALL, 1, kfunc_id),
439+
BPF_EXIT_INSN(),
440+
};
441+
const size_t insn_cnt = ARRAY_SIZE(insns);
442+
char buf[4096];
443+
int fd_array[2] = {-1};
444+
int ret;
445+
446+
if (opts)
447+
return libbpf_err(-EINVAL);
448+
449+
if (!can_probe_prog_type(prog_type))
450+
return libbpf_err(-EOPNOTSUPP);
451+
452+
if (btf_fd >= 0)
453+
fd_array[1] = btf_fd;
454+
else
455+
/* insn.off = 0, means vmlinux btf */
456+
insns[0].off = 0;
457+
458+
buf[0] = '\0';
459+
ret = probe_prog_load(prog_type, insns, insn_cnt, btf_fd >= 0 ? fd_array : NULL,
460+
buf, sizeof(buf));
461+
if (ret < 0)
462+
return libbpf_err(ret);
463+
464+
if (ret > 0)
465+
return 1; /* assume supported */
466+
467+
/* If BPF verifier recognizes BPF kfunc but it's not supported for
468+
* given BPF program type, it will emit "calling kernel function
469+
* <name> is not allowed". If the kfunc id is invalid,
470+
* it will emit "kernel btf_id <id> is not a function". If BTF fd
471+
* invalid in module BTF, it will emit "invalid module BTF fd specified" or
472+
* "negative offset disallowed for kernel module function call". If
473+
* kfunc prog not dev buound, it will emit "metadata kfuncs require
474+
* device-bound program".
475+
*/
476+
if (strstr(buf, "not allowed") || strstr(buf, "not a function") ||
477+
strstr(buf, "invalid module BTF fd") ||
478+
strstr(buf, "negative offset disallowed") ||
479+
strstr(buf, "device-bound program"))
480+
return 0;
481+
482+
return 1;
483+
}
484+
434485
int libbpf_probe_bpf_helper(enum bpf_prog_type prog_type, enum bpf_func_id helper_id,
435486
const void *opts)
436487
{

0 commit comments

Comments
 (0)