mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	kprobes: Prohibit probing on hardirq tracers
Since kprobes breakpoint handling involves hardirq tracer, probing these functions cause breakpoint recursion problem. Prohibit probing on those functions. Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> Acked-by: Steven Rostedt (VMware) <rostedt@goodmis.org> Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com> Cc: Andrea Righi <righi.andrea@gmail.com> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/154998802073.31052.17255044712514564153.stgit@devbox Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									6143c6fb1e
								
							
						
					
					
						commit
						eeeb080bae
					
				
					 2 changed files with 12 additions and 2 deletions
				
			
		| 
						 | 
					@ -14,6 +14,7 @@
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/ftrace.h>
 | 
					#include <linux/ftrace.h>
 | 
				
			||||||
 | 
					#include <linux/kprobes.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "trace.h"
 | 
					#include "trace.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -365,7 +366,7 @@ check_critical_timing(struct trace_array *tr,
 | 
				
			||||||
	__trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 | 
						__trace_function(tr, CALLER_ADDR0, parent_ip, flags, pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void
 | 
					static nokprobe_inline void
 | 
				
			||||||
start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 | 
					start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int cpu;
 | 
						int cpu;
 | 
				
			||||||
| 
						 | 
					@ -401,7 +402,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 | 
				
			||||||
	atomic_dec(&data->disabled);
 | 
						atomic_dec(&data->disabled);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline void
 | 
					static nokprobe_inline void
 | 
				
			||||||
stop_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 | 
					stop_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int cpu;
 | 
						int cpu;
 | 
				
			||||||
| 
						 | 
					@ -443,6 +444,7 @@ void start_critical_timings(void)
 | 
				
			||||||
		start_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 | 
							start_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(start_critical_timings);
 | 
					EXPORT_SYMBOL_GPL(start_critical_timings);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(start_critical_timings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void stop_critical_timings(void)
 | 
					void stop_critical_timings(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -452,6 +454,7 @@ void stop_critical_timings(void)
 | 
				
			||||||
		stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 | 
							stop_critical_timing(CALLER_ADDR0, CALLER_ADDR1, pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(stop_critical_timings);
 | 
					EXPORT_SYMBOL_GPL(stop_critical_timings);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(stop_critical_timings);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_FUNCTION_TRACER
 | 
					#ifdef CONFIG_FUNCTION_TRACER
 | 
				
			||||||
static bool function_enabled;
 | 
					static bool function_enabled;
 | 
				
			||||||
| 
						 | 
					@ -611,6 +614,7 @@ void tracer_hardirqs_on(unsigned long a0, unsigned long a1)
 | 
				
			||||||
	if (!preempt_trace(pc) && irq_trace())
 | 
						if (!preempt_trace(pc) && irq_trace())
 | 
				
			||||||
		stop_critical_timing(a0, a1, pc);
 | 
							stop_critical_timing(a0, a1, pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(tracer_hardirqs_on);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void tracer_hardirqs_off(unsigned long a0, unsigned long a1)
 | 
					void tracer_hardirqs_off(unsigned long a0, unsigned long a1)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -619,6 +623,7 @@ void tracer_hardirqs_off(unsigned long a0, unsigned long a1)
 | 
				
			||||||
	if (!preempt_trace(pc) && irq_trace())
 | 
						if (!preempt_trace(pc) && irq_trace())
 | 
				
			||||||
		start_critical_timing(a0, a1, pc);
 | 
							start_critical_timing(a0, a1, pc);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(tracer_hardirqs_off);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int irqsoff_tracer_init(struct trace_array *tr)
 | 
					static int irqsoff_tracer_init(struct trace_array *tr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,6 +9,7 @@
 | 
				
			||||||
#include <linux/uaccess.h>
 | 
					#include <linux/uaccess.h>
 | 
				
			||||||
#include <linux/module.h>
 | 
					#include <linux/module.h>
 | 
				
			||||||
#include <linux/ftrace.h>
 | 
					#include <linux/ftrace.h>
 | 
				
			||||||
 | 
					#include <linux/kprobes.h>
 | 
				
			||||||
#include "trace.h"
 | 
					#include "trace.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define CREATE_TRACE_POINTS
 | 
					#define CREATE_TRACE_POINTS
 | 
				
			||||||
| 
						 | 
					@ -30,6 +31,7 @@ void trace_hardirqs_on(void)
 | 
				
			||||||
	lockdep_hardirqs_on(CALLER_ADDR0);
 | 
						lockdep_hardirqs_on(CALLER_ADDR0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(trace_hardirqs_on);
 | 
					EXPORT_SYMBOL(trace_hardirqs_on);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(trace_hardirqs_on);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void trace_hardirqs_off(void)
 | 
					void trace_hardirqs_off(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -43,6 +45,7 @@ void trace_hardirqs_off(void)
 | 
				
			||||||
	lockdep_hardirqs_off(CALLER_ADDR0);
 | 
						lockdep_hardirqs_off(CALLER_ADDR0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(trace_hardirqs_off);
 | 
					EXPORT_SYMBOL(trace_hardirqs_off);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(trace_hardirqs_off);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
 | 
					__visible void trace_hardirqs_on_caller(unsigned long caller_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -56,6 +59,7 @@ __visible void trace_hardirqs_on_caller(unsigned long caller_addr)
 | 
				
			||||||
	lockdep_hardirqs_on(CALLER_ADDR0);
 | 
						lockdep_hardirqs_on(CALLER_ADDR0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(trace_hardirqs_on_caller);
 | 
					EXPORT_SYMBOL(trace_hardirqs_on_caller);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(trace_hardirqs_on_caller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
 | 
					__visible void trace_hardirqs_off_caller(unsigned long caller_addr)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -69,6 +73,7 @@ __visible void trace_hardirqs_off_caller(unsigned long caller_addr)
 | 
				
			||||||
	lockdep_hardirqs_off(CALLER_ADDR0);
 | 
						lockdep_hardirqs_off(CALLER_ADDR0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(trace_hardirqs_off_caller);
 | 
					EXPORT_SYMBOL(trace_hardirqs_off_caller);
 | 
				
			||||||
 | 
					NOKPROBE_SYMBOL(trace_hardirqs_off_caller);
 | 
				
			||||||
#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
					#endif /* CONFIG_TRACE_IRQFLAGS */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
 | 
					#ifdef CONFIG_TRACE_PREEMPT_TOGGLE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue