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.c14
1 files changed, 2 insertions, 12 deletions
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index b95984154dba..58a815e90373 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -116,15 +116,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
116 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 116 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
117 117
118 if (kprobe_running()) { 118 if (kprobe_running()) {
119 /* We *are* holding lock here, so this is safe.
120 * Disarm the probe we just hit, and ignore it.
121 */
122 p = get_kprobe(addr); 119 p = get_kprobe(addr);
123 if (p) { 120 if (p) {
124 if (kcb->kprobe_status == KPROBE_HIT_SS) { 121 if (kcb->kprobe_status == KPROBE_HIT_SS) {
125 regs->tstate = ((regs->tstate & ~TSTATE_PIL) | 122 regs->tstate = ((regs->tstate & ~TSTATE_PIL) |
126 kcb->kprobe_orig_tstate_pil); 123 kcb->kprobe_orig_tstate_pil);
127 unlock_kprobes();
128 goto no_kprobe; 124 goto no_kprobe;
129 } 125 }
130 /* We have reentered the kprobe_handler(), since 126 /* We have reentered the kprobe_handler(), since
@@ -144,14 +140,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs)
144 if (p->break_handler && p->break_handler(p, regs)) 140 if (p->break_handler && p->break_handler(p, regs))
145 goto ss_probe; 141 goto ss_probe;
146 } 142 }
147 /* If it's not ours, can't be delete race, (we hold lock). */
148 goto no_kprobe; 143 goto no_kprobe;
149 } 144 }
150 145
151 lock_kprobes();
152 p = get_kprobe(addr); 146 p = get_kprobe(addr);
153 if (!p) { 147 if (!p) {
154 unlock_kprobes();
155 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) { 148 if (*(u32 *)addr != BREAKPOINT_INSTRUCTION) {
156 /* 149 /*
157 * The breakpoint instruction was removed right 150 * The breakpoint instruction was removed right
@@ -296,14 +289,12 @@ static inline int post_kprobe_handler(struct pt_regs *regs)
296 goto out; 289 goto out;
297 } 290 }
298 reset_current_kprobe(); 291 reset_current_kprobe();
299 unlock_kprobes();
300out: 292out:
301 preempt_enable_no_resched(); 293 preempt_enable_no_resched();
302 294
303 return 1; 295 return 1;
304} 296}
305 297
306/* Interrupts disabled, kprobe_lock held. */
307static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) 298static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
308{ 299{
309 struct kprobe *cur = kprobe_running(); 300 struct kprobe *cur = kprobe_running();
@@ -316,7 +307,6 @@ static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
316 resume_execution(cur, regs, kcb); 307 resume_execution(cur, regs, kcb);
317 308
318 reset_current_kprobe(); 309 reset_current_kprobe();
319 unlock_kprobes();
320 preempt_enable_no_resched(); 310 preempt_enable_no_resched();
321 } 311 }
322 return 0; 312 return 0;
@@ -331,7 +321,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
331 struct die_args *args = (struct die_args *)data; 321 struct die_args *args = (struct die_args *)data;
332 int ret = NOTIFY_DONE; 322 int ret = NOTIFY_DONE;
333 323
334 preempt_disable(); 324 rcu_read_lock();
335 switch (val) { 325 switch (val) {
336 case DIE_DEBUG: 326 case DIE_DEBUG:
337 if (kprobe_handler(args->regs)) 327 if (kprobe_handler(args->regs))
@@ -350,7 +340,7 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
350 default: 340 default:
351 break; 341 break;
352 } 342 }
353 preempt_enable(); 343 rcu_read_unlock();
354 return ret; 344 return ret;
355} 345}
356 346