diff options
Diffstat (limited to 'arch/sparc64/kernel')
-rw-r--r-- | arch/sparc64/kernel/kprobes.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index 0d66d07c8c6e..755a0d7d887f 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -118,8 +118,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
118 | void *addr = (void *) regs->tpc; | 118 | void *addr = (void *) regs->tpc; |
119 | int ret = 0; | 119 | int ret = 0; |
120 | 120 | ||
121 | preempt_disable(); | ||
122 | |||
123 | if (kprobe_running()) { | 121 | if (kprobe_running()) { |
124 | /* We *are* holding lock here, so this is safe. | 122 | /* We *are* holding lock here, so this is safe. |
125 | * Disarm the probe we just hit, and ignore it. | 123 | * Disarm the probe we just hit, and ignore it. |
@@ -171,6 +169,11 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
171 | goto no_kprobe; | 169 | goto no_kprobe; |
172 | } | 170 | } |
173 | 171 | ||
172 | /* | ||
173 | * This preempt_disable() matches the preempt_enable_no_resched() | ||
174 | * in post_kprobes_handler() | ||
175 | */ | ||
176 | preempt_disable(); | ||
174 | set_current_kprobe(p, regs); | 177 | set_current_kprobe(p, regs); |
175 | kprobe_status = KPROBE_HIT_ACTIVE; | 178 | kprobe_status = KPROBE_HIT_ACTIVE; |
176 | if (p->pre_handler && p->pre_handler(p, regs)) | 179 | if (p->pre_handler && p->pre_handler(p, regs)) |
@@ -182,7 +185,6 @@ ss_probe: | |||
182 | return 1; | 185 | return 1; |
183 | 186 | ||
184 | no_kprobe: | 187 | no_kprobe: |
185 | preempt_enable_no_resched(); | ||
186 | return ret; | 188 | return ret; |
187 | } | 189 | } |
188 | 190 | ||
@@ -322,29 +324,29 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
322 | unsigned long val, void *data) | 324 | unsigned long val, void *data) |
323 | { | 325 | { |
324 | struct die_args *args = (struct die_args *)data; | 326 | struct die_args *args = (struct die_args *)data; |
327 | int ret = NOTIFY_DONE; | ||
328 | |||
329 | preempt_disable(); | ||
325 | switch (val) { | 330 | switch (val) { |
326 | case DIE_DEBUG: | 331 | case DIE_DEBUG: |
327 | if (kprobe_handler(args->regs)) | 332 | if (kprobe_handler(args->regs)) |
328 | return NOTIFY_STOP; | 333 | ret = NOTIFY_STOP; |
329 | break; | 334 | break; |
330 | case DIE_DEBUG_2: | 335 | case DIE_DEBUG_2: |
331 | if (post_kprobe_handler(args->regs)) | 336 | if (post_kprobe_handler(args->regs)) |
332 | return NOTIFY_STOP; | 337 | ret = NOTIFY_STOP; |
333 | break; | 338 | break; |
334 | case DIE_GPF: | 339 | case DIE_GPF: |
335 | if (kprobe_running() && | ||
336 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
337 | return NOTIFY_STOP; | ||
338 | break; | ||
339 | case DIE_PAGE_FAULT: | 340 | case DIE_PAGE_FAULT: |
340 | if (kprobe_running() && | 341 | if (kprobe_running() && |
341 | kprobe_fault_handler(args->regs, args->trapnr)) | 342 | kprobe_fault_handler(args->regs, args->trapnr)) |
342 | return NOTIFY_STOP; | 343 | ret = NOTIFY_STOP; |
343 | break; | 344 | break; |
344 | default: | 345 | default: |
345 | break; | 346 | break; |
346 | } | 347 | } |
347 | return NOTIFY_DONE; | 348 | preempt_enable(); |
349 | return ret; | ||
348 | } | 350 | } |
349 | 351 | ||
350 | asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, | 352 | asmlinkage void __kprobes kprobe_trap(unsigned long trap_level, |
@@ -396,7 +398,6 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
396 | 398 | ||
397 | void __kprobes jprobe_return(void) | 399 | void __kprobes jprobe_return(void) |
398 | { | 400 | { |
399 | preempt_enable_no_resched(); | ||
400 | __asm__ __volatile__( | 401 | __asm__ __volatile__( |
401 | ".globl jprobe_return_trap_instruction\n" | 402 | ".globl jprobe_return_trap_instruction\n" |
402 | "jprobe_return_trap_instruction:\n\t" | 403 | "jprobe_return_trap_instruction:\n\t" |