diff options
author | Masami Hiramatsu <mhiramat@kernel.org> | 2017-01-08 09:58:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2017-01-14 02:38:05 -0500 |
commit | 5b485629ba0d5d027880769ff467c587b24b4bde (patch) | |
tree | 395ec5583989fd297007dfd2c7d04292ed273242 /kernel/extable.c | |
parent | f913f3a655cb4c37129bb36c9f175071e1fbdc29 (diff) |
kprobes, extable: Identify kprobes trampolines as kernel text area
Improve __kernel_text_address()/kernel_text_address() to return
true if the given address is on a kprobe's instruction slot
trampoline.
This can help stacktraces to determine the address is on a
text area or not.
To implement this atomically in is_kprobe_*_slot(), also change
the insn_cache page list to an RCU list.
This changes timings a bit (it delays page freeing to the RCU garbage
collection phase), but none of that is in the hot path.
Note: this change can add small overhead to stack unwinders because
it adds 2 additional checks to __kernel_text_address(). However, the
impact should be very small, because kprobe_insn_pages list has 1 entry
per 256 probes(on x86, on arm/arm64 it will be 1024 probes),
and kprobe_optinsn_pages has 1 entry per 32 probes(on x86).
In most use cases, the number of kprobe events may be less
than 20, which means that is_kprobe_*_slot() will check just one entry.
Tested-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Acked-by: Peter Zijlstra <peterz@infradead.org>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
Cc: Andrew Morton <akpm@linux-foundation.org>
Cc: Andrey Konovalov <andreyknvl@google.com>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Link: http://lkml.kernel.org/r/148388747896.6869.6354262871751682264.stgit@devbox
[ Improved the changelog and coding style. ]
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'kernel/extable.c')
-rw-r--r-- | kernel/extable.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index e3beec4a2339..e1359474baa5 100644 --- a/kernel/extable.c +++ b/kernel/extable.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/kprobes.h> | ||
23 | 24 | ||
24 | #include <asm/sections.h> | 25 | #include <asm/sections.h> |
25 | #include <linux/uaccess.h> | 26 | #include <linux/uaccess.h> |
@@ -104,6 +105,8 @@ int __kernel_text_address(unsigned long addr) | |||
104 | return 1; | 105 | return 1; |
105 | if (is_ftrace_trampoline(addr)) | 106 | if (is_ftrace_trampoline(addr)) |
106 | return 1; | 107 | return 1; |
108 | if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) | ||
109 | return 1; | ||
107 | /* | 110 | /* |
108 | * There might be init symbols in saved stacktraces. | 111 | * There might be init symbols in saved stacktraces. |
109 | * Give those symbols a chance to be printed in | 112 | * Give those symbols a chance to be printed in |
@@ -123,7 +126,11 @@ int kernel_text_address(unsigned long addr) | |||
123 | return 1; | 126 | return 1; |
124 | if (is_module_text_address(addr)) | 127 | if (is_module_text_address(addr)) |
125 | return 1; | 128 | return 1; |
126 | return is_ftrace_trampoline(addr); | 129 | if (is_ftrace_trampoline(addr)) |
130 | return 1; | ||
131 | if (is_kprobe_optinsn_slot(addr) || is_kprobe_insn_slot(addr)) | ||
132 | return 1; | ||
133 | return 0; | ||
127 | } | 134 | } |
128 | 135 | ||
129 | /* | 136 | /* |