Skip to content

Commit 1c68907

Browse files
committed
Merge tag 'perf-kprobes-2020-10-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf/kprobes updates from Ingo Molnar: "This prepares to unify the kretprobe trampoline handler and make kretprobe lockless (those patches are still work in progress)" * tag 'perf-kprobes-2020-10-12' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: kprobes: Fix to check probe enabled before disarm_kprobe_ftrace() kprobes: Make local functions static kprobes: Free kretprobe_instance with RCU callback kprobes: Remove NMI context check sparc: kprobes: Use generic kretprobe trampoline handler sh: kprobes: Use generic kretprobe trampoline handler s390: kprobes: Use generic kretprobe trampoline handler powerpc: kprobes: Use generic kretprobe trampoline handler parisc: kprobes: Use generic kretprobe trampoline handler mips: kprobes: Use generic kretprobe trampoline handler ia64: kprobes: Use generic kretprobe trampoline handler csky: kprobes: Use generic kretprobe trampoline handler arc: kprobes: Use generic kretprobe trampoline handler arm64: kprobes: Use generic kretprobe trampoline handler arm: kprobes: Use generic kretprobe trampoline handler x86/kprobes: Use generic kretprobe trampoline handler kprobes: Add generic kretprobe trampoline handler
2 parents 3bff611 + bcb5320 commit 1c68907

File tree

14 files changed

+166
-856
lines changed

14 files changed

+166
-856
lines changed

arch/arc/kernel/kprobes.c

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
388388
{
389389

390390
ri->ret_addr = (kprobe_opcode_t *) regs->blink;
391+
ri->fp = NULL;
391392

392393
/* Replace the return addr with trampoline addr */
393394
regs->blink = (unsigned long)&kretprobe_trampoline;
@@ -396,58 +397,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
396397
static int __kprobes trampoline_probe_handler(struct kprobe *p,
397398
struct pt_regs *regs)
398399
{
399-
struct kretprobe_instance *ri = NULL;
400-
struct hlist_head *head, empty_rp;
401-
struct hlist_node *tmp;
402-
unsigned long flags, orig_ret_address = 0;
403-
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
404-
405-
INIT_HLIST_HEAD(&empty_rp);
406-
kretprobe_hash_lock(current, &head, &flags);
407-
408-
/*
409-
* It is possible to have multiple instances associated with a given
410-
* task either because an multiple functions in the call path
411-
* have a return probe installed on them, and/or more than one return
412-
* return probe was registered for a target function.
413-
*
414-
* We can handle this because:
415-
* - instances are always inserted at the head of the list
416-
* - when multiple return probes are registered for the same
417-
* function, the first instance's ret_addr will point to the
418-
* real return address, and all the rest will point to
419-
* kretprobe_trampoline
420-
*/
421-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
422-
if (ri->task != current)
423-
/* another task is sharing our hash bucket */
424-
continue;
425-
426-
if (ri->rp && ri->rp->handler)
427-
ri->rp->handler(ri, regs);
428-
429-
orig_ret_address = (unsigned long)ri->ret_addr;
430-
recycle_rp_inst(ri, &empty_rp);
431-
432-
if (orig_ret_address != trampoline_address) {
433-
/*
434-
* This is the real return address. Any other
435-
* instances associated with this task are for
436-
* other calls deeper on the call stack
437-
*/
438-
break;
439-
}
440-
}
441-
442-
kretprobe_assert(ri, orig_ret_address, trampoline_address);
443-
regs->ret = orig_ret_address;
444-
445-
kretprobe_hash_unlock(current, &flags);
446-
447-
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
448-
hlist_del(&ri->hlist);
449-
kfree(ri);
450-
}
400+
regs->ret = __kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
451401

452402
/* By returning a non zero value, we are telling the kprobe handler
453403
* that we don't want the post_handler to run

arch/arm/probes/kprobes/core.c

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -413,87 +413,15 @@ void __naked __kprobes kretprobe_trampoline(void)
413413
/* Called from kretprobe_trampoline */
414414
static __used __kprobes void *trampoline_handler(struct pt_regs *regs)
415415
{
416-
struct kretprobe_instance *ri = NULL;
417-
struct hlist_head *head, empty_rp;
418-
struct hlist_node *tmp;
419-
unsigned long flags, orig_ret_address = 0;
420-
unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline;
421-
kprobe_opcode_t *correct_ret_addr = NULL;
422-
423-
INIT_HLIST_HEAD(&empty_rp);
424-
kretprobe_hash_lock(current, &head, &flags);
425-
426-
/*
427-
* It is possible to have multiple instances associated with a given
428-
* task either because multiple functions in the call path have
429-
* a return probe installed on them, and/or more than one return
430-
* probe was registered for a target function.
431-
*
432-
* We can handle this because:
433-
* - instances are always inserted at the head of the list
434-
* - when multiple return probes are registered for the same
435-
* function, the first instance's ret_addr will point to the
436-
* real return address, and all the rest will point to
437-
* kretprobe_trampoline
438-
*/
439-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
440-
if (ri->task != current)
441-
/* another task is sharing our hash bucket */
442-
continue;
443-
444-
orig_ret_address = (unsigned long)ri->ret_addr;
445-
446-
if (orig_ret_address != trampoline_address)
447-
/*
448-
* This is the real return address. Any other
449-
* instances associated with this task are for
450-
* other calls deeper on the call stack
451-
*/
452-
break;
453-
}
454-
455-
kretprobe_assert(ri, orig_ret_address, trampoline_address);
456-
457-
correct_ret_addr = ri->ret_addr;
458-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
459-
if (ri->task != current)
460-
/* another task is sharing our hash bucket */
461-
continue;
462-
463-
orig_ret_address = (unsigned long)ri->ret_addr;
464-
if (ri->rp && ri->rp->handler) {
465-
__this_cpu_write(current_kprobe, &ri->rp->kp);
466-
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
467-
ri->ret_addr = correct_ret_addr;
468-
ri->rp->handler(ri, regs);
469-
__this_cpu_write(current_kprobe, NULL);
470-
}
471-
472-
recycle_rp_inst(ri, &empty_rp);
473-
474-
if (orig_ret_address != trampoline_address)
475-
/*
476-
* This is the real return address. Any other
477-
* instances associated with this task are for
478-
* other calls deeper on the call stack
479-
*/
480-
break;
481-
}
482-
483-
kretprobe_hash_unlock(current, &flags);
484-
485-
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
486-
hlist_del(&ri->hlist);
487-
kfree(ri);
488-
}
489-
490-
return (void *)orig_ret_address;
416+
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
417+
(void *)regs->ARM_fp);
491418
}
492419

493420
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
494421
struct pt_regs *regs)
495422
{
496423
ri->ret_addr = (kprobe_opcode_t *)regs->ARM_lr;
424+
ri->fp = (void *)regs->ARM_fp;
497425

498426
/* Replace the return addr with trampoline addr. */
499427
regs->ARM_lr = (unsigned long)&kretprobe_trampoline;

arch/arm64/kernel/probes/kprobes.c

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -464,87 +464,15 @@ int __init arch_populate_kprobe_blacklist(void)
464464

465465
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
466466
{
467-
struct kretprobe_instance *ri = NULL;
468-
struct hlist_head *head, empty_rp;
469-
struct hlist_node *tmp;
470-
unsigned long flags, orig_ret_address = 0;
471-
unsigned long trampoline_address =
472-
(unsigned long)&kretprobe_trampoline;
473-
kprobe_opcode_t *correct_ret_addr = NULL;
474-
475-
INIT_HLIST_HEAD(&empty_rp);
476-
kretprobe_hash_lock(current, &head, &flags);
477-
478-
/*
479-
* It is possible to have multiple instances associated with a given
480-
* task either because multiple functions in the call path have
481-
* return probes installed on them, and/or more than one
482-
* return probe was registered for a target function.
483-
*
484-
* We can handle this because:
485-
* - instances are always pushed into the head of the list
486-
* - when multiple return probes are registered for the same
487-
* function, the (chronologically) first instance's ret_addr
488-
* will be the real return address, and all the rest will
489-
* point to kretprobe_trampoline.
490-
*/
491-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
492-
if (ri->task != current)
493-
/* another task is sharing our hash bucket */
494-
continue;
495-
496-
orig_ret_address = (unsigned long)ri->ret_addr;
497-
498-
if (orig_ret_address != trampoline_address)
499-
/*
500-
* This is the real return address. Any other
501-
* instances associated with this task are for
502-
* other calls deeper on the call stack
503-
*/
504-
break;
505-
}
506-
507-
kretprobe_assert(ri, orig_ret_address, trampoline_address);
508-
509-
correct_ret_addr = ri->ret_addr;
510-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
511-
if (ri->task != current)
512-
/* another task is sharing our hash bucket */
513-
continue;
514-
515-
orig_ret_address = (unsigned long)ri->ret_addr;
516-
if (ri->rp && ri->rp->handler) {
517-
__this_cpu_write(current_kprobe, &ri->rp->kp);
518-
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
519-
ri->ret_addr = correct_ret_addr;
520-
ri->rp->handler(ri, regs);
521-
__this_cpu_write(current_kprobe, NULL);
522-
}
523-
524-
recycle_rp_inst(ri, &empty_rp);
525-
526-
if (orig_ret_address != trampoline_address)
527-
/*
528-
* This is the real return address. Any other
529-
* instances associated with this task are for
530-
* other calls deeper on the call stack
531-
*/
532-
break;
533-
}
534-
535-
kretprobe_hash_unlock(current, &flags);
536-
537-
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
538-
hlist_del(&ri->hlist);
539-
kfree(ri);
540-
}
541-
return (void *)orig_ret_address;
467+
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline,
468+
(void *)kernel_stack_pointer(regs));
542469
}
543470

544471
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
545472
struct pt_regs *regs)
546473
{
547474
ri->ret_addr = (kprobe_opcode_t *)regs->regs[30];
475+
ri->fp = (void *)kernel_stack_pointer(regs);
548476

549477
/* replace return addr (x30) with trampoline */
550478
regs->regs[30] = (long)&kretprobe_trampoline;

arch/csky/kernel/probes/kprobes.c

Lines changed: 2 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -404,87 +404,14 @@ int __init arch_populate_kprobe_blacklist(void)
404404

405405
void __kprobes __used *trampoline_probe_handler(struct pt_regs *regs)
406406
{
407-
struct kretprobe_instance *ri = NULL;
408-
struct hlist_head *head, empty_rp;
409-
struct hlist_node *tmp;
410-
unsigned long flags, orig_ret_address = 0;
411-
unsigned long trampoline_address =
412-
(unsigned long)&kretprobe_trampoline;
413-
kprobe_opcode_t *correct_ret_addr = NULL;
414-
415-
INIT_HLIST_HEAD(&empty_rp);
416-
kretprobe_hash_lock(current, &head, &flags);
417-
418-
/*
419-
* It is possible to have multiple instances associated with a given
420-
* task either because multiple functions in the call path have
421-
* return probes installed on them, and/or more than one
422-
* return probe was registered for a target function.
423-
*
424-
* We can handle this because:
425-
* - instances are always pushed into the head of the list
426-
* - when multiple return probes are registered for the same
427-
* function, the (chronologically) first instance's ret_addr
428-
* will be the real return address, and all the rest will
429-
* point to kretprobe_trampoline.
430-
*/
431-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
432-
if (ri->task != current)
433-
/* another task is sharing our hash bucket */
434-
continue;
435-
436-
orig_ret_address = (unsigned long)ri->ret_addr;
437-
438-
if (orig_ret_address != trampoline_address)
439-
/*
440-
* This is the real return address. Any other
441-
* instances associated with this task are for
442-
* other calls deeper on the call stack
443-
*/
444-
break;
445-
}
446-
447-
kretprobe_assert(ri, orig_ret_address, trampoline_address);
448-
449-
correct_ret_addr = ri->ret_addr;
450-
hlist_for_each_entry_safe(ri, tmp, head, hlist) {
451-
if (ri->task != current)
452-
/* another task is sharing our hash bucket */
453-
continue;
454-
455-
orig_ret_address = (unsigned long)ri->ret_addr;
456-
if (ri->rp && ri->rp->handler) {
457-
__this_cpu_write(current_kprobe, &ri->rp->kp);
458-
get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE;
459-
ri->ret_addr = correct_ret_addr;
460-
ri->rp->handler(ri, regs);
461-
__this_cpu_write(current_kprobe, NULL);
462-
}
463-
464-
recycle_rp_inst(ri, &empty_rp);
465-
466-
if (orig_ret_address != trampoline_address)
467-
/*
468-
* This is the real return address. Any other
469-
* instances associated with this task are for
470-
* other calls deeper on the call stack
471-
*/
472-
break;
473-
}
474-
475-
kretprobe_hash_unlock(current, &flags);
476-
477-
hlist_for_each_entry_safe(ri, tmp, &empty_rp, hlist) {
478-
hlist_del(&ri->hlist);
479-
kfree(ri);
480-
}
481-
return (void *)orig_ret_address;
407+
return (void *)kretprobe_trampoline_handler(regs, &kretprobe_trampoline, NULL);
482408
}
483409

484410
void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri,
485411
struct pt_regs *regs)
486412
{
487413
ri->ret_addr = (kprobe_opcode_t *)regs->lr;
414+
ri->fp = NULL;
488415
regs->lr = (unsigned long) &kretprobe_trampoline;
489416
}
490417

0 commit comments

Comments
 (0)