diff options
Diffstat (limited to 'arch/x86_64/kernel/kprobes.c')
-rw-r--r-- | arch/x86_64/kernel/kprobes.c | 183 |
1 files changed, 91 insertions, 92 deletions
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index 76a28b007be9..dddeb678b440 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -34,7 +34,6 @@ | |||
34 | #include <linux/config.h> | 34 | #include <linux/config.h> |
35 | #include <linux/kprobes.h> | 35 | #include <linux/kprobes.h> |
36 | #include <linux/ptrace.h> | 36 | #include <linux/ptrace.h> |
37 | #include <linux/spinlock.h> | ||
38 | #include <linux/string.h> | 37 | #include <linux/string.h> |
39 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
40 | #include <linux/preempt.h> | 39 | #include <linux/preempt.h> |
@@ -44,17 +43,10 @@ | |||
44 | #include <asm/kdebug.h> | 43 | #include <asm/kdebug.h> |
45 | 44 | ||
46 | static DECLARE_MUTEX(kprobe_mutex); | 45 | static DECLARE_MUTEX(kprobe_mutex); |
47 | |||
48 | static struct kprobe *current_kprobe; | ||
49 | static unsigned long kprobe_status, kprobe_old_rflags, kprobe_saved_rflags; | ||
50 | static struct kprobe *kprobe_prev; | ||
51 | static unsigned long kprobe_status_prev, kprobe_old_rflags_prev, kprobe_saved_rflags_prev; | ||
52 | static struct pt_regs jprobe_saved_regs; | ||
53 | static long *jprobe_saved_rsp; | ||
54 | void jprobe_return_end(void); | 46 | void jprobe_return_end(void); |
55 | 47 | ||
56 | /* copy of the kernel stack at the probe fire time */ | 48 | DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; |
57 | static kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; | 49 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
58 | 50 | ||
59 | /* | 51 | /* |
60 | * returns non-zero if opcode modifies the interrupt flag. | 52 | * returns non-zero if opcode modifies the interrupt flag. |
@@ -236,29 +228,30 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
236 | up(&kprobe_mutex); | 228 | up(&kprobe_mutex); |
237 | } | 229 | } |
238 | 230 | ||
239 | static inline void save_previous_kprobe(void) | 231 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) |
240 | { | 232 | { |
241 | kprobe_prev = current_kprobe; | 233 | kcb->prev_kprobe.kp = kprobe_running(); |
242 | kprobe_status_prev = kprobe_status; | 234 | kcb->prev_kprobe.status = kcb->kprobe_status; |
243 | kprobe_old_rflags_prev = kprobe_old_rflags; | 235 | kcb->prev_kprobe.old_rflags = kcb->kprobe_old_rflags; |
244 | kprobe_saved_rflags_prev = kprobe_saved_rflags; | 236 | kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; |
245 | } | 237 | } |
246 | 238 | ||
247 | static inline void restore_previous_kprobe(void) | 239 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
248 | { | 240 | { |
249 | current_kprobe = kprobe_prev; | 241 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
250 | kprobe_status = kprobe_status_prev; | 242 | kcb->kprobe_status = kcb->prev_kprobe.status; |
251 | kprobe_old_rflags = kprobe_old_rflags_prev; | 243 | kcb->kprobe_old_rflags = kcb->prev_kprobe.old_rflags; |
252 | kprobe_saved_rflags = kprobe_saved_rflags_prev; | 244 | kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; |
253 | } | 245 | } |
254 | 246 | ||
255 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs) | 247 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
248 | struct kprobe_ctlblk *kcb) | ||
256 | { | 249 | { |
257 | current_kprobe = p; | 250 | __get_cpu_var(current_kprobe) = p; |
258 | kprobe_saved_rflags = kprobe_old_rflags | 251 | kcb->kprobe_saved_rflags = kcb->kprobe_old_rflags |
259 | = (regs->eflags & (TF_MASK | IF_MASK)); | 252 | = (regs->eflags & (TF_MASK | IF_MASK)); |
260 | if (is_IF_modifier(p->ainsn.insn)) | 253 | if (is_IF_modifier(p->ainsn.insn)) |
261 | kprobe_saved_rflags &= ~IF_MASK; | 254 | kcb->kprobe_saved_rflags &= ~IF_MASK; |
262 | } | 255 | } |
263 | 256 | ||
264 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 257 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
@@ -272,6 +265,7 @@ static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
272 | regs->rip = (unsigned long)p->ainsn.insn; | 265 | regs->rip = (unsigned long)p->ainsn.insn; |
273 | } | 266 | } |
274 | 267 | ||
268 | /* Called with kretprobe_lock held */ | ||
275 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | 269 | void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, |
276 | struct pt_regs *regs) | 270 | struct pt_regs *regs) |
277 | { | 271 | { |
@@ -292,32 +286,30 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | |||
292 | } | 286 | } |
293 | } | 287 | } |
294 | 288 | ||
295 | /* | ||
296 | * Interrupts are disabled on entry as trap3 is an interrupt gate and they | ||
297 | * remain disabled thorough out this function. | ||
298 | */ | ||
299 | int __kprobes kprobe_handler(struct pt_regs *regs) | 289 | int __kprobes kprobe_handler(struct pt_regs *regs) |
300 | { | 290 | { |
301 | struct kprobe *p; | 291 | struct kprobe *p; |
302 | int ret = 0; | 292 | int ret = 0; |
303 | kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); | 293 | kprobe_opcode_t *addr = (kprobe_opcode_t *)(regs->rip - sizeof(kprobe_opcode_t)); |
294 | struct kprobe_ctlblk *kcb; | ||
304 | 295 | ||
305 | /* We're in an interrupt, but this is clear and BUG()-safe. */ | 296 | /* |
297 | * We don't want to be preempted for the entire | ||
298 | * duration of kprobe processing | ||
299 | */ | ||
306 | preempt_disable(); | 300 | preempt_disable(); |
301 | kcb = get_kprobe_ctlblk(); | ||
307 | 302 | ||
308 | /* Check we're not actually recursing */ | 303 | /* Check we're not actually recursing */ |
309 | if (kprobe_running()) { | 304 | if (kprobe_running()) { |
310 | /* We *are* holding lock here, so this is safe. | ||
311 | Disarm the probe we just hit, and ignore it. */ | ||
312 | p = get_kprobe(addr); | 305 | p = get_kprobe(addr); |
313 | if (p) { | 306 | if (p) { |
314 | if (kprobe_status == KPROBE_HIT_SS && | 307 | if (kcb->kprobe_status == KPROBE_HIT_SS && |
315 | *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { | 308 | *p->ainsn.insn == BREAKPOINT_INSTRUCTION) { |
316 | regs->eflags &= ~TF_MASK; | 309 | regs->eflags &= ~TF_MASK; |
317 | regs->eflags |= kprobe_saved_rflags; | 310 | regs->eflags |= kcb->kprobe_saved_rflags; |
318 | unlock_kprobes(); | ||
319 | goto no_kprobe; | 311 | goto no_kprobe; |
320 | } else if (kprobe_status == KPROBE_HIT_SSDONE) { | 312 | } else if (kcb->kprobe_status == KPROBE_HIT_SSDONE) { |
321 | /* TODO: Provide re-entrancy from | 313 | /* TODO: Provide re-entrancy from |
322 | * post_kprobes_handler() and avoid exception | 314 | * post_kprobes_handler() and avoid exception |
323 | * stack corruption while single-stepping on | 315 | * stack corruption while single-stepping on |
@@ -325,6 +317,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
325 | */ | 317 | */ |
326 | arch_disarm_kprobe(p); | 318 | arch_disarm_kprobe(p); |
327 | regs->rip = (unsigned long)p->addr; | 319 | regs->rip = (unsigned long)p->addr; |
320 | reset_current_kprobe(); | ||
328 | ret = 1; | 321 | ret = 1; |
329 | } else { | 322 | } else { |
330 | /* We have reentered the kprobe_handler(), since | 323 | /* We have reentered the kprobe_handler(), since |
@@ -334,27 +327,24 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
334 | * of the new probe without calling any user | 327 | * of the new probe without calling any user |
335 | * handlers. | 328 | * handlers. |
336 | */ | 329 | */ |
337 | save_previous_kprobe(); | 330 | save_previous_kprobe(kcb); |
338 | set_current_kprobe(p, regs); | 331 | set_current_kprobe(p, regs, kcb); |
339 | p->nmissed++; | 332 | p->nmissed++; |
340 | prepare_singlestep(p, regs); | 333 | prepare_singlestep(p, regs); |
341 | kprobe_status = KPROBE_REENTER; | 334 | kcb->kprobe_status = KPROBE_REENTER; |
342 | return 1; | 335 | return 1; |
343 | } | 336 | } |
344 | } else { | 337 | } else { |
345 | p = current_kprobe; | 338 | p = __get_cpu_var(current_kprobe); |
346 | if (p->break_handler && p->break_handler(p, regs)) { | 339 | if (p->break_handler && p->break_handler(p, regs)) { |
347 | goto ss_probe; | 340 | goto ss_probe; |
348 | } | 341 | } |
349 | } | 342 | } |
350 | /* If it's not ours, can't be delete race, (we hold lock). */ | ||
351 | goto no_kprobe; | 343 | goto no_kprobe; |
352 | } | 344 | } |
353 | 345 | ||
354 | lock_kprobes(); | ||
355 | p = get_kprobe(addr); | 346 | p = get_kprobe(addr); |
356 | if (!p) { | 347 | if (!p) { |
357 | unlock_kprobes(); | ||
358 | if (*addr != BREAKPOINT_INSTRUCTION) { | 348 | if (*addr != BREAKPOINT_INSTRUCTION) { |
359 | /* | 349 | /* |
360 | * The breakpoint instruction was removed right | 350 | * The breakpoint instruction was removed right |
@@ -372,8 +362,8 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
372 | goto no_kprobe; | 362 | goto no_kprobe; |
373 | } | 363 | } |
374 | 364 | ||
375 | kprobe_status = KPROBE_HIT_ACTIVE; | 365 | set_current_kprobe(p, regs, kcb); |
376 | set_current_kprobe(p, regs); | 366 | kcb->kprobe_status = KPROBE_HIT_ACTIVE; |
377 | 367 | ||
378 | if (p->pre_handler && p->pre_handler(p, regs)) | 368 | if (p->pre_handler && p->pre_handler(p, regs)) |
379 | /* handler has already set things up, so skip ss setup */ | 369 | /* handler has already set things up, so skip ss setup */ |
@@ -381,7 +371,7 @@ int __kprobes kprobe_handler(struct pt_regs *regs) | |||
381 | 371 | ||
382 | ss_probe: | 372 | ss_probe: |
383 | prepare_singlestep(p, regs); | 373 | prepare_singlestep(p, regs); |
384 | kprobe_status = KPROBE_HIT_SS; | 374 | kcb->kprobe_status = KPROBE_HIT_SS; |
385 | return 1; | 375 | return 1; |
386 | 376 | ||
387 | no_kprobe: | 377 | no_kprobe: |
@@ -409,9 +399,10 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
409 | struct kretprobe_instance *ri = NULL; | 399 | struct kretprobe_instance *ri = NULL; |
410 | struct hlist_head *head; | 400 | struct hlist_head *head; |
411 | struct hlist_node *node, *tmp; | 401 | struct hlist_node *node, *tmp; |
412 | unsigned long orig_ret_address = 0; | 402 | unsigned long flags, orig_ret_address = 0; |
413 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; | 403 | unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; |
414 | 404 | ||
405 | spin_lock_irqsave(&kretprobe_lock, flags); | ||
415 | head = kretprobe_inst_table_head(current); | 406 | head = kretprobe_inst_table_head(current); |
416 | 407 | ||
417 | /* | 408 | /* |
@@ -450,13 +441,14 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
450 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); | 441 | BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); |
451 | regs->rip = orig_ret_address; | 442 | regs->rip = orig_ret_address; |
452 | 443 | ||
453 | unlock_kprobes(); | 444 | reset_current_kprobe(); |
445 | spin_unlock_irqrestore(&kretprobe_lock, flags); | ||
454 | preempt_enable_no_resched(); | 446 | preempt_enable_no_resched(); |
455 | 447 | ||
456 | /* | 448 | /* |
457 | * By returning a non-zero value, we are telling | 449 | * By returning a non-zero value, we are telling |
458 | * kprobe_handler() that we have handled unlocking | 450 | * kprobe_handler() that we don't want the post_handler |
459 | * and re-enabling preemption. | 451 | * to run (and have re-enabled preemption) |
460 | */ | 452 | */ |
461 | return 1; | 453 | return 1; |
462 | } | 454 | } |
@@ -483,7 +475,8 @@ int __kprobes trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) | |||
483 | * that is atop the stack is the address following the copied instruction. | 475 | * that is atop the stack is the address following the copied instruction. |
484 | * We need to make it the address following the original instruction. | 476 | * We need to make it the address following the original instruction. |
485 | */ | 477 | */ |
486 | static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | 478 | static void __kprobes resume_execution(struct kprobe *p, |
479 | struct pt_regs *regs, struct kprobe_ctlblk *kcb) | ||
487 | { | 480 | { |
488 | unsigned long *tos = (unsigned long *)regs->rsp; | 481 | unsigned long *tos = (unsigned long *)regs->rsp; |
489 | unsigned long next_rip = 0; | 482 | unsigned long next_rip = 0; |
@@ -498,7 +491,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
498 | switch (*insn) { | 491 | switch (*insn) { |
499 | case 0x9c: /* pushfl */ | 492 | case 0x9c: /* pushfl */ |
500 | *tos &= ~(TF_MASK | IF_MASK); | 493 | *tos &= ~(TF_MASK | IF_MASK); |
501 | *tos |= kprobe_old_rflags; | 494 | *tos |= kcb->kprobe_old_rflags; |
502 | break; | 495 | break; |
503 | case 0xc3: /* ret/lret */ | 496 | case 0xc3: /* ret/lret */ |
504 | case 0xcb: | 497 | case 0xcb: |
@@ -537,30 +530,28 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
537 | } | 530 | } |
538 | } | 531 | } |
539 | 532 | ||
540 | /* | ||
541 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they | ||
542 | * remain disabled thoroughout this function. And we hold kprobe lock. | ||
543 | */ | ||
544 | int __kprobes post_kprobe_handler(struct pt_regs *regs) | 533 | int __kprobes post_kprobe_handler(struct pt_regs *regs) |
545 | { | 534 | { |
546 | if (!kprobe_running()) | 535 | struct kprobe *cur = kprobe_running(); |
536 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
537 | |||
538 | if (!cur) | ||
547 | return 0; | 539 | return 0; |
548 | 540 | ||
549 | if ((kprobe_status != KPROBE_REENTER) && current_kprobe->post_handler) { | 541 | if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { |
550 | kprobe_status = KPROBE_HIT_SSDONE; | 542 | kcb->kprobe_status = KPROBE_HIT_SSDONE; |
551 | current_kprobe->post_handler(current_kprobe, regs, 0); | 543 | cur->post_handler(cur, regs, 0); |
552 | } | 544 | } |
553 | 545 | ||
554 | resume_execution(current_kprobe, regs); | 546 | resume_execution(cur, regs, kcb); |
555 | regs->eflags |= kprobe_saved_rflags; | 547 | regs->eflags |= kcb->kprobe_saved_rflags; |
556 | 548 | ||
557 | /* Restore the original saved kprobes variables and continue. */ | 549 | /* Restore the original saved kprobes variables and continue. */ |
558 | if (kprobe_status == KPROBE_REENTER) { | 550 | if (kcb->kprobe_status == KPROBE_REENTER) { |
559 | restore_previous_kprobe(); | 551 | restore_previous_kprobe(kcb); |
560 | goto out; | 552 | goto out; |
561 | } else { | ||
562 | unlock_kprobes(); | ||
563 | } | 553 | } |
554 | reset_current_kprobe(); | ||
564 | out: | 555 | out: |
565 | preempt_enable_no_resched(); | 556 | preempt_enable_no_resched(); |
566 | 557 | ||
@@ -575,18 +566,19 @@ out: | |||
575 | return 1; | 566 | return 1; |
576 | } | 567 | } |
577 | 568 | ||
578 | /* Interrupts disabled, kprobe_lock held. */ | ||
579 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 569 | int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
580 | { | 570 | { |
581 | if (current_kprobe->fault_handler | 571 | struct kprobe *cur = kprobe_running(); |
582 | && current_kprobe->fault_handler(current_kprobe, regs, trapnr)) | 572 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
573 | |||
574 | if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) | ||
583 | return 1; | 575 | return 1; |
584 | 576 | ||
585 | if (kprobe_status & KPROBE_HIT_SS) { | 577 | if (kcb->kprobe_status & KPROBE_HIT_SS) { |
586 | resume_execution(current_kprobe, regs); | 578 | resume_execution(cur, regs, kcb); |
587 | regs->eflags |= kprobe_old_rflags; | 579 | regs->eflags |= kcb->kprobe_old_rflags; |
588 | 580 | ||
589 | unlock_kprobes(); | 581 | reset_current_kprobe(); |
590 | preempt_enable_no_resched(); | 582 | preempt_enable_no_resched(); |
591 | } | 583 | } |
592 | return 0; | 584 | return 0; |
@@ -599,39 +591,41 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self, | |||
599 | unsigned long val, void *data) | 591 | unsigned long val, void *data) |
600 | { | 592 | { |
601 | struct die_args *args = (struct die_args *)data; | 593 | struct die_args *args = (struct die_args *)data; |
594 | int ret = NOTIFY_DONE; | ||
595 | |||
602 | switch (val) { | 596 | switch (val) { |
603 | case DIE_INT3: | 597 | case DIE_INT3: |
604 | if (kprobe_handler(args->regs)) | 598 | if (kprobe_handler(args->regs)) |
605 | return NOTIFY_STOP; | 599 | ret = NOTIFY_STOP; |
606 | break; | 600 | break; |
607 | case DIE_DEBUG: | 601 | case DIE_DEBUG: |
608 | if (post_kprobe_handler(args->regs)) | 602 | if (post_kprobe_handler(args->regs)) |
609 | return NOTIFY_STOP; | 603 | ret = NOTIFY_STOP; |
610 | break; | 604 | break; |
611 | case DIE_GPF: | 605 | case DIE_GPF: |
612 | if (kprobe_running() && | ||
613 | kprobe_fault_handler(args->regs, args->trapnr)) | ||
614 | return NOTIFY_STOP; | ||
615 | break; | ||
616 | case DIE_PAGE_FAULT: | 606 | case DIE_PAGE_FAULT: |
607 | /* kprobe_running() needs smp_processor_id() */ | ||
608 | preempt_disable(); | ||
617 | if (kprobe_running() && | 609 | if (kprobe_running() && |
618 | kprobe_fault_handler(args->regs, args->trapnr)) | 610 | kprobe_fault_handler(args->regs, args->trapnr)) |
619 | return NOTIFY_STOP; | 611 | ret = NOTIFY_STOP; |
612 | preempt_enable(); | ||
620 | break; | 613 | break; |
621 | default: | 614 | default: |
622 | break; | 615 | break; |
623 | } | 616 | } |
624 | return NOTIFY_DONE; | 617 | return ret; |
625 | } | 618 | } |
626 | 619 | ||
627 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | 620 | int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) |
628 | { | 621 | { |
629 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 622 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
630 | unsigned long addr; | 623 | unsigned long addr; |
624 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
631 | 625 | ||
632 | jprobe_saved_regs = *regs; | 626 | kcb->jprobe_saved_regs = *regs; |
633 | jprobe_saved_rsp = (long *) regs->rsp; | 627 | kcb->jprobe_saved_rsp = (long *) regs->rsp; |
634 | addr = (unsigned long)jprobe_saved_rsp; | 628 | addr = (unsigned long)(kcb->jprobe_saved_rsp); |
635 | /* | 629 | /* |
636 | * As Linus pointed out, gcc assumes that the callee | 630 | * As Linus pointed out, gcc assumes that the callee |
637 | * owns the argument space and could overwrite it, e.g. | 631 | * owns the argument space and could overwrite it, e.g. |
@@ -639,7 +633,8 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
639 | * we also save and restore enough stack bytes to cover | 633 | * we also save and restore enough stack bytes to cover |
640 | * the argument area. | 634 | * the argument area. |
641 | */ | 635 | */ |
642 | memcpy(jprobes_stack, (kprobe_opcode_t *) addr, MIN_STACK_SIZE(addr)); | 636 | memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, |
637 | MIN_STACK_SIZE(addr)); | ||
643 | regs->eflags &= ~IF_MASK; | 638 | regs->eflags &= ~IF_MASK; |
644 | regs->rip = (unsigned long)(jp->entry); | 639 | regs->rip = (unsigned long)(jp->entry); |
645 | return 1; | 640 | return 1; |
@@ -647,36 +642,40 @@ int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) | |||
647 | 642 | ||
648 | void __kprobes jprobe_return(void) | 643 | void __kprobes jprobe_return(void) |
649 | { | 644 | { |
650 | preempt_enable_no_resched(); | 645 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
646 | |||
651 | asm volatile (" xchg %%rbx,%%rsp \n" | 647 | asm volatile (" xchg %%rbx,%%rsp \n" |
652 | " int3 \n" | 648 | " int3 \n" |
653 | " .globl jprobe_return_end \n" | 649 | " .globl jprobe_return_end \n" |
654 | " jprobe_return_end: \n" | 650 | " jprobe_return_end: \n" |
655 | " nop \n"::"b" | 651 | " nop \n"::"b" |
656 | (jprobe_saved_rsp):"memory"); | 652 | (kcb->jprobe_saved_rsp):"memory"); |
657 | } | 653 | } |
658 | 654 | ||
659 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) | 655 | int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) |
660 | { | 656 | { |
657 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | ||
661 | u8 *addr = (u8 *) (regs->rip - 1); | 658 | u8 *addr = (u8 *) (regs->rip - 1); |
662 | unsigned long stack_addr = (unsigned long)jprobe_saved_rsp; | 659 | unsigned long stack_addr = (unsigned long)(kcb->jprobe_saved_rsp); |
663 | struct jprobe *jp = container_of(p, struct jprobe, kp); | 660 | struct jprobe *jp = container_of(p, struct jprobe, kp); |
664 | 661 | ||
665 | if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { | 662 | if ((addr > (u8 *) jprobe_return) && (addr < (u8 *) jprobe_return_end)) { |
666 | if ((long *)regs->rsp != jprobe_saved_rsp) { | 663 | if ((long *)regs->rsp != kcb->jprobe_saved_rsp) { |
667 | struct pt_regs *saved_regs = | 664 | struct pt_regs *saved_regs = |
668 | container_of(jprobe_saved_rsp, struct pt_regs, rsp); | 665 | container_of(kcb->jprobe_saved_rsp, |
666 | struct pt_regs, rsp); | ||
669 | printk("current rsp %p does not match saved rsp %p\n", | 667 | printk("current rsp %p does not match saved rsp %p\n", |
670 | (long *)regs->rsp, jprobe_saved_rsp); | 668 | (long *)regs->rsp, kcb->jprobe_saved_rsp); |
671 | printk("Saved registers for jprobe %p\n", jp); | 669 | printk("Saved registers for jprobe %p\n", jp); |
672 | show_registers(saved_regs); | 670 | show_registers(saved_regs); |
673 | printk("Current registers\n"); | 671 | printk("Current registers\n"); |
674 | show_registers(regs); | 672 | show_registers(regs); |
675 | BUG(); | 673 | BUG(); |
676 | } | 674 | } |
677 | *regs = jprobe_saved_regs; | 675 | *regs = kcb->jprobe_saved_regs; |
678 | memcpy((kprobe_opcode_t *) stack_addr, jprobes_stack, | 676 | memcpy((kprobe_opcode_t *) stack_addr, kcb->jprobes_stack, |
679 | MIN_STACK_SIZE(stack_addr)); | 677 | MIN_STACK_SIZE(stack_addr)); |
678 | preempt_enable_no_resched(); | ||
680 | return 1; | 679 | return 1; |
681 | } | 680 | } |
682 | return 0; | 681 | return 0; |