@@ -961,9 +961,16 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
961961
962962#ifdef CONFIG_KPROBES_ON_FTRACE
963963static struct ftrace_ops kprobe_ftrace_ops __read_mostly = {
964+ .func = kprobe_ftrace_handler ,
965+ .flags = FTRACE_OPS_FL_SAVE_REGS ,
966+ };
967+
968+ static struct ftrace_ops kprobe_ipmodify_ops __read_mostly = {
964969 .func = kprobe_ftrace_handler ,
965970 .flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY ,
966971};
972+
973+ static int kprobe_ipmodify_enabled ;
967974static int kprobe_ftrace_enabled ;
968975
969976/* Must ensure p->addr is really on ftrace */
@@ -976,58 +983,75 @@ static int prepare_kprobe(struct kprobe *p)
976983}
977984
978985/* Caller must lock kprobe_mutex */
979- static int arm_kprobe_ftrace (struct kprobe * p )
986+ static int __arm_kprobe_ftrace (struct kprobe * p , struct ftrace_ops * ops ,
987+ int * cnt )
980988{
981989 int ret = 0 ;
982990
983- ret = ftrace_set_filter_ip (& kprobe_ftrace_ops ,
984- (unsigned long )p -> addr , 0 , 0 );
991+ ret = ftrace_set_filter_ip (ops , (unsigned long )p -> addr , 0 , 0 );
985992 if (ret ) {
986993 pr_debug ("Failed to arm kprobe-ftrace at %pS (%d)\n" ,
987994 p -> addr , ret );
988995 return ret ;
989996 }
990997
991- if (kprobe_ftrace_enabled == 0 ) {
992- ret = register_ftrace_function (& kprobe_ftrace_ops );
998+ if (* cnt == 0 ) {
999+ ret = register_ftrace_function (ops );
9931000 if (ret ) {
9941001 pr_debug ("Failed to init kprobe-ftrace (%d)\n" , ret );
9951002 goto err_ftrace ;
9961003 }
9971004 }
9981005
999- kprobe_ftrace_enabled ++ ;
1006+ ( * cnt ) ++ ;
10001007 return ret ;
10011008
10021009err_ftrace :
10031010 /*
1004- * Note: Since kprobe_ftrace_ops has IPMODIFY set, and ftrace requires a
1005- * non-empty filter_hash for IPMODIFY ops, we're safe from an accidental
1006- * empty filter_hash which would undesirably trace all functions.
1011+ * At this point, sinec ops is not registered, we should be sefe from
1012+ * registering empty filter.
10071013 */
1008- ftrace_set_filter_ip (& kprobe_ftrace_ops , (unsigned long )p -> addr , 1 , 0 );
1014+ ftrace_set_filter_ip (ops , (unsigned long )p -> addr , 1 , 0 );
10091015 return ret ;
10101016}
10111017
1018+ static int arm_kprobe_ftrace (struct kprobe * p )
1019+ {
1020+ bool ipmodify = (p -> post_handler != NULL );
1021+
1022+ return __arm_kprobe_ftrace (p ,
1023+ ipmodify ? & kprobe_ipmodify_ops : & kprobe_ftrace_ops ,
1024+ ipmodify ? & kprobe_ipmodify_enabled : & kprobe_ftrace_enabled );
1025+ }
1026+
10121027/* Caller must lock kprobe_mutex */
1013- static int disarm_kprobe_ftrace (struct kprobe * p )
1028+ static int __disarm_kprobe_ftrace (struct kprobe * p , struct ftrace_ops * ops ,
1029+ int * cnt )
10141030{
10151031 int ret = 0 ;
10161032
1017- if (kprobe_ftrace_enabled == 1 ) {
1018- ret = unregister_ftrace_function (& kprobe_ftrace_ops );
1033+ if (* cnt == 1 ) {
1034+ ret = unregister_ftrace_function (ops );
10191035 if (WARN (ret < 0 , "Failed to unregister kprobe-ftrace (%d)\n" , ret ))
10201036 return ret ;
10211037 }
10221038
1023- kprobe_ftrace_enabled -- ;
1039+ ( * cnt ) -- ;
10241040
1025- ret = ftrace_set_filter_ip (& kprobe_ftrace_ops ,
1026- (unsigned long )p -> addr , 1 , 0 );
1041+ ret = ftrace_set_filter_ip (ops , (unsigned long )p -> addr , 1 , 0 );
10271042 WARN_ONCE (ret < 0 , "Failed to disarm kprobe-ftrace at %pS (%d)\n" ,
10281043 p -> addr , ret );
10291044 return ret ;
10301045}
1046+
1047+ static int disarm_kprobe_ftrace (struct kprobe * p )
1048+ {
1049+ bool ipmodify = (p -> post_handler != NULL );
1050+
1051+ return __disarm_kprobe_ftrace (p ,
1052+ ipmodify ? & kprobe_ipmodify_ops : & kprobe_ftrace_ops ,
1053+ ipmodify ? & kprobe_ipmodify_enabled : & kprobe_ftrace_enabled );
1054+ }
10311055#else /* !CONFIG_KPROBES_ON_FTRACE */
10321056#define prepare_kprobe (p ) arch_prepare_kprobe(p)
10331057#define arm_kprobe_ftrace (p ) (-ENODEV)
0 commit comments