aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r--arch/i386/kernel/kprobes.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c
index a6d8c45961d3..6345b430b105 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;
@@ -176,7 +177,8 @@ static int kprobe_handler(struct pt_regs *regs)
176 Disarm the probe we just hit, and ignore it. */ 177 Disarm the probe we just hit, and ignore it. */
177 p = get_kprobe(addr); 178 p = get_kprobe(addr);
178 if (p) { 179 if (p) {
179 if (kprobe_status == KPROBE_HIT_SS) { 180 if (kprobe_status == KPROBE_HIT_SS &&
181 *p->ainsn.insn == BREAKPOINT_INSTRUCTION) {
180 regs->eflags &= ~TF_MASK; 182 regs->eflags &= ~TF_MASK;
181 regs->eflags |= kprobe_saved_eflags; 183 regs->eflags |= kprobe_saved_eflags;
182 unlock_kprobes(); 184 unlock_kprobes();
@@ -220,7 +222,10 @@ static int kprobe_handler(struct pt_regs *regs)
220 * either a probepoint or a debugger breakpoint 222 * either a probepoint or a debugger breakpoint
221 * at this address. In either case, no further 223 * at this address. In either case, no further
222 * handling of this interrupt is appropriate. 224 * handling of this interrupt is appropriate.
225 * Back up over the (now missing) int3 and run
226 * the original instruction.
223 */ 227 */
228 regs->eip -= sizeof(kprobe_opcode_t);
224 ret = 1; 229 ret = 1;
225 } 230 }
226 /* Not one of ours: let kernel handle it */ 231 /* Not one of ours: let kernel handle it */
@@ -259,7 +264,7 @@ no_kprobe:
259/* 264/*
260 * Called when we hit the probe point at kretprobe_trampoline 265 * Called when we hit the probe point at kretprobe_trampoline
261 */ 266 */
262int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 267int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
263{ 268{
264 struct kretprobe_instance *ri = NULL; 269 struct kretprobe_instance *ri = NULL;
265 struct hlist_head *head; 270 struct hlist_head *head;
@@ -338,7 +343,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. 343 * that is atop the stack is the address following the copied instruction.
339 * We need to make it the address following the original instruction. 344 * We need to make it the address following the original instruction.
340 */ 345 */
341static void resume_execution(struct kprobe *p, struct pt_regs *regs) 346static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
342{ 347{
343 unsigned long *tos = (unsigned long *)&regs->esp; 348 unsigned long *tos = (unsigned long *)&regs->esp;
344 unsigned long next_eip = 0; 349 unsigned long next_eip = 0;
@@ -444,8 +449,8 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
444/* 449/*
445 * Wrapper routine to for handling exceptions. 450 * Wrapper routine to for handling exceptions.
446 */ 451 */
447int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val, 452int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
448 void *data) 453 unsigned long val, void *data)
449{ 454{
450 struct die_args *args = (struct die_args *)data; 455 struct die_args *args = (struct die_args *)data;
451 switch (val) { 456 switch (val) {
@@ -473,7 +478,7 @@ int kprobe_exceptions_notify(struct notifier_block *self, unsigned long val,
473 return NOTIFY_DONE; 478 return NOTIFY_DONE;
474} 479}
475 480
476int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) 481int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
477{ 482{
478 struct jprobe *jp = container_of(p, struct jprobe, kp); 483 struct jprobe *jp = container_of(p, struct jprobe, kp);
479 unsigned long addr; 484 unsigned long addr;
@@ -495,7 +500,7 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
495 return 1; 500 return 1;
496} 501}
497 502
498void jprobe_return(void) 503void __kprobes jprobe_return(void)
499{ 504{
500 preempt_enable_no_resched(); 505 preempt_enable_no_resched();
501 asm volatile (" xchgl %%ebx,%%esp \n" 506 asm volatile (" xchgl %%ebx,%%esp \n"
@@ -506,7 +511,7 @@ void jprobe_return(void)
506 (jprobe_saved_esp):"memory"); 511 (jprobe_saved_esp):"memory");
507} 512}
508 513
509int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 514int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
510{ 515{
511 u8 *addr = (u8 *) (regs->eip - 1); 516 u8 *addr = (u8 *) (regs->eip - 1);
512 unsigned long stack_addr = (unsigned long)jprobe_saved_esp; 517 unsigned long stack_addr = (unsigned long)jprobe_saved_esp;