0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include <linux/kernel.h>
0023 #include <linux/module.h>
0024 #include <linux/kprobes.h>
0025 #include <linux/ktime.h>
0026 #include <linux/sched.h>
0027
0028 static char func_name[KSYM_NAME_LEN] = "kernel_clone";
0029 module_param_string(func, func_name, KSYM_NAME_LEN, 0644);
0030 MODULE_PARM_DESC(func, "Function to kretprobe; this module will report the"
0031 " function's execution time");
0032
0033
0034 struct my_data {
0035 ktime_t entry_stamp;
0036 };
0037
0038
0039 static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
0040 {
0041 struct my_data *data;
0042
0043 if (!current->mm)
0044 return 1;
0045
0046 data = (struct my_data *)ri->data;
0047 data->entry_stamp = ktime_get();
0048 return 0;
0049 }
0050 NOKPROBE_SYMBOL(entry_handler);
0051
0052
0053
0054
0055
0056
0057 static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
0058 {
0059 unsigned long retval = regs_return_value(regs);
0060 struct my_data *data = (struct my_data *)ri->data;
0061 s64 delta;
0062 ktime_t now;
0063
0064 now = ktime_get();
0065 delta = ktime_to_ns(ktime_sub(now, data->entry_stamp));
0066 pr_info("%s returned %lu and took %lld ns to execute\n",
0067 func_name, retval, (long long)delta);
0068 return 0;
0069 }
0070 NOKPROBE_SYMBOL(ret_handler);
0071
0072 static struct kretprobe my_kretprobe = {
0073 .handler = ret_handler,
0074 .entry_handler = entry_handler,
0075 .data_size = sizeof(struct my_data),
0076
0077 .maxactive = 20,
0078 };
0079
0080 static int __init kretprobe_init(void)
0081 {
0082 int ret;
0083
0084 my_kretprobe.kp.symbol_name = func_name;
0085 ret = register_kretprobe(&my_kretprobe);
0086 if (ret < 0) {
0087 pr_err("register_kretprobe failed, returned %d\n", ret);
0088 return ret;
0089 }
0090 pr_info("Planted return probe at %s: %p\n",
0091 my_kretprobe.kp.symbol_name, my_kretprobe.kp.addr);
0092 return 0;
0093 }
0094
0095 static void __exit kretprobe_exit(void)
0096 {
0097 unregister_kretprobe(&my_kretprobe);
0098 pr_info("kretprobe at %p unregistered\n", my_kretprobe.kp.addr);
0099
0100
0101 pr_info("Missed probing %d instances of %s\n",
0102 my_kretprobe.nmissed, my_kretprobe.kp.symbol_name);
0103 }
0104
0105 module_init(kretprobe_init)
0106 module_exit(kretprobe_exit)
0107 MODULE_LICENSE("GPL");