@@ -371,15 +371,13 @@ static const char *type_from_btf_id(struct btf *btf, s32 id)
371371 return NULL ;
372372}
373373
374- static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
375- bool tracepoint )
374+ static const struct btf_type * find_btf_func_proto (const char * funcname )
376375{
377376 struct btf * btf = traceprobe_get_btf ();
378- const struct btf_param * param ;
379377 const struct btf_type * t ;
380378 s32 id ;
381379
382- if (!btf || !funcname || ! nr )
380+ if (!btf || !funcname )
383381 return ERR_PTR (- EINVAL );
384382
385383 id = btf_find_by_name_kind (btf , funcname , BTF_KIND_FUNC );
@@ -396,6 +394,22 @@ static const struct btf_param *find_btf_func_param(const char *funcname, s32 *nr
396394 if (!btf_type_is_func_proto (t ))
397395 return ERR_PTR (- ENOENT );
398396
397+ return t ;
398+ }
399+
400+ static const struct btf_param * find_btf_func_param (const char * funcname , s32 * nr ,
401+ bool tracepoint )
402+ {
403+ const struct btf_param * param ;
404+ const struct btf_type * t ;
405+
406+ if (!funcname || !nr )
407+ return ERR_PTR (- EINVAL );
408+
409+ t = find_btf_func_proto (funcname );
410+ if (IS_ERR (t ))
411+ return (const struct btf_param * )t ;
412+
399413 * nr = btf_type_vlen (t );
400414 param = (const struct btf_param * )(t + 1 );
401415
@@ -462,6 +476,32 @@ static const struct fetch_type *parse_btf_arg_type(int arg_idx,
462476 return find_fetch_type (typestr , ctx -> flags );
463477}
464478
479+ static const struct fetch_type * parse_btf_retval_type (
480+ struct traceprobe_parse_context * ctx )
481+ {
482+ struct btf * btf = traceprobe_get_btf ();
483+ const char * typestr = NULL ;
484+ const struct btf_type * t ;
485+
486+ if (btf && ctx -> funcname ) {
487+ t = find_btf_func_proto (ctx -> funcname );
488+ if (!IS_ERR (t ))
489+ typestr = type_from_btf_id (btf , t -> type );
490+ }
491+
492+ return find_fetch_type (typestr , ctx -> flags );
493+ }
494+
495+ static bool is_btf_retval_void (const char * funcname )
496+ {
497+ const struct btf_type * t ;
498+
499+ t = find_btf_func_proto (funcname );
500+ if (IS_ERR (t ))
501+ return false;
502+
503+ return t -> type == 0 ;
504+ }
465505#else
466506static struct btf * traceprobe_get_btf (void )
467507{
@@ -480,8 +520,15 @@ static int parse_btf_arg(const char *varname, struct fetch_insn *code,
480520 trace_probe_log_err (ctx -> offset , NOSUP_BTFARG );
481521 return - EOPNOTSUPP ;
482522}
523+
483524#define parse_btf_arg_type (idx , ctx ) \
484525 find_fetch_type(NULL, ctx->flags)
526+
527+ #define parse_btf_retval_type (ctx ) \
528+ find_fetch_type(NULL, ctx->flags)
529+
530+ #define is_btf_retval_void (funcname ) (false)
531+
485532#endif
486533
487534#define PARAM_MAX_STACK (THREAD_SIZE / sizeof(unsigned long))
@@ -512,6 +559,11 @@ static int parse_probe_vars(char *arg, const struct fetch_type *t,
512559
513560 if (strcmp (arg , "retval" ) == 0 ) {
514561 if (ctx -> flags & TPARG_FL_RETURN ) {
562+ if ((ctx -> flags & TPARG_FL_KERNEL ) &&
563+ is_btf_retval_void (ctx -> funcname )) {
564+ err = TP_ERR_NO_RETVAL ;
565+ goto inval ;
566+ }
515567 code -> op = FETCH_OP_RETVAL ;
516568 return 0 ;
517569 }
@@ -912,9 +964,12 @@ static int traceprobe_parse_probe_arg_body(const char *argv, ssize_t *size,
912964 goto fail ;
913965
914966 /* Update storing type if BTF is available */
915- if (IS_ENABLED (CONFIG_PROBE_EVENTS_BTF_ARGS ) &&
916- !t && code -> op == FETCH_OP_ARG )
917- parg -> type = parse_btf_arg_type (code -> param , ctx );
967+ if (IS_ENABLED (CONFIG_PROBE_EVENTS_BTF_ARGS ) && !t ) {
968+ if (code -> op == FETCH_OP_ARG )
969+ parg -> type = parse_btf_arg_type (code -> param , ctx );
970+ else if (code -> op == FETCH_OP_RETVAL )
971+ parg -> type = parse_btf_retval_type (ctx );
972+ }
918973
919974 ret = - EINVAL ;
920975 /* Store operation */
0 commit comments