@@ -961,9 +961,16 @@ static struct kprobe *alloc_aggr_kprobe(struct kprobe *p)
961
961
962
962
#ifdef CONFIG_KPROBES_ON_FTRACE
963
963
static 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 = {
964
969
.func = kprobe_ftrace_handler ,
965
970
.flags = FTRACE_OPS_FL_SAVE_REGS | FTRACE_OPS_FL_IPMODIFY ,
966
971
};
972
+
973
+ static int kprobe_ipmodify_enabled ;
967
974
static int kprobe_ftrace_enabled ;
968
975
969
976
/* Must ensure p->addr is really on ftrace */
@@ -976,58 +983,75 @@ static int prepare_kprobe(struct kprobe *p)
976
983
}
977
984
978
985
/* 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 )
980
988
{
981
989
int ret = 0 ;
982
990
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 );
985
992
if (ret ) {
986
993
pr_debug ("Failed to arm kprobe-ftrace at %pS (%d)\n" ,
987
994
p -> addr , ret );
988
995
return ret ;
989
996
}
990
997
991
- if (kprobe_ftrace_enabled == 0 ) {
992
- ret = register_ftrace_function (& kprobe_ftrace_ops );
998
+ if (* cnt == 0 ) {
999
+ ret = register_ftrace_function (ops );
993
1000
if (ret ) {
994
1001
pr_debug ("Failed to init kprobe-ftrace (%d)\n" , ret );
995
1002
goto err_ftrace ;
996
1003
}
997
1004
}
998
1005
999
- kprobe_ftrace_enabled ++ ;
1006
+ ( * cnt ) ++ ;
1000
1007
return ret ;
1001
1008
1002
1009
err_ftrace :
1003
1010
/*
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.
1007
1013
*/
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 );
1009
1015
return ret ;
1010
1016
}
1011
1017
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
+
1012
1027
/* 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 )
1014
1030
{
1015
1031
int ret = 0 ;
1016
1032
1017
- if (kprobe_ftrace_enabled == 1 ) {
1018
- ret = unregister_ftrace_function (& kprobe_ftrace_ops );
1033
+ if (* cnt == 1 ) {
1034
+ ret = unregister_ftrace_function (ops );
1019
1035
if (WARN (ret < 0 , "Failed to unregister kprobe-ftrace (%d)\n" , ret ))
1020
1036
return ret ;
1021
1037
}
1022
1038
1023
- kprobe_ftrace_enabled -- ;
1039
+ ( * cnt ) -- ;
1024
1040
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 );
1027
1042
WARN_ONCE (ret < 0 , "Failed to disarm kprobe-ftrace at %pS (%d)\n" ,
1028
1043
p -> addr , ret );
1029
1044
return ret ;
1030
1045
}
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
+ }
1031
1055
#else /* !CONFIG_KPROBES_ON_FTRACE */
1032
1056
#define prepare_kprobe (p ) arch_prepare_kprobe(p)
1033
1057
#define arm_kprobe_ftrace (p ) (-ENODEV)
0 commit comments