diff options
Diffstat (limited to 'arch/sparc64/kernel/kprobes.c')
-rw-r--r-- | arch/sparc64/kernel/kprobes.c | 14 |
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(); | ||
300 | out: | 292 | out: |
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. */ | ||
307 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 298 | static 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 | ||