aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@suse.de>2007-07-22 05:12:31 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-22 14:03:37 -0400
commit19d36ccdc34f5ed444f8a6af0cbfdb6790eb1177 (patch)
tree39942efb826f2793692da60b04fc0e7b015fa23d /arch/i386/kernel/kprobes.c
parentf51c94528a9bc73504928926ca4d791a2b7ddd7c (diff)
x86: Fix alternatives and kprobes to remap write-protected kernel text
Reenable kprobes and alternative patching when the kernel text is write protected by DEBUG_RODATA Add a general utility function to change write protected text. The new function remaps the code using vmap to write it and takes care of CPU synchronization. It also does CLFLUSH to make icache recovery faster. There are some limitations on when the function can be used, see the comment. This is a newer version that also changes the paravirt_ops code. text_poke also supports multi byte patching now. Contains bug fixes from Zach Amsden and suggestions from Mathieu Desnoyers. Cc: Jan Beulich <jbeulich@novell.com> Cc: Jeremy Fitzhardinge <jeremy@goop.org> Cc: Mathieu Desnoyers <compudj@krystal.dyndns.org> Cc: Zach Amsden <zach@vmware.com> Signed-off-by: Andi Kleen <ak@suse.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index dde828a333c3..448a50b1324c 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -35,6 +35,7 @@
35#include <asm/cacheflush.h> 35#include <asm/cacheflush.h>
36#include <asm/desc.h> 36#include <asm/desc.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38#include <asm/alternative.h>
38 39
39void jprobe_return_end(void); 40void jprobe_return_end(void);
40 41
@@ -169,16 +170,12 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
169 170
170void __kprobes arch_arm_kprobe(struct kprobe *p) 171void __kprobes arch_arm_kprobe(struct kprobe *p)
171{ 172{
172 *p->addr = BREAKPOINT_INSTRUCTION; 173 text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
173 flush_icache_range((unsigned long) p->addr,
174 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
175} 174}
176 175
177void __kprobes arch_disarm_kprobe(struct kprobe *p) 176void __kprobes arch_disarm_kprobe(struct kprobe *p)
178{ 177{
179 *p->addr = p->opcode; 178 text_poke(p->addr, &p->opcode, 1);
180 flush_icache_range((unsigned long) p->addr,
181 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
182} 179}
183 180
184void __kprobes arch_remove_kprobe(struct kprobe *p) 181void __kprobes arch_remove_kprobe(struct kprobe *p)