Linux Audio

Check our new training course

Loading...
v6.13.7
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
 
  3 * Here's a sample kernel module showing the use of kprobes to dump a
  4 * stack trace and selected registers when kernel_clone() is called.
  5 *
  6 * For more information on theory of operation of kprobes, see
  7 * Documentation/trace/kprobes.rst
  8 *
  9 * You will see the trace data in /var/log/messages and on the console
 10 * whenever kernel_clone() is invoked to create a new process.
 11 */
 12
 13#define pr_fmt(fmt) "%s: " fmt, __func__
 14
 15#include <linux/kernel.h>
 16#include <linux/module.h>
 17#include <linux/kprobes.h>
 18
 19static char symbol[KSYM_NAME_LEN] = "kernel_clone";
 20module_param_string(symbol, symbol, KSYM_NAME_LEN, 0644);
 
 21
 22/* For each probe you need to allocate a kprobe structure */
 23static struct kprobe kp = {
 24	.symbol_name	= symbol,
 25};
 26
 27/* kprobe pre_handler: called just before the probed instruction is executed */
 28static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
 29{
 30#ifdef CONFIG_X86
 31	pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
 32		p->symbol_name, p->addr, regs->ip, regs->flags);
 33#endif
 34#ifdef CONFIG_PPC
 35	pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
 36		p->symbol_name, p->addr, regs->nip, regs->msr);
 37#endif
 38#ifdef CONFIG_MIPS
 39	pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
 40		p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
 41#endif
 
 
 
 
 42#ifdef CONFIG_ARM64
 43	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n",
 
 44		p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
 45#endif
 46#ifdef CONFIG_ARM
 47	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n",
 48		p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr);
 49#endif
 50#ifdef CONFIG_RISCV
 51	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n",
 52		p->symbol_name, p->addr, regs->epc, regs->status);
 53#endif
 54#ifdef CONFIG_S390
 55	pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
 56		p->symbol_name, p->addr, regs->psw.addr, regs->flags);
 57#endif
 58#ifdef CONFIG_LOONGARCH
 59	pr_info("<%s> p->addr = 0x%p, era = 0x%lx, estat = 0x%lx\n",
 60		p->symbol_name, p->addr, regs->csr_era, regs->csr_estat);
 61#endif
 62
 63	/* A dump_stack() here will give a stack backtrace */
 64	return 0;
 65}
 66
 67/* kprobe post_handler: called after the probed instruction is executed */
 68static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
 69				unsigned long flags)
 70{
 71#ifdef CONFIG_X86
 72	pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n",
 73		p->symbol_name, p->addr, regs->flags);
 74#endif
 75#ifdef CONFIG_PPC
 76	pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n",
 77		p->symbol_name, p->addr, regs->msr);
 78#endif
 79#ifdef CONFIG_MIPS
 80	pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
 81		p->symbol_name, p->addr, regs->cp0_status);
 82#endif
 
 
 
 
 83#ifdef CONFIG_ARM64
 84	pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n",
 85		p->symbol_name, p->addr, (long)regs->pstate);
 86#endif
 87#ifdef CONFIG_ARM
 88	pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n",
 89		p->symbol_name, p->addr, (long)regs->ARM_cpsr);
 90#endif
 91#ifdef CONFIG_RISCV
 92	pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
 93		p->symbol_name, p->addr, regs->status);
 94#endif
 95#ifdef CONFIG_S390
 96	pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n",
 97		p->symbol_name, p->addr, regs->flags);
 98#endif
 99#ifdef CONFIG_LOONGARCH
100	pr_info("<%s> p->addr = 0x%p, estat = 0x%lx\n",
101		p->symbol_name, p->addr, regs->csr_estat);
102#endif
103}
104
105static int __init kprobe_init(void)
106{
107	int ret;
108	kp.pre_handler = handler_pre;
109	kp.post_handler = handler_post;
 
110
111	ret = register_kprobe(&kp);
112	if (ret < 0) {
113		pr_err("register_kprobe failed, returned %d\n", ret);
114		return ret;
115	}
116	pr_info("Planted kprobe at %p\n", kp.addr);
117	return 0;
118}
119
120static void __exit kprobe_exit(void)
121{
122	unregister_kprobe(&kp);
123	pr_info("kprobe at %p unregistered\n", kp.addr);
124}
125
126module_init(kprobe_init)
127module_exit(kprobe_exit)
128MODULE_DESCRIPTION("sample kernel module showing the use of kprobes");
129MODULE_LICENSE("GPL");
v4.10.11
 
  1/*
  2 * NOTE: This example is works on x86 and powerpc.
  3 * Here's a sample kernel module showing the use of kprobes to dump a
  4 * stack trace and selected registers when _do_fork() is called.
  5 *
  6 * For more information on theory of operation of kprobes, see
  7 * Documentation/kprobes.txt
  8 *
  9 * You will see the trace data in /var/log/messages and on the console
 10 * whenever _do_fork() is invoked to create a new process.
 11 */
 12
 
 
 13#include <linux/kernel.h>
 14#include <linux/module.h>
 15#include <linux/kprobes.h>
 16
 17#define MAX_SYMBOL_LEN	64
 18static char symbol[MAX_SYMBOL_LEN] = "_do_fork";
 19module_param_string(symbol, symbol, sizeof(symbol), 0644);
 20
 21/* For each probe you need to allocate a kprobe structure */
 22static struct kprobe kp = {
 23	.symbol_name	= symbol,
 24};
 25
 26/* kprobe pre_handler: called just before the probed instruction is executed */
 27static int handler_pre(struct kprobe *p, struct pt_regs *regs)
 28{
 29#ifdef CONFIG_X86
 30	pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
 31		p->symbol_name, p->addr, regs->ip, regs->flags);
 32#endif
 33#ifdef CONFIG_PPC
 34	pr_info("<%s> pre_handler: p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
 35		p->symbol_name, p->addr, regs->nip, regs->msr);
 36#endif
 37#ifdef CONFIG_MIPS
 38	pr_info("<%s> pre_handler: p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
 39		p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
 40#endif
 41#ifdef CONFIG_TILEGX
 42	pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx, ex1 = 0x%lx\n",
 43		p->symbol_name, p->addr, regs->pc, regs->ex1);
 44#endif
 45#ifdef CONFIG_ARM64
 46	pr_info("<%s> pre_handler: p->addr = 0x%p, pc = 0x%lx,"
 47			" pstate = 0x%lx\n",
 48		p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
 49#endif
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 50
 51	/* A dump_stack() here will give a stack backtrace */
 52	return 0;
 53}
 54
 55/* kprobe post_handler: called after the probed instruction is executed */
 56static void handler_post(struct kprobe *p, struct pt_regs *regs,
 57				unsigned long flags)
 58{
 59#ifdef CONFIG_X86
 60	pr_info("<%s> post_handler: p->addr = 0x%p, flags = 0x%lx\n",
 61		p->symbol_name, p->addr, regs->flags);
 62#endif
 63#ifdef CONFIG_PPC
 64	pr_info("<%s> post_handler: p->addr = 0x%p, msr = 0x%lx\n",
 65		p->symbol_name, p->addr, regs->msr);
 66#endif
 67#ifdef CONFIG_MIPS
 68	pr_info("<%s> post_handler: p->addr = 0x%p, status = 0x%lx\n",
 69		p->symbol_name, p->addr, regs->cp0_status);
 70#endif
 71#ifdef CONFIG_TILEGX
 72	pr_info("<%s> post_handler: p->addr = 0x%p, ex1 = 0x%lx\n",
 73		p->symbol_name, p->addr, regs->ex1);
 74#endif
 75#ifdef CONFIG_ARM64
 76	pr_info("<%s> post_handler: p->addr = 0x%p, pstate = 0x%lx\n",
 77		p->symbol_name, p->addr, (long)regs->pstate);
 78#endif
 79}
 80
 81/*
 82 * fault_handler: this is called if an exception is generated for any
 83 * instruction within the pre- or post-handler, or when Kprobes
 84 * single-steps the probed instruction.
 85 */
 86static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)
 87{
 88	pr_info("fault_handler: p->addr = 0x%p, trap #%dn", p->addr, trapnr);
 89	/* Return 0 because we don't handle the fault. */
 90	return 0;
 
 
 
 
 91}
 92
 93static int __init kprobe_init(void)
 94{
 95	int ret;
 96	kp.pre_handler = handler_pre;
 97	kp.post_handler = handler_post;
 98	kp.fault_handler = handler_fault;
 99
100	ret = register_kprobe(&kp);
101	if (ret < 0) {
102		pr_err("register_kprobe failed, returned %d\n", ret);
103		return ret;
104	}
105	pr_info("Planted kprobe at %p\n", kp.addr);
106	return 0;
107}
108
109static void __exit kprobe_exit(void)
110{
111	unregister_kprobe(&kp);
112	pr_info("kprobe at %p unregistered\n", kp.addr);
113}
114
115module_init(kprobe_init)
116module_exit(kprobe_exit)
 
117MODULE_LICENSE("GPL");