aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sh/kernel/kprobes.c37
1 files changed, 20 insertions, 17 deletions
diff --git a/arch/sh/kernel/kprobes.c b/arch/sh/kernel/kprobes.c
index a478ba78e752..e357e3669a34 100644
--- a/arch/sh/kernel/kprobes.c
+++ b/arch/sh/kernel/kprobes.c
@@ -115,20 +115,20 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
115 } 115 }
116} 116}
117 117
118static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) 118static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
119{ 119{
120 kcb->prev_kprobe.kp = kprobe_running(); 120 kcb->prev_kprobe.kp = kprobe_running();
121 kcb->prev_kprobe.status = kcb->kprobe_status; 121 kcb->prev_kprobe.status = kcb->kprobe_status;
122} 122}
123 123
124static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) 124static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
125{ 125{
126 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; 126 __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
127 kcb->kprobe_status = kcb->prev_kprobe.status; 127 kcb->kprobe_status = kcb->prev_kprobe.status;
128} 128}
129 129
130static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, 130static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
131 struct kprobe_ctlblk *kcb) 131 struct kprobe_ctlblk *kcb)
132{ 132{
133 __get_cpu_var(current_kprobe) = p; 133 __get_cpu_var(current_kprobe) = p;
134} 134}
@@ -138,7 +138,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
138 * on the next instruction, following branches. Two probes are set if the 138 * on the next instruction, following branches. Two probes are set if the
139 * branch is conditional. 139 * branch is conditional.
140 */ 140 */
141static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) 141static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
142{ 142{
143 kprobe_opcode_t *addr = NULL; 143 kprobe_opcode_t *addr = NULL;
144 saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc); 144 saved_current_opcode.addr = (kprobe_opcode_t *) (regs->pc);
@@ -273,12 +273,12 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
273 /* handler has already set things up, so skip ss setup */ 273 /* handler has already set things up, so skip ss setup */
274 return 1; 274 return 1;
275 275
276 ss_probe: 276ss_probe:
277 prepare_singlestep(p, regs); 277 prepare_singlestep(p, regs);
278 kcb->kprobe_status = KPROBE_HIT_SS; 278 kcb->kprobe_status = KPROBE_HIT_SS;
279 return 1; 279 return 1;
280 280
281 no_kprobe: 281no_kprobe:
282 preempt_enable_no_resched(); 282 preempt_enable_no_resched();
283 return ret; 283 return ret;
284} 284}
@@ -358,7 +358,7 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs)
358 return orig_ret_address; 358 return orig_ret_address;
359} 359}
360 360
361static inline int post_kprobe_handler(struct pt_regs *regs) 361static int __kprobes post_kprobe_handler(struct pt_regs *regs)
362{ 362{
363 struct kprobe *cur = kprobe_running(); 363 struct kprobe *cur = kprobe_running();
364 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 364 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -391,14 +391,15 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
391 } 391 }
392 } 392 }
393 393
394 /*Restore back the original saved kprobes variables and continue. */ 394 /* Restore back the original saved kprobes variables and continue. */
395 if (kcb->kprobe_status == KPROBE_REENTER) { 395 if (kcb->kprobe_status == KPROBE_REENTER) {
396 restore_previous_kprobe(kcb); 396 restore_previous_kprobe(kcb);
397 goto out; 397 goto out;
398 } 398 }
399
399 reset_current_kprobe(); 400 reset_current_kprobe();
400 401
401 out: 402out:
402 preempt_enable_no_resched(); 403 preempt_enable_no_resched();
403 404
404 return 1; 405 return 1;
@@ -463,6 +464,7 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
463 default: 464 default:
464 break; 465 break;
465 } 466 }
467
466 return 0; 468 return 0;
467} 469}
468 470
@@ -498,8 +500,8 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
498 ret = NOTIFY_STOP; 500 ret = NOTIFY_STOP;
499 } else { 501 } else {
500 p = __get_cpu_var(current_kprobe); 502 p = __get_cpu_var(current_kprobe);
501 if (p->break_handler 503 if (p->break_handler &&
502 && p->break_handler(p, args->regs)) 504 p->break_handler(p, args->regs))
503 ret = NOTIFY_STOP; 505 ret = NOTIFY_STOP;
504 } 506 }
505 } 507 }
@@ -542,25 +544,26 @@ void __kprobes jprobe_return(void)
542int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) 544int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
543{ 545{
544 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 546 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
545 u8 *addr = (u8 *) regs->pc;
546 unsigned long stack_addr = kcb->jprobe_saved_r15; 547 unsigned long stack_addr = kcb->jprobe_saved_r15;
548 u8 *addr = (u8 *)regs->pc;
547 549
548 if ((addr >= (u8 *) jprobe_return) 550 if ((addr >= (u8 *)jprobe_return) &&
549 && (addr <= (u8 *) jprobe_return_end)) { 551 (addr <= (u8 *)jprobe_return_end)) {
550 *regs = kcb->jprobe_saved_regs; 552 *regs = kcb->jprobe_saved_regs;
551 553
552 memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, 554 memcpy((kprobe_opcode_t *)stack_addr, kcb->jprobes_stack,
553 MIN_STACK_SIZE(stack_addr)); 555 MIN_STACK_SIZE(stack_addr));
554 556
555 kcb->kprobe_status = KPROBE_HIT_SS; 557 kcb->kprobe_status = KPROBE_HIT_SS;
556 preempt_enable_no_resched(); 558 preempt_enable_no_resched();
557 return 1; 559 return 1;
558 } 560 }
561
559 return 0; 562 return 0;
560} 563}
561 564
562static struct kprobe trampoline_p = { 565static struct kprobe trampoline_p = {
563 .addr = (kprobe_opcode_t *) &kretprobe_trampoline, 566 .addr = (kprobe_opcode_t *)&kretprobe_trampoline,
564 .pre_handler = trampoline_probe_handler 567 .pre_handler = trampoline_probe_handler
565}; 568};
566 569