@@ -906,6 +906,167 @@ int trace_kprobe_run_command(const char *command)
906906 return trace_run_command (command , create_or_delete_trace_kprobe );
907907}
908908
909+ static int trace_kprobe_run_cmd (struct dynevent_cmd * cmd )
910+ {
911+ return trace_run_command (cmd -> buf , create_or_delete_trace_kprobe );
912+ }
913+
914+ /**
915+ * kprobe_event_cmd_init - Initialize a kprobe event command object
916+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
917+ * @buf: A pointer to the buffer used to build the command
918+ * @maxlen: The length of the buffer passed in @buf
919+ *
920+ * Initialize a synthetic event command object. Use this before
921+ * calling any of the other kprobe_event functions.
922+ */
923+ void kprobe_event_cmd_init (struct dynevent_cmd * cmd , char * buf , int maxlen )
924+ {
925+ dynevent_cmd_init (cmd , buf , maxlen , DYNEVENT_TYPE_KPROBE ,
926+ trace_kprobe_run_cmd );
927+ }
928+ EXPORT_SYMBOL_GPL (kprobe_event_cmd_init );
929+
930+ /**
931+ * __kprobe_event_gen_cmd_start - Generate a kprobe event command from arg list
932+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
933+ * @name: The name of the kprobe event
934+ * @loc: The location of the kprobe event
935+ * @kretprobe: Is this a return probe?
936+ * @args: Variable number of arg (pairs), one pair for each field
937+ *
938+ * NOTE: Users normally won't want to call this function directly, but
939+ * rather use the kprobe_event_gen_cmd_start() wrapper, which automatically
940+ * adds a NULL to the end of the arg list. If this function is used
941+ * directly, make sure the last arg in the variable arg list is NULL.
942+ *
943+ * Generate a kprobe event command to be executed by
944+ * kprobe_event_gen_cmd_end(). This function can be used to generate the
945+ * complete command or only the first part of it; in the latter case,
946+ * kprobe_event_add_fields() can be used to add more fields following this.
947+ *
948+ * Return: 0 if successful, error otherwise.
949+ */
950+ int __kprobe_event_gen_cmd_start (struct dynevent_cmd * cmd , bool kretprobe ,
951+ const char * name , const char * loc , ...)
952+ {
953+ char buf [MAX_EVENT_NAME_LEN ];
954+ struct dynevent_arg arg ;
955+ va_list args ;
956+ int ret ;
957+
958+ if (cmd -> type != DYNEVENT_TYPE_KPROBE )
959+ return - EINVAL ;
960+
961+ if (kretprobe )
962+ snprintf (buf , MAX_EVENT_NAME_LEN , "r:kprobes/%s" , name );
963+ else
964+ snprintf (buf , MAX_EVENT_NAME_LEN , "p:kprobes/%s" , name );
965+
966+ ret = dynevent_str_add (cmd , buf );
967+ if (ret )
968+ return ret ;
969+
970+ dynevent_arg_init (& arg , NULL , 0 );
971+ arg .str = loc ;
972+ ret = dynevent_arg_add (cmd , & arg );
973+ if (ret )
974+ return ret ;
975+
976+ va_start (args , loc );
977+ for (;;) {
978+ const char * field ;
979+
980+ field = va_arg (args , const char * );
981+ if (!field )
982+ break ;
983+
984+ if (++ cmd -> n_fields > MAX_TRACE_ARGS ) {
985+ ret = - EINVAL ;
986+ break ;
987+ }
988+
989+ arg .str = field ;
990+ ret = dynevent_arg_add (cmd , & arg );
991+ if (ret )
992+ break ;
993+ }
994+ va_end (args );
995+
996+ return ret ;
997+ }
998+ EXPORT_SYMBOL_GPL (__kprobe_event_gen_cmd_start );
999+
1000+ /**
1001+ * __kprobe_event_add_fields - Add probe fields to a kprobe command from arg list
1002+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
1003+ * @args: Variable number of arg (pairs), one pair for each field
1004+ *
1005+ * NOTE: Users normally won't want to call this function directly, but
1006+ * rather use the kprobe_event_add_fields() wrapper, which
1007+ * automatically adds a NULL to the end of the arg list. If this
1008+ * function is used directly, make sure the last arg in the variable
1009+ * arg list is NULL.
1010+ *
1011+ * Add probe fields to an existing kprobe command using a variable
1012+ * list of args. Fields are added in the same order they're listed.
1013+ *
1014+ * Return: 0 if successful, error otherwise.
1015+ */
1016+ int __kprobe_event_add_fields (struct dynevent_cmd * cmd , ...)
1017+ {
1018+ struct dynevent_arg arg ;
1019+ va_list args ;
1020+ int ret ;
1021+
1022+ if (cmd -> type != DYNEVENT_TYPE_KPROBE )
1023+ return - EINVAL ;
1024+
1025+ dynevent_arg_init (& arg , NULL , 0 );
1026+
1027+ va_start (args , cmd );
1028+ for (;;) {
1029+ const char * field ;
1030+
1031+ field = va_arg (args , const char * );
1032+ if (!field )
1033+ break ;
1034+
1035+ if (++ cmd -> n_fields > MAX_TRACE_ARGS ) {
1036+ ret = - EINVAL ;
1037+ break ;
1038+ }
1039+
1040+ arg .str = field ;
1041+ ret = dynevent_arg_add (cmd , & arg );
1042+ if (ret )
1043+ break ;
1044+ }
1045+ va_end (args );
1046+
1047+ return ret ;
1048+ }
1049+ EXPORT_SYMBOL_GPL (__kprobe_event_add_fields );
1050+
1051+ /**
1052+ * kprobe_event_delete - Delete a kprobe event
1053+ * @name: The name of the kprobe event to delete
1054+ *
1055+ * Delete a kprobe event with the give @name from kernel code rather
1056+ * than directly from the command line.
1057+ *
1058+ * Return: 0 if successful, error otherwise.
1059+ */
1060+ int kprobe_event_delete (const char * name )
1061+ {
1062+ char buf [MAX_EVENT_NAME_LEN ];
1063+
1064+ snprintf (buf , MAX_EVENT_NAME_LEN , "-:%s" , name );
1065+
1066+ return trace_run_command (buf , create_or_delete_trace_kprobe );
1067+ }
1068+ EXPORT_SYMBOL_GPL (kprobe_event_delete );
1069+
9091070static int trace_kprobe_release (struct dyn_event * ev )
9101071{
9111072 struct trace_kprobe * tk = to_trace_kprobe (ev );
0 commit comments