@@ -433,6 +433,61 @@ static bool can_probe_prog_type(enum bpf_prog_type prog_type)
433433 return true;
434434}
435435
436+ int libbpf_probe_bpf_kfunc (enum bpf_prog_type prog_type , int kfunc_id , int btf_fd ,
437+ const void * opts )
438+ {
439+ struct bpf_insn insns [] = {
440+ BPF_RAW_INSN (BPF_JMP | BPF_CALL , 0 , BPF_PSEUDO_KFUNC_CALL , btf_fd , kfunc_id ),
441+ BPF_EXIT_INSN (),
442+ };
443+ const size_t insn_cnt = ARRAY_SIZE (insns );
444+ char buf [4096 ];
445+ int * fd_array = NULL ;
446+ size_t fd_array_cnt = 0 , fd_array_cap = fd_array_cnt ;
447+ int ret ;
448+
449+ if (opts )
450+ return libbpf_err (- EINVAL );
451+
452+ if (!can_probe_prog_type (prog_type ))
453+ return - EOPNOTSUPP ;
454+
455+ if (btf_fd ) {
456+ ret = libbpf_ensure_mem ((void * * )& fd_array , & fd_array_cap ,
457+ sizeof (int ), fd_array_cnt + btf_fd );
458+ if (ret )
459+ return ret ;
460+
461+ /* In kernel, obtain the btf fd by means of the offset of
462+ * the fd_array, and the offset is the btf fd.
463+ */
464+ fd_array [btf_fd ] = btf_fd ;
465+ }
466+
467+ buf [0 ] = '\0' ;
468+ ret = probe_prog_load (prog_type , insns , insn_cnt , fd_array ,
469+ fd_array_cnt , buf , sizeof (buf ));
470+ if (ret < 0 ) {
471+ free (fd_array );
472+ return libbpf_err (ret );
473+ }
474+
475+ free (fd_array );
476+ /* If BPF verifier recognizes BPF kfunc but it's not supported for
477+ * given BPF program type, it will emit "calling kernel function
478+ * bpf_cpumask_create is not allowed", if the kfunc id is invalid,
479+ * it will emit "kernel btf_id 4294967295 is not a function". If btf fd
480+ * invalid in module btf, it will emit "invalid module BTF fd specified" or
481+ * "negative offset disallowed for kernel module function call"
482+ */
483+ if (ret == 0 && (strstr (buf , "not allowed" ) || strstr (buf , "not a function" ) ||
484+ (strstr (buf , "invalid module BTF fd" )) ||
485+ (strstr (buf , "negative offset disallowed" ))))
486+ return 0 ;
487+
488+ return 1 ; /* assume supported */
489+ }
490+
436491int libbpf_probe_bpf_helper (enum bpf_prog_type prog_type , enum bpf_func_id helper_id ,
437492 const void * opts )
438493{
0 commit comments