linux-stable-rt/arch
Rusty Lynch 73649dab0f [PATCH] x86_64 specific function return probes
The following patch adds the x86_64 architecture specific implementation
for function return probes.

Function return probes is a mechanism built on top of kprobes that allows
a caller to register a handler to be called when a given function exits.
For example, to instrument the return path of sys_mkdir:

static int sys_mkdir_exit(struct kretprobe_instance *i, struct pt_regs *regs)
{
	printk("sys_mkdir exited\n");
	return 0;
}
static struct kretprobe return_probe = {
	.handler = sys_mkdir_exit,
};

<inside setup function>

return_probe.kp.addr = (kprobe_opcode_t *) kallsyms_lookup_name("sys_mkdir");
if (register_kretprobe(&return_probe)) {
	printk(KERN_DEBUG "Unable to register return probe!\n");
	/* do error path */
}

<inside cleanup function>
unregister_kretprobe(&return_probe);

The way this works is that:

* At system initialization time, kernel/kprobes.c installs a kprobe
  on a function called kretprobe_trampoline() that is implemented in
  the arch/x86_64/kernel/kprobes.c  (More on this later)

* When a return probe is registered using register_kretprobe(),
  kernel/kprobes.c will install a kprobe on the first instruction of the
  targeted function with the pre handler set to arch_prepare_kretprobe()
  which is implemented in arch/x86_64/kernel/kprobes.c.

* arch_prepare_kretprobe() will prepare a kretprobe instance that stores:
  - nodes for hanging this instance in an empty or free list
  - a pointer to the return probe
  - the original return address
  - a pointer to the stack address

  With all this stowed away, arch_prepare_kretprobe() then sets the return
  address for the targeted function to a special trampoline function called
  kretprobe_trampoline() implemented in arch/x86_64/kernel/kprobes.c

* The kprobe completes as normal, with control passing back to the target
  function that executes as normal, and eventually returns to our trampoline
  function.

* Since a kprobe was installed on kretprobe_trampoline() during system
  initialization, control passes back to kprobes via the architecture
  specific function trampoline_probe_handler() which will lookup the
  instance in an hlist maintained by kernel/kprobes.c, and then call
  the handler function.

* When trampoline_probe_handler() is done, the kprobes infrastructure
  single steps the original instruction (in this case just a top), and
  then calls trampoline_post_handler().  trampoline_post_handler() then
  looks up the instance again, puts the instance back on the free list,
  and then makes a long jump back to the original return instruction.

So to recap, to instrument the exit path of a function this implementation
will cause four interruptions:

  - A breakpoint at the very beginning of the function allowing us to
    switch out the return address
  - A single step interruption to execute the original instruction that
    we replaced with the break instruction (normal kprobe flow)
  - A breakpoint in the trampoline function where our instrumented function
    returned to
  - A single step interruption to execute the original instruction that
    we replaced with the break instruction (normal kprobe flow)

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
2005-06-23 09:45:21 -07:00
..
alpha [PATCH] update all defconfigs for ARCH_DISCONTIGMEM_ENABLE 2005-06-23 09:45:02 -07:00
arm [PATCH] use ${CROSS_COMPILE}installkernel in arch/*/boot/install.sh 2005-06-23 09:45:07 -07:00
arm26 [PATCH] use ${CROSS_COMPILE}installkernel in arch/*/boot/install.sh 2005-06-23 09:45:07 -07:00
cris [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
frv [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
h8300 [PATCH] ptrace_h8300: condition bugfix 2005-06-23 09:45:15 -07:00
i386 [PATCH] kprobes: function-return probes 2005-06-23 09:45:21 -07:00
ia64 [PATCH] ia64: Selectable Timer Interrupt Frequency 2005-06-23 09:45:10 -07:00
m32r [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
m68k [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
m68knommu [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
mips [PATCH] mm/Kconfig: kill unused ARCH_FLATMEM_DISABLE 2005-06-23 09:45:03 -07:00
parisc [PATCH] mm/Kconfig: kill unused ARCH_FLATMEM_DISABLE 2005-06-23 09:45:03 -07:00
ppc [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
ppc64 [PATCH] use ${CROSS_COMPILE}installkernel in arch/*/boot/install.sh 2005-06-23 09:45:07 -07:00
s390 [PATCH] use ${CROSS_COMPILE}installkernel in arch/*/boot/install.sh 2005-06-23 09:45:07 -07:00
sh [PATCH] mm/Kconfig: kill unused ARCH_FLATMEM_DISABLE 2005-06-23 09:45:03 -07:00
sh64 [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
sparc [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
sparc64 [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
um [PATCH] kstrdup: convert a few existing implementations 2005-06-23 09:45:18 -07:00
v850 [PATCH] make each arch use mm/Kconfig 2005-06-23 09:45:02 -07:00
x86_64 [PATCH] x86_64 specific function return probes 2005-06-23 09:45:21 -07:00