diff options
author | Suresh Siddha <suresh.b.siddha@intel.com> | 2009-10-28 18:46:57 -0800 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-11-02 17:16:36 +0100 |
commit | 55ca3cc1746335bb6ef1d3894ddb6d0c729b3518 (patch) | |
tree | 1678b567a1d4ebb92c51abc0234334023879c749 /arch/x86/kernel/ftrace.c | |
parent | 502f660466ba7a66711ffdf414b1f7f1131dcbf7 (diff) | |
download | linux-55ca3cc1746335bb6ef1d3894ddb6d0c729b3518.tar.gz linux-55ca3cc1746335bb6ef1d3894ddb6d0c729b3518.tar.bz2 linux-55ca3cc1746335bb6ef1d3894ddb6d0c729b3518.zip |
x86_64, ftrace: Make ftrace use kernel identity mapping to modify code
On x86_64, kernel text mappings are mapped read-only with
CONFIG_DEBUG_RODATA. So use the kernel identity mapping instead
of the kernel text mapping to modify the kernel text.
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
Acked-by: Steven Rostedt <rostedt@goodmis.org>
Tested-by: Steven Rostedt <rostedt@goodmis.org>
LKML-Reference: <20091029024821.080941108@sbs-t61.sc.intel.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/kernel/ftrace.c')
-rw-r--r-- | arch/x86/kernel/ftrace.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c index 9dbb527e1652..944e9820b4b5 100644 --- a/arch/x86/kernel/ftrace.c +++ b/arch/x86/kernel/ftrace.c @@ -187,9 +187,26 @@ static void wait_for_nmi(void) nmi_wait_count++; } +static inline int +within(unsigned long addr, unsigned long start, unsigned long end) +{ + return addr >= start && addr < end; +} + static int do_ftrace_mod_code(unsigned long ip, void *new_code) { + /* + * On x86_64, kernel text mappings are mapped read-only with + * CONFIG_DEBUG_RODATA. So we use the kernel identity mapping instead + * of the kernel text mapping to modify the kernel text. + * + * For 32bit kernels, these mappings are same and we can use + * kernel identity mapping to modify code. + */ + if (within(ip, (unsigned long)_text, (unsigned long)_etext)) + ip = (unsigned long)__va(__pa(ip)); + mod_code_ip = (void *)ip; mod_code_newcode = new_code; |