[PATCH] Return probe redesign: x86_64 specific changes

The following patch contains the x86_64 specific changes for the new
return probe design. Changes include:
* Removing the architecture specific functions for querying a return probe
instance off a stack address
* Complete rework onf arch_prepare_kretprobe() and trampoline_probe_handler()
* Removing trampoline_post_handler()
* Adding arch_init() so that now we handle registering the return probe
trampoline instead of kernel/kprobes.c doing it

NOTE:
Note that with this new design, the dependency on calculating a pointer to
the task off the stack pointer no longer exist (resolving the problem of
interruption stacks as pointed out in the original feedback to this port.)

Signed-off-by: Rusty Lynch <rusty.lynch@intel.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

authored by Rusty Lynch and committed by Linus Torvalds ba8af12f 4bdbd37f

+67 -60
+67 -60
arch/x86_64/kernel/kprobes.c
··· 272 272 regs->rip = (unsigned long)p->ainsn.insn; 273 273 } 274 274 275 - struct task_struct *arch_get_kprobe_task(void *ptr) 276 - { 277 - return ((struct thread_info *) (((unsigned long) ptr) & 278 - (~(THREAD_SIZE -1))))->task; 279 - } 280 - 281 275 void arch_prepare_kretprobe(struct kretprobe *rp, struct pt_regs *regs) 282 276 { 283 277 unsigned long *sara = (unsigned long *)regs->rsp; 284 - struct kretprobe_instance *ri; 285 - static void *orig_ret_addr; 278 + struct kretprobe_instance *ri; 286 279 287 - /* 288 - * Save the return address when the return probe hits 289 - * the first time, and use it to populate the (krprobe 290 - * instance)->ret_addr for subsequent return probes at 291 - * the same addrress since stack address would have 292 - * the kretprobe_trampoline by then. 293 - */ 294 - if (((void*) *sara) != kretprobe_trampoline) 295 - orig_ret_addr = (void*) *sara; 280 + if ((ri = get_free_rp_inst(rp)) != NULL) { 281 + ri->rp = rp; 282 + ri->task = current; 283 + ri->ret_addr = (kprobe_opcode_t *) *sara; 296 284 297 - if ((ri = get_free_rp_inst(rp)) != NULL) { 298 - ri->rp = rp; 299 - ri->stack_addr = sara; 300 - ri->ret_addr = orig_ret_addr; 301 - add_rp_inst(ri); 302 285 /* Replace the return addr with trampoline addr */ 303 286 *sara = (unsigned long) &kretprobe_trampoline; 304 - } else { 305 - rp->nmissed++; 306 - } 307 - } 308 287 309 - void arch_kprobe_flush_task(struct task_struct *tk) 310 - { 311 - struct kretprobe_instance *ri; 312 - while ((ri = get_rp_inst_tsk(tk)) != NULL) { 313 - *((unsigned long *)(ri->stack_addr)) = 314 - (unsigned long) ri->ret_addr; 315 - recycle_rp_inst(ri); 316 - } 288 + add_rp_inst(ri); 289 + } else { 290 + rp->nmissed++; 291 + } 317 292 } 318 293 319 294 /* ··· 401 426 */ 402 427 int trampoline_probe_handler(struct kprobe *p, struct pt_regs *regs) 403 428 { 404 - struct task_struct *tsk; 405 - struct kretprobe_instance *ri; 406 - struct hlist_head *head; 407 - struct hlist_node *node; 408 - unsigned long *sara = (unsigned long *)regs->rsp - 1; 429 + struct kretprobe_instance *ri = NULL; 430 + struct hlist_head *head; 431 + struct hlist_node *node, *tmp; 432 + unsigned long orig_ret_address = 0; 433 + unsigned long trampoline_address =(unsigned long)&kretprobe_trampoline; 409 434 410 - tsk = arch_get_kprobe_task(sara); 411 - head = kretprobe_inst_table_head(tsk); 435 + head = kretprobe_inst_table_head(current); 412 436 413 - hlist_for_each_entry(ri, node, head, hlist) { 414 - if (ri->stack_addr == sara && ri->rp) { 415 - if (ri->rp->handler) 416 - ri->rp->handler(ri, regs); 417 - } 418 - } 419 - return 0; 420 - } 437 + /* 438 + * It is possible to have multiple instances associated with a given 439 + * task either because an multiple functions in the call path 440 + * have a return probe installed on them, and/or more then one return 441 + * return probe was registered for a target function. 442 + * 443 + * We can handle this because: 444 + * - instances are always inserted at the head of the list 445 + * - when multiple return probes are registered for the same 446 + * function, the first instance's ret_addr will point to the 447 + * real return address, and all the rest will point to 448 + * kretprobe_trampoline 449 + */ 450 + hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { 451 + if (ri->task != current) 452 + /* another task is sharing our hash bucket */ 453 + continue; 421 454 422 - void trampoline_post_handler(struct kprobe *p, struct pt_regs *regs, 423 - unsigned long flags) 424 - { 425 - struct kretprobe_instance *ri; 426 - /* RA already popped */ 427 - unsigned long *sara = ((unsigned long *)regs->rsp) - 1; 455 + if (ri->rp && ri->rp->handler) 456 + ri->rp->handler(ri, regs); 428 457 429 - while ((ri = get_rp_inst(sara))) { 430 - regs->rip = (unsigned long)ri->ret_addr; 458 + orig_ret_address = (unsigned long)ri->ret_addr; 431 459 recycle_rp_inst(ri); 460 + 461 + if (orig_ret_address != trampoline_address) 462 + /* 463 + * This is the real return address. Any other 464 + * instances associated with this task are for 465 + * other calls deeper on the call stack 466 + */ 467 + break; 432 468 } 433 - regs->eflags &= ~TF_MASK; 469 + 470 + BUG_ON(!orig_ret_address || (orig_ret_address == trampoline_address)); 471 + regs->rip = orig_ret_address; 472 + 473 + unlock_kprobes(); 474 + preempt_enable_no_resched(); 475 + 476 + /* 477 + * By returning a non-zero value, we are telling 478 + * kprobe_handler() that we have handled unlocking 479 + * and re-enabling preemption. 480 + */ 481 + return 1; 434 482 } 435 483 436 484 /* ··· 546 548 current_kprobe->post_handler(current_kprobe, regs, 0); 547 549 } 548 550 549 - if (current_kprobe->post_handler != trampoline_post_handler) 550 - resume_execution(current_kprobe, regs); 551 + resume_execution(current_kprobe, regs); 551 552 regs->eflags |= kprobe_saved_rflags; 552 553 553 554 /* Restore the original saved kprobes variables and continue. */ ··· 675 678 return 1; 676 679 } 677 680 return 0; 681 + } 682 + 683 + static struct kprobe trampoline_p = { 684 + .addr = (kprobe_opcode_t *) &kretprobe_trampoline, 685 + .pre_handler = trampoline_probe_handler 686 + }; 687 + 688 + int __init arch_init(void) 689 + { 690 + return register_kprobe(&trampoline_p); 678 691 }