aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/kprobes.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64/kernel/kprobes.c')
-rw-r--r--arch/sparc64/kernel/kprobes.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index 58a815e90373..96bd09b098f4 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -113,7 +113,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
113 struct kprobe *p; 113 struct kprobe *p;
114 void *addr = (void *) regs->tpc; 114 void *addr = (void *) regs->tpc;
115 int ret = 0; 115 int ret = 0;
116 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 116 struct kprobe_ctlblk *kcb;
117
118 /*
119 * We don't want to be preempted for the entire
120 * duration of kprobe processing
121 */
122 preempt_disable();
123 kcb = get_kprobe_ctlblk();
117 124
118 if (kprobe_running()) { 125 if (kprobe_running()) {
119 p = get_kprobe(addr); 126 p = get_kprobe(addr);
@@ -159,11 +166,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
159 goto no_kprobe; 166 goto no_kprobe;
160 } 167 }
161 168
162 /*
163 * This preempt_disable() matches the preempt_enable_no_resched()
164 * in post_kprobes_handler()
165 */
166 preempt_disable();
167 set_current_kprobe(p, regs, kcb); 169 set_current_kprobe(p, regs, kcb);
168 kcb->kprobe_status = KPROBE_HIT_ACTIVE; 170 kcb->kprobe_status = KPROBE_HIT_ACTIVE;
169 if (p->pre_handler && p->pre_handler(p, regs)) 171 if (p->pre_handler && p->pre_handler(p, regs))
@@ -175,6 +177,7 @@ ss_probe:
175 return 1; 177 return 1;
176 178
177no_kprobe: 179no_kprobe:
180 preempt_enable_no_resched();
178 return ret; 181 return ret;
179} 182}
180 183
@@ -321,7 +324,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
321 struct die_args *args = (struct die_args *)data; 324 struct die_args *args = (struct die_args *)data;
322 int ret = NOTIFY_DONE; 325 int ret = NOTIFY_DONE;
323 326
324 rcu_read_lock();
325 switch (val) { 327 switch (val) {
326 case DIE_DEBUG: 328 case DIE_DEBUG:
327 if (kprobe_handler(args->regs)) 329 if (kprobe_handler(args->regs))
@@ -333,14 +335,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
333 break; 335 break;
334 case DIE_GPF: 336 case DIE_GPF:
335 case DIE_PAGE_FAULT: 337 case DIE_PAGE_FAULT:
338 /* kprobe_running() needs smp_processor_id() */
339 preempt_disable();
336 if (kprobe_running() && 340 if (kprobe_running() &&
337 kprobe_fault_handler(args->regs, args->trapnr)) 341 kprobe_fault_handler(args->regs, args->trapnr))
338 ret = NOTIFY_STOP; 342 ret = NOTIFY_STOP;
343 preempt_enable();
339 break; 344 break;
340 default: 345 default:
341 break; 346 break;
342 } 347 }
343 rcu_read_unlock();
344 return ret; 348 return ret;
345} 349}
346 350
@@ -426,6 +430,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
426 &(kcb->jprobe_saved_stack), 430 &(kcb->jprobe_saved_stack),
427 sizeof(kcb->jprobe_saved_stack)); 431 sizeof(kcb->jprobe_saved_stack));
428 432
433 preempt_enable_no_resched();
429 return 1; 434 return 1;
430 } 435 }
431 return 0; 436 return 0;