aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
authorPrasanna S Panchamukhi <prasanna@in.ibm.com>2005-09-06 18:19:27 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-07 19:57:59 -0400
commit3d97ae5b958855ac007b6f56a0f94ab8ade09e9e (patch)
tree6258b62fdbf4fcc7086e86d920e23609022d0881 /arch/i386/kernel/kprobes.c
parentd0aaff9796c3310326d10da44fc0faed352a1d29 (diff)
[PATCH] kprobes: prevent possible race conditions i386 changes
This patch contains the i386 architecture specific changes to prevent the possible race conditions. Signed-off-by: Prasanna S Panchamukhi <prasanna@in.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index a6d8c45961d3..7fb5a6f4a563 100644
--- a/arch/i386/kernel/kprobes.c
+++ b/arch/i386/kernel/kprobes.c
@@ -62,32 +62,32 @@ static inline int is_IF_modifier(kprobe_opcode_t opcode)
62 return 0; 62 return 0;
63} 63}
64 64
65int arch_prepare_kprobe(struct kprobe *p) 65int __kprobes arch_prepare_kprobe(struct kprobe *p)
66{ 66{
67 return 0; 67 return 0;
68} 68}
69 69
70void arch_copy_kprobe(struct kprobe *p) 70void __kprobes arch_copy_kprobe(struct kprobe *p)
71{ 71{
72 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); 72 memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t));
73 p->opcode = *p->addr; 73 p->opcode = *p->addr;
74} 74}
75 75
76void arch_arm_kprobe(struct kprobe *p) 76void __kprobes arch_arm_kprobe(struct kprobe *p)
77{ 77{
78 *p->addr = BREAKPOINT_INSTRUCTION; 78 *p->addr = BREAKPOINT_INSTRUCTION;
79 flush_icache_range((unsigned long) p->addr, 79 flush_icache_range((unsigned long) p->addr,
80 (unsigned long) p->addr + sizeof(kprobe_opcode_t)); 80 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
81} 81}
82 82
83void arch_disarm_kprobe(struct kprobe *p) 83void __kprobes arch_disarm_kprobe(struct kprobe *p)
84{ 84{
85 *p->addr = p->opcode; 85 *p->addr = p->opcode;
86 flush_icache_range((unsigned long) p->addr, 86 flush_icache_range((unsigned long) p->addr,
87 (unsigned long) p->addr + sizeof(kprobe_opcode_t)); 87 (unsigned long) p->addr + sizeof(kprobe_opcode_t));
88} 88}
89 89
90void arch_remove_kprobe(struct kprobe *p) 90void __kprobes arch_remove_kprobe(struct kprobe *p)
91{ 91{
92} 92}
93 93
@@ -127,7 +127,8 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
127 regs->eip = (unsigned long)&p->ainsn.insn; 127 regs->eip = (unsigned long)&p->ainsn.insn;
128} 128}
129 129
130void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) 130void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
131 struct pt_regs *regs)
131{ 132{
132 unsigned long *sara = (unsigned long *)&regs->esp; 133 unsigned long *sara = (unsigned long *)&regs->esp;
133 struct kretprobe_instance *ri; 134 struct kretprobe_instance *ri;
@@ -150,7 +151,7 @@ void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs)
150 * Interrupts are disabled on entry as trap3 is an interrupt gate and they 151 * Interrupts are disabled on entry as trap3 is an interrupt gate and they
151 * remain disabled thorough out this function. 152 * remain disabled thorough out this function.
152 */ 153 */
153static int kprobe_handler(struct pt_regs *regs) 154static int __kprobes kprobe_handler(struct pt_regs *regs)
154{ 155{
155 struct kprobe *p; 156 struct kprobe *p;
156 int ret = 0; 157 int ret = 0;
@@ -259,7 +260,7 @@ no_kprobe:
259/* 260/*
260 * Called when we hit the probe point at kretprobe_trampoline 261 * Called when we hit the probe point at kretprobe_trampoline
261 */ 262 */
262int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 263int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
263{ 264{
264 struct kretprobe_instance *ri = NULL; 265 struct kretprobe_instance *ri = NULL;
265 struct hlist_head *head; 266 struct hlist_head *head;
@@ -338,7 +339,7 @@ int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
338 * that is atop the stack is the address following the copied instruction. 339 * that is atop the stack is the address following the copied instruction.
339 * We need to make it the address following the original instruction. 340 * We need to make it the address following the original instruction.
340 */ 341 */
341static void resume_execution(struct kprobe *p, struct pt_regs *regs) 342static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
342{ 343{
343 unsigned long *tos = (unsigned long *)&regs->esp; 344 unsigned long *tos = (unsigned long *)&regs->esp;
344 unsigned long next_eip = 0; 345 unsigned long next_eip = 0;
@@ -444,8 +445,8 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
444/* 445/*
445 * Wrapper routine to for handling exceptions. 446 * Wrapper routine to for handling exceptions.
446 */ 447 */
447int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, 448int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
448 void *data) 449 unsigned long val, void *data)
449{ 450{
450 struct die_args *args = (struct die_args *)data; 451 struct die_args *args = (struct die_args *)data;
451 switch (val) { 452 switch (val) {
@@ -473,7 +474,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
473 return NOTIFY_DONE; 474 return NOTIFY_DONE;
474} 475}
475 476
476int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 477int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
477{ 478{
478 struct jprobe *jp = container_of(p, struct jprobe, kp); 479 struct jprobe *jp = container_of(p, struct jprobe, kp);
479 unsigned long addr; 480 unsigned long addr;
@@ -495,7 +496,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
495 return 1; 496 return 1;
496} 497}
497 498
498void jprobe_return(void) 499void __kprobes jprobe_return(void)
499{ 500{
500 preempt_enable_no_resched(); 501 preempt_enable_no_resched();
501 asm volatile (" xchgl %%ebx,%%esp \n" 502 asm volatile (" xchgl %%ebx,%%esp \n"
@@ -506,7 +507,7 @@ void jprobe_return(void)
506 (jprobe_saved_esp):"memory"); 507 (jprobe_saved_esp):"memory");
507} 508}
508 509
509int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 510int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
510{ 511{
511 u8 *addr = (u8 *) (regs->eip - 1); 512 u8 *addr = (u8 *) (regs->eip - 1);
512 unsigned long stack_addr = (unsigned long)jprobe_saved_esp; 513 unsigned long stack_addr = (unsigned long)jprobe_saved_esp;