cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kprobe_example.c (3532B)


      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
     19#define MAX_SYMBOL_LEN	64
     20static char symbol[MAX_SYMBOL_LEN] = "kernel_clone";
     21module_param_string(symbol, symbol, sizeof(symbol), 0644);
     22
     23/* For each probe you need to allocate a kprobe structure */
     24static struct kprobe kp = {
     25	.symbol_name	= symbol,
     26};
     27
     28/* kprobe pre_handler: called just before the probed instruction is executed */
     29static int __kprobes handler_pre(struct kprobe *p, struct pt_regs *regs)
     30{
     31#ifdef CONFIG_X86
     32	pr_info("<%s> p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
     33		p->symbol_name, p->addr, regs->ip, regs->flags);
     34#endif
     35#ifdef CONFIG_PPC
     36	pr_info("<%s> p->addr = 0x%p, nip = 0x%lx, msr = 0x%lx\n",
     37		p->symbol_name, p->addr, regs->nip, regs->msr);
     38#endif
     39#ifdef CONFIG_MIPS
     40	pr_info("<%s> p->addr = 0x%p, epc = 0x%lx, status = 0x%lx\n",
     41		p->symbol_name, p->addr, regs->cp0_epc, regs->cp0_status);
     42#endif
     43#ifdef CONFIG_ARM64
     44	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, pstate = 0x%lx\n",
     45		p->symbol_name, p->addr, (long)regs->pc, (long)regs->pstate);
     46#endif
     47#ifdef CONFIG_ARM
     48	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, cpsr = 0x%lx\n",
     49		p->symbol_name, p->addr, (long)regs->ARM_pc, (long)regs->ARM_cpsr);
     50#endif
     51#ifdef CONFIG_RISCV
     52	pr_info("<%s> p->addr = 0x%p, pc = 0x%lx, status = 0x%lx\n",
     53		p->symbol_name, p->addr, regs->epc, regs->status);
     54#endif
     55#ifdef CONFIG_S390
     56	pr_info("<%s> p->addr, 0x%p, ip = 0x%lx, flags = 0x%lx\n",
     57		p->symbol_name, p->addr, regs->psw.addr, regs->flags);
     58#endif
     59
     60	/* A dump_stack() here will give a stack backtrace */
     61	return 0;
     62}
     63
     64/* kprobe post_handler: called after the probed instruction is executed */
     65static void __kprobes handler_post(struct kprobe *p, struct pt_regs *regs,
     66				unsigned long flags)
     67{
     68#ifdef CONFIG_X86
     69	pr_info("<%s> p->addr = 0x%p, flags = 0x%lx\n",
     70		p->symbol_name, p->addr, regs->flags);
     71#endif
     72#ifdef CONFIG_PPC
     73	pr_info("<%s> p->addr = 0x%p, msr = 0x%lx\n",
     74		p->symbol_name, p->addr, regs->msr);
     75#endif
     76#ifdef CONFIG_MIPS
     77	pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
     78		p->symbol_name, p->addr, regs->cp0_status);
     79#endif
     80#ifdef CONFIG_ARM64
     81	pr_info("<%s> p->addr = 0x%p, pstate = 0x%lx\n",
     82		p->symbol_name, p->addr, (long)regs->pstate);
     83#endif
     84#ifdef CONFIG_ARM
     85	pr_info("<%s> p->addr = 0x%p, cpsr = 0x%lx\n",
     86		p->symbol_name, p->addr, (long)regs->ARM_cpsr);
     87#endif
     88#ifdef CONFIG_RISCV
     89	pr_info("<%s> p->addr = 0x%p, status = 0x%lx\n",
     90		p->symbol_name, p->addr, regs->status);
     91#endif
     92#ifdef CONFIG_S390
     93	pr_info("<%s> p->addr, 0x%p, flags = 0x%lx\n",
     94		p->symbol_name, p->addr, regs->flags);
     95#endif
     96}
     97
     98static int __init kprobe_init(void)
     99{
    100	int ret;
    101	kp.pre_handler = handler_pre;
    102	kp.post_handler = handler_post;
    103
    104	ret = register_kprobe(&kp);
    105	if (ret < 0) {
    106		pr_err("register_kprobe failed, returned %d\n", ret);
    107		return ret;
    108	}
    109	pr_info("Planted kprobe at %p\n", kp.addr);
    110	return 0;
    111}
    112
    113static void __exit kprobe_exit(void)
    114{
    115	unregister_kprobe(&kp);
    116	pr_info("kprobe at %p unregistered\n", kp.addr);
    117}
    118
    119module_init(kprobe_init)
    120module_exit(kprobe_exit)
    121MODULE_LICENSE("GPL");