@@ -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