diff options
Diffstat (limited to 'kernel/extable.c')
| -rw-r--r-- | kernel/extable.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/kernel/extable.c b/kernel/extable.c index a26cb2e17023..e136ed8d82ba 100644 --- a/kernel/extable.c +++ b/kernel/extable.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | */ | 17 | */ |
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/ftrace.h> | ||
| 20 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
| 21 | #include <asm/sections.h> | 22 | #include <asm/sections.h> |
| 22 | 23 | ||
| @@ -40,7 +41,7 @@ const struct exception_table_entry *search_exception_tables(unsigned long addr) | |||
| 40 | return e; | 41 | return e; |
| 41 | } | 42 | } |
| 42 | 43 | ||
| 43 | int core_kernel_text(unsigned long addr) | 44 | __notrace_funcgraph int core_kernel_text(unsigned long addr) |
| 44 | { | 45 | { |
| 45 | if (addr >= (unsigned long)_stext && | 46 | if (addr >= (unsigned long)_stext && |
| 46 | addr <= (unsigned long)_etext) | 47 | addr <= (unsigned long)_etext) |
| @@ -53,7 +54,7 @@ int core_kernel_text(unsigned long addr) | |||
| 53 | return 0; | 54 | return 0; |
| 54 | } | 55 | } |
| 55 | 56 | ||
| 56 | int __kernel_text_address(unsigned long addr) | 57 | __notrace_funcgraph int __kernel_text_address(unsigned long addr) |
| 57 | { | 58 | { |
| 58 | if (core_kernel_text(addr)) | 59 | if (core_kernel_text(addr)) |
| 59 | return 1; | 60 | return 1; |
| @@ -66,3 +67,19 @@ int kernel_text_address(unsigned long addr) | |||
| 66 | return 1; | 67 | return 1; |
| 67 | return module_text_address(addr) != NULL; | 68 | return module_text_address(addr) != NULL; |
| 68 | } | 69 | } |
| 70 | |||
| 71 | /* | ||
| 72 | * On some architectures (PPC64, IA64) function pointers | ||
| 73 | * are actually only tokens to some data that then holds the | ||
| 74 | * real function address. As a result, to find if a function | ||
| 75 | * pointer is part of the kernel text, we need to do some | ||
| 76 | * special dereferencing first. | ||
| 77 | */ | ||
| 78 | int func_ptr_is_kernel_text(void *ptr) | ||
| 79 | { | ||
| 80 | unsigned long addr; | ||
| 81 | addr = (unsigned long) dereference_function_descriptor(ptr); | ||
| 82 | if (core_kernel_text(addr)) | ||
| 83 | return 1; | ||
| 84 | return module_text_address(addr) != NULL; | ||
| 85 | } | ||
