diff options
Diffstat (limited to 'arch/i386/kernel/kprobes.c')
-rw-r--r-- | arch/i386/kernel/kprobes.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index ad469299267a..32b0c24ab9a6 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -153,7 +153,14 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
153 | int ret = 0; | 153 | int ret = 0; |
154 | kprobe_opcode_t *addr = NULL; | 154 | kprobe_opcode_t *addr = NULL; |
155 | unsigned long *lp; | 155 | unsigned long *lp; |
156 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 156 | struct kprobe_ctlblk *kcb; |
157 | |||
158 | /* | ||
159 | * We don't want to be preempted for the entire | ||
160 | * duration of kprobe processing | ||
161 | */ | ||
162 | preempt_disable(); | ||
163 | kcb = get_kprobe_ctlblk(); | ||
157 | 164 | ||
158 | /* Check if the application is using LDT entry for its code segment and | 165 | /* Check if the application is using LDT entry for its code segment and |
159 | * calculate the address by reading the base address from the LDT entry. | 166 | * calculate the address by reading the base address from the LDT entry. |
@@ -221,11 +228,6 @@ static int __kprobes kprobe_handler(struct pt_regs *regs) | |||
221 | goto no_kprobe; | 228 | goto no_kprobe; |
222 | } | 229 | } |
223 | 230 | ||
224 | /* | ||
225 | * This preempt_disable() matches the preempt_enable_no_resched() | ||
226 | * in post_kprobe_handler() | ||
227 | */ | ||
228 | preempt_disable(); | ||
229 | set_current_kprobe(p, regs, kcb); | 231 | set_current_kprobe(p, regs, kcb); |
230 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; | 232 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
231 | 233 | ||
@@ -239,6 +241,7 @@ ss_probe: | |||
239 | return 1; | 241 | return 1; |
240 | 242 | ||
241 | no_kprobe: | 243 | no_kprobe: |
244 | preempt_enable_no_resched(); | ||
242 | return ret; | 245 | return ret; |
243 | } | 246 | } |
244 | 247 | ||
@@ -310,8 +313,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
310 | 313 | ||
311 | /* | 314 | /* |
312 | * By returning a non-zero value, we are telling | 315 | * By returning a non-zero value, we are telling |
313 | * kprobe_handler() that we have handled unlocking | 316 | * kprobe_handler() that we don't want the post_handler |
314 | * and re-enabling preemption | 317 | * to run (and have re-enabled preemption) |
315 | */ | 318 | */ |
316 | return 1; | 319 | return 1; |
317 | } | 320 | } |
@@ -455,7 +458,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
455 | struct die_args *args = (struct die_args *)data; | 458 | struct die_args *args = (struct die_args *)data; |
456 | int ret = NOTIFY_DONE; | 459 | int ret = NOTIFY_DONE; |
457 | 460 | ||
458 | rcu_read_lock(); | ||
459 | switch (val) { | 461 | switch (val) { |
460 | case DIE_INT3: | 462 | case DIE_INT3: |
461 | if (kprobe_handler(args->regs)) | 463 | if (kprobe_handler(args->regs)) |
@@ -467,14 +469,16 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
467 | break; | 469 | break; |
468 | case DIE_GPF: | 470 | case DIE_GPF: |
469 | case DIE_PAGE_FAULT: | 471 | case DIE_PAGE_FAULT: |
472 | /* kprobe_running() needs smp_processor_id() */ | ||
473 | preempt_disable(); | ||
470 | if (kprobe_running() && | 474 | if (kprobe_running() && |
471 | kprobe_fault_handler(args->regs, args->trapnr)) | 475 | kprobe_fault_handler(args->regs, args->trapnr)) |
472 | ret = NOTIFY_STOP; | 476 | ret = NOTIFY_STOP; |
477 | preempt_enable(); | ||
473 | break; | 478 | break; |
474 | default: | 479 | default: |
475 | break; | 480 | break; |
476 | } | 481 | } |
477 | rcu_read_unlock(); | ||
478 | return ret; | 482 | return ret; |
479 | } | 483 | } |
480 | 484 | ||
@@ -537,6 +541,7 @@ int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | |||
537 | *regs = kcb->jprobe_saved_regs; | 541 | *regs = kcb->jprobe_saved_regs; |
538 | memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, | 542 | memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, |
539 | MIN_STACK_SIZE(stack_addr)); | 543 | MIN_STACK_SIZE(stack_addr)); |
544 | preempt_enable_no_resched(); | ||
540 | return 1; | 545 | return 1; |
541 | } | 546 | } |
542 | return 0; | 547 | return 0; |