aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86_64
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/x86_64
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/x86_64')
-rw-r--r--arch/x86_64/kernel/kprobes.c10
-rw-r--r--arch/x86_64/mm/init.c10
-rw-r--r--arch/x86_64/mm/pageattr.c2
3 files changed, 4 insertions, 18 deletions
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c
index d4a0d0ac9935..a30e004682e2 100644
--- a/arch/x86_64/kernel/kprobes.c
+++ b/arch/x86_64/kernel/kprobes.c
@@ -39,9 +39,9 @@
39#include <linux/module.h> 39#include <linux/module.h>
40#include <linux/kdebug.h> 40#include <linux/kdebug.h>
41 41
42#include <asm/cacheflush.h>
43#include <asm/pgtable.h> 42#include <asm/pgtable.h>
44#include <asm/uaccess.h> 43#include <asm/uaccess.h>
44#include <asm/alternative.h>
45 45
46void jprobe_return_end(void); 46void jprobe_return_end(void);
47static void __kprobes arch_copy_kprobe(struct kprobe *p); 47static void __kprobes arch_copy_kprobe(struct kprobe *p);
@@ -209,16 +209,12 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p)
209 209
210void __kprobes arch_arm_kprobe(struct kprobe *p) 210void __kprobes arch_arm_kprobe(struct kprobe *p)
211{ 211{
212 *p->addr = BREAKPOINT_INSTRUCTION; 212 text_poke(p->addr, ((unsigned char []){BREAKPOINT_INSTRUCTION}), 1);
213 flush_icache_range((unsigned long) p->addr,
214 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
215} 213}
216 214
217void __kprobes arch_disarm_kprobe(struct kprobe *p) 215void __kprobes arch_disarm_kprobe(struct kprobe *p)
218{ 216{
219 *p->addr = p->opcode; 217 text_poke(p->addr, &p->opcode, 1);
220 flush_icache_range((unsigned long) p->addr,
221 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
222} 218}
223 219
224void __kprobes arch_remove_kprobe(struct kprobe *p) 220void __kprobes arch_remove_kprobe(struct kprobe *p)
diff --git a/arch/x86_64/mm/init.c b/arch/x86_64/mm/init.c
index 2044fa961c07..314e12b2209f 100644
--- a/arch/x86_64/mm/init.c
+++ b/arch/x86_64/mm/init.c
@@ -600,16 +600,6 @@ void mark_rodata_ro(void)
600{ 600{
601 unsigned long start = (unsigned long)_stext, end; 601 unsigned long start = (unsigned long)_stext, end;
602 602
603#ifdef CONFIG_HOTPLUG_CPU
604 /* It must still be possible to apply SMP alternatives. */
605 if (num_possible_cpus() > 1)
606 start = (unsigned long)_etext;
607#endif
608
609#ifdef CONFIG_KPROBES
610 start = (unsigned long)__start_rodata;
611#endif
612
613 end = (unsigned long)__end_rodata; 603 end = (unsigned long)__end_rodata;
614 start = (start + PAGE_SIZE - 1) & PAGE_MASK; 604 start = (start + PAGE_SIZE - 1) & PAGE_MASK;
615 end &= PAGE_MASK; 605 end &= PAGE_MASK;
diff --git a/arch/x86_64/mm/pageattr.c b/arch/x86_64/mm/pageattr.c
index 36377b6b8efe..7e161c698af4 100644
--- a/arch/x86_64/mm/pageattr.c
+++ b/arch/x86_64/mm/pageattr.c
@@ -13,7 +13,7 @@
13#include <asm/tlbflush.h> 13#include <asm/tlbflush.h>
14#include <asm/io.h> 14#include <asm/io.h>
15 15
16static inline pte_t *lookup_address(unsigned long address) 16pte_t *lookup_address(unsigned long address)
17{ 17{
18 pgd_t *pgd = pgd_offset_k(address); 18 pgd_t *pgd = pgd_offset_k(address);
19 pud_t *pud; 19 pud_t *pud;