root/samples/hw_breakpoint/data_breakpoint.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. sample_hbp_handler
  2. hw_break_module_init
  3. hw_break_module_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * data_breakpoint.c - Sample HW Breakpoint file to watch kernel data address
   4  *
   5  * usage: insmod data_breakpoint.ko ksym=<ksym_name>
   6  *
   7  * This file is a kernel module that places a breakpoint over ksym_name kernel
   8  * variable using Hardware Breakpoint register. The corresponding handler which
   9  * prints a backtrace is invoked every time a write operation is performed on
  10  * that variable.
  11  *
  12  * Copyright (C) IBM Corporation, 2009
  13  *
  14  * Author: K.Prasad <prasad@linux.vnet.ibm.com>
  15  */
  16 #include <linux/module.h>       /* Needed by all modules */
  17 #include <linux/kernel.h>       /* Needed for KERN_INFO */
  18 #include <linux/init.h>         /* Needed for the macros */
  19 #include <linux/kallsyms.h>
  20 
  21 #include <linux/perf_event.h>
  22 #include <linux/hw_breakpoint.h>
  23 
  24 struct perf_event * __percpu *sample_hbp;
  25 
  26 static char ksym_name[KSYM_NAME_LEN] = "pid_max";
  27 module_param_string(ksym, ksym_name, KSYM_NAME_LEN, S_IRUGO);
  28 MODULE_PARM_DESC(ksym, "Kernel symbol to monitor; this module will report any"
  29                         " write operations on the kernel symbol");
  30 
  31 static void sample_hbp_handler(struct perf_event *bp,
  32                                struct perf_sample_data *data,
  33                                struct pt_regs *regs)
  34 {
  35         printk(KERN_INFO "%s value is changed\n", ksym_name);
  36         dump_stack();
  37         printk(KERN_INFO "Dump stack from sample_hbp_handler\n");
  38 }
  39 
  40 static int __init hw_break_module_init(void)
  41 {
  42         int ret;
  43         struct perf_event_attr attr;
  44 
  45         hw_breakpoint_init(&attr);
  46         attr.bp_addr = kallsyms_lookup_name(ksym_name);
  47         attr.bp_len = HW_BREAKPOINT_LEN_4;
  48         attr.bp_type = HW_BREAKPOINT_W | HW_BREAKPOINT_R;
  49 
  50         sample_hbp = register_wide_hw_breakpoint(&attr, sample_hbp_handler, NULL);
  51         if (IS_ERR((void __force *)sample_hbp)) {
  52                 ret = PTR_ERR((void __force *)sample_hbp);
  53                 goto fail;
  54         }
  55 
  56         printk(KERN_INFO "HW Breakpoint for %s write installed\n", ksym_name);
  57 
  58         return 0;
  59 
  60 fail:
  61         printk(KERN_INFO "Breakpoint registration failed\n");
  62 
  63         return ret;
  64 }
  65 
  66 static void __exit hw_break_module_exit(void)
  67 {
  68         unregister_wide_hw_breakpoint(sample_hbp);
  69         printk(KERN_INFO "HW Breakpoint for %s write uninstalled\n", ksym_name);
  70 }
  71 
  72 module_init(hw_break_module_init);
  73 module_exit(hw_break_module_exit);
  74 
  75 MODULE_LICENSE("GPL");
  76 MODULE_AUTHOR("K.Prasad");
  77 MODULE_DESCRIPTION("ksym breakpoint");

/* [<][>][^][v][top][bottom][index][help] */