Skip to contentSkip to conversation

tracing: wprobe: Add wprobe for watchpoint

PATCH Superseded Masami Hiramatsu (Google) 2 participants 11 messages Sep 5, 2025 – Sep 10, 2025

Subsystems (5)

v2 of 19 Superseded Latest is v19 →

lore
Share & tools
lore

Masami Hiramatsu (Google)

author maintainer
#0 lore raw

v2 cover tracing: wprobe: Add wprobe for watchpoint

Hi,

Here is the 2nd version of the series for adding new wprobe (watch probe) which provides memory access tracing event. Moreover, this can be used via event trigger. Thus it can trace memory access on a dynamically allocated objects too.

This version fixes an unused static function error when CONFIG_WPROBE_TRIGGERS=n. Also it allows modify_wide_hw_breakpoint() to change compatible types. And make CONFIG_WPROBE_TRIGGERS a hidden config (enable if possible.)

I introduced CONFIG_HAVE_REINSTALL_HW_BREAKPOINT because it allows us to implement dependency of the feature which requires the modify_wide_hw_breakpoint(), e.g. CONFIG_WPROBE_TRIGGERS. So, the architecture which implement arch_reinstall_hw_breakpoint() will enable HAVE_REINSTALL_HW_BREAKPOINT.

The basic usage of this wprobe is similar to other probes;

w:[GRP/][EVENT] [r|w|rw]@<ADDRESS|SYMBOL[+OFFS]> [FETCHARGS]

This defines a new wprobe event. For example, to trace jiffies update, you can do;

echo 'w:my_jiffies w@jiffies:8 value=+0($addr)' >> dynamic_events echo 1 > events/wprobes/my_jiffies/enable

Moreover, this can be combined with event trigger to trace the memory accecss on slab objects. The trigger syntax is;

set_wprobe:WPROBE_EVENT:FIELD[+ADJUST]
clear_wprobe:WPROBE_EVENT

For example, trace the first 8 byte of the dentry data structure passed to do_truncate() until it is deleted by __dentry_kill(). (Note: all tracefs setup uses '>>' so that it does not kick do_truncate())

  # echo 'w:watch rw@0:8 address=$addr value=+0($addr)' > dynamic_events
  # echo 'f:truncate do_truncate dentry=$arg2' >> dynamic_events
  # echo 'set_wprobe:watch:dentry' >> events/fprobes/truncate/trigger
  # echo 'f:dentry_kill __dentry_kill dentry=$arg1' >> dynamic_events
  # echo 'clear_wprobe:watch' >> events/fprobes/dentry_kill/trigger
  # echo 1 >> events/fprobes/truncate/enable
  # echo 1 >> events/fprobes/dentry_kill/enable
  # echo aaa > /tmp/hoge
  # echo bbb > /tmp/hoge
  # echo ccc > /tmp/hoge
  # rm /tmp/hoge

Then, the trace data will show;

# tracer: nop
#
# entries-in-buffer/entries-written: 16/16 #P:8
#
# _-----=> irqs-off/BH-disabled
# / _----=> need-resched

#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#    [    7.026136] sh (113) used greatest stack depth: 12912 bytes left
          | |         |   |||||     |         |
              sh-113     [002] .....     7.024402: truncate: (do_truncate+0x4/0x120) dentry=0xffff8880069194b8
              sh-113     [002] ..Zff     7.024822: watch: (lookup_fast+0xaa/0x150) address=0xffff8880069194b8 value=0x200008
              sh-113     [002] ..Zff     7.024830: watch: (step_into+0x82/0x360) address=0xffff8880069194b8 value=0x200008
              sh-113     [002] ..Zff     7.024834: watch: (step_into+0x9f/0x360) address=0xffff8880069194b8 value=0x200008
              sh-113     [002] ..Zff     7.024839: watch: (path_openat+0xb3a/0xe70) address=0xffff8880069194b8 value=0x200008
              sh-113     [002] ..Zff     7.024843: watch: (path_openat+0xb9a/0xe70) address=0xffff8880069194b8 value=0x200008
              sh-113     [002] .....     7.024847: truncate: (do_truncate+0x4/0x120) dentry=0xffff8880069194b8
              sh-113     [002] ...1.     7.025364: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff888006919380
              sh-113     [002] ...1.     7.025511: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880069195f0
              rm-118     [003] ...1.     7.027543: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880069194b8
              sh-113     [002] ...2.     7.027825: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880044429c0
              sh-113     [002] ...2.     7.027833: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff888004442270

Thank you,

---

Jinchao Wang (1):
x86/HWBP: introduce arch_reinstall_hw_breakpoint() for atomic context

Masami Hiramatsu (Google) (5):
tracing: wprobe: Add watchpoint probe event based on hardware breakpoint
HWBP: Add modify_wide_hw_breakpoint_local() API
tracing: wprobe: Add wprobe event trigger
selftests: tracing: Add a basic testcase for wprobe
selftests: tracing: Add syntax testcase for wprobe

 Documentation/trace/index.rst                      |    1 
 Documentation/trace/wprobetrace.rst                |  129 ++
 arch/Kconfig                                       |   10 
 arch/x86/Kconfig                                   |    1 
 arch/x86/include/asm/hw_breakpoint.h               |    1 
 arch/x86/kernel/hw_breakpoint.c                    |   50 +
 include/linux/hw_breakpoint.h                      |    6 
 include/linux/trace_events.h                       |    3 
 kernel/events/hw_breakpoint.c                      |   36 +
 kernel/trace/Kconfig                               |   24 
 kernel/trace/Makefile                              |    1 
 kernel/trace/trace.c                               |    9 
 kernel/trace/trace.h                               |    5 
 kernel/trace/trace_probe.c                         |   20 
 kernel/trace/trace_probe.h                         |    8 
 kernel/trace/trace_wprobe.c                        | 1104 ++++++++++++++++++++
 .../ftrace/test.d/dynevent/add_remove_wprobe.tc    |   68 +
 .../test.d/dynevent/wprobes_syntax_errors.tc       |   20 
 18 files changed, 1493 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/trace/wprobetrace.rst
 create mode 100644 kernel/trace/trace_wprobe.c
 create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/add_remove_wprobe.tc
 create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/wprobes_syntax_errors.tc

--
Masami Hiramatsu (Google) <[email protected]>

author maintainer
#1 lore raw

PATCH v2 1/6 tracing: wprobe: Add watchpoint probe event based on hardware breakpoint

From: Masami Hiramatsu (Google) <[email protected]>

Add a new probe event for the hardware breakpoint called wprobe-event. This wprobe allows user to trace (watch) the memory access at the specified memory address.
The new syntax is;

w[:[GROUP/]EVENT] [r|w|rw]@[ADDR|SYM][:SIZE] [FETCH_ARGs]

User also can use $addr to fetch the accessed address. But no other variables are supported. To record updated value, use '+0($addr)'.

For example, tracing updates of the jiffies;

/sys/kernel/tracing # echo 'w:my_jiffies w@jiffies' >> dynamic_events /sys/kernel/tracing # cat dynamic_events w:wprobes/my_jiffies w@jiffies:4
/sys/kernel/tracing # echo 1 > events/wprobes/my_jiffies/enable /sys/kernel/tracing # head -n 20 trace | tail -n 5

 #           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
 #              | |         |   |||||     |         |
          <idle>-0       [000] d.Z1.   206.547317: my_jiffies: (tick_do_update_jiffies64+0xbe/0x130)
          <idle>-0       [000] d.Z1.   206.548341: my_jiffies: (tick_do_update_jiffies64+0xbe/0x130)
          <idle>-0       [000] d.Z1.   206.549346: my_jiffies: (tick_do_update_jiffies64+0xbe/0x130)
---
 Documentation/trace/index.rst       |    1 
 Documentation/trace/wprobetrace.rst |   69 ++++
 include/linux/trace_events.h        |    2 
 kernel/trace/Kconfig                |   14 +
 kernel/trace/Makefile               |    1 
 kernel/trace/trace.c                |    9 
 kernel/trace/trace.h                |    5 
 kernel/trace/trace_probe.c          |   20 +
 kernel/trace/trace_probe.h          |    8 
 kernel/trace/trace_wprobe.c         |  685 +++++++++++++++++++++++++++++++++++
 10 files changed, 811 insertions(+), 3 deletions(-)
 create mode 100644 Documentation/trace/wprobetrace.rst
 create mode 100644 kernel/trace/trace_wprobe.c
Documentation/trace/index.rst +1 -0
index b4a429dc4f7a..14de6858ae1b 100644
@@ -36,6 +36,7 @@ the Linux kernel.
    kprobes
    kprobetrace
    fprobetrace
+   wprobetrace
    eprobetrace
    fprobe
    ring-buffer-design
Documentation/trace/wprobetrace.rst new file +69 -0

69 lines not on this page · raw message

include/linux/trace_events.h +2 -0
index 04307a19cde3..7c65f2f73ff4 100644
@@ -324,6 +324,7 @@ enum {
 	TRACE_EVENT_FL_UPROBE_BIT,
 	TRACE_EVENT_FL_EPROBE_BIT,
 	TRACE_EVENT_FL_FPROBE_BIT,
+	TRACE_EVENT_FL_WPROBE_BIT,
 	TRACE_EVENT_FL_CUSTOM_BIT,
 	TRACE_EVENT_FL_TEST_STR_BIT,
 };
@@ -354,6 +355,7 @@ enum {
 	TRACE_EVENT_FL_UPROBE		= (1 << TRACE_EVENT_FL_UPROBE_BIT),
 	TRACE_EVENT_FL_EPROBE		= (1 << TRACE_EVENT_FL_EPROBE_BIT),
 	TRACE_EVENT_FL_FPROBE		= (1 << TRACE_EVENT_FL_FPROBE_BIT),
+	TRACE_EVENT_FL_WPROBE		= (1 << TRACE_EVENT_FL_WPROBE_BIT),
 	TRACE_EVENT_FL_CUSTOM		= (1 << TRACE_EVENT_FL_CUSTOM_BIT),
 	TRACE_EVENT_FL_TEST_STR		= (1 << TRACE_EVENT_FL_TEST_STR_BIT),
 };
kernel/trace/Kconfig +14 -0
index d2c79da81e4f..dd8919386425 100644
@@ -807,6 +807,20 @@ config EPROBE_EVENTS
 	  convert the type of an event field. For example, turn an
 	  address into a string.
 
+config WPROBE_EVENTS
+	bool "Enable wprobe-based dynamic events"
+	depends on TRACING
+	depends on HAVE_HW_BREAKPOINT
+	select PROBE_EVENTS
+	select DYNAMIC_EVENTS
+	default y
+	help
+	  This allows the user to add watchpoint tracing events based on
+	  hardware breakpoints on the fly via the ftrace interface.
+
+	  Those events can be inserted wherever hardware breakpoints can be
+	  set, and record various register and memory values.
+
 config BPF_EVENTS
 	depends on BPF_SYSCALL
 	depends on (KPROBE_EVENTS || UPROBE_EVENTS) && PERF_EVENTS
kernel/trace/Makefile +1 -0
index dcb4e02afc5f..1d57bb36c5fc 100644
@@ -106,6 +106,7 @@ obj-$(CONFIG_FTRACE_RECORD_RECURSION) += trace_recursion_record.o
 obj-$(CONFIG_FPROBE) += fprobe.o
 obj-$(CONFIG_RETHOOK) += rethook.o
 obj-$(CONFIG_FPROBE_EVENTS) += trace_fprobe.o
+obj-$(CONFIG_WPROBE_EVENTS) += trace_wprobe.o
 
 obj-$(CONFIG_TRACEPOINT_BENCHMARK) += trace_benchmark.o
 obj-$(CONFIG_RV) += rv/
kernel/trace/trace.c +8 -1
index 4283ed4e8f59..ac2fc6d768ad 100644
@@ -5506,8 +5506,12 @@ static const char readme_msg[] =
 	"  uprobe_events\t\t- Create/append/remove/show the userspace dynamic events\n"
 	"\t\t\t  Write into this file to define/undefine new trace events.\n"
 #endif
+#ifdef CONFIG_WPROBE_EVENTS
+	"  wprobe_events\t\t- Create/append/remove/show the hardware breakpoint dynamic events\n"
+	"\t\t\t  Write into this file to define/undefine new trace events.\n"
+#endif
 #if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS) || \
-    defined(CONFIG_FPROBE_EVENTS)
+    defined(CONFIG_FPROBE_EVENTS) || defined(CONFIG_WPROBE_EVENTS)
 	"\t  accepts: event-definitions (one definition per line)\n"
 #if defined(CONFIG_KPROBE_EVENTS) || defined(CONFIG_UPROBE_EVENTS)
 	"\t   Format: p[:[<group>/][<event>]] <place> [<args>]\n"
@@ -5517,6 +5521,9 @@ static const char readme_msg[] =
 	"\t           f[:[<group>/][<event>]] <func-name>[%return] [<args>]\n"
 	"\t           t[:[<group>/][<event>]] <tracepoint> [<args>]\n"
 #endif
+#ifdef CONFIG_WPROBE_EVENTS
+	"\t           w[:[<group>/][<event>]] [r|w|rw]@<addr>[:<len>]\n"
+#endif
 #ifdef CONFIG_HIST_TRIGGERS
 	"\t           s:[synthetic/]<event> <field> [<field>]\n"
 #endif
kernel/trace/trace.h +5 -0
index 1dbf1d3cf2f1..ae175ddc3f58 100644
@@ -173,6 +173,11 @@ struct fexit_trace_entry_head {
 	unsigned long		ret_ip;
 };
 
+struct wprobe_trace_entry_head {
+	struct trace_entry	ent;
+	unsigned long		ip;
+};
+
 #define TRACE_BUF_SIZE		1024
 
 struct trace_array;
kernel/trace/trace_probe.c +19 -1
index 5b92376a58fc..ef500c373f3c 100644
@@ -968,6 +968,24 @@ static int parse_probe_vars(char *orig_arg, const struct fetch_type *t,
 		goto inval;
 	}
 
+	/* wprobe only support "$addr" and "$value" variable */
+	if (ctx->flags & TPARG_FL_WPROBE) {
+		if (!strcmp(arg, "addr")) {
+			code->op = FETCH_OP_BADDR;
+			return 0;
+		}
+		if (!strcmp(arg, "value")) {
+			code->op = FETCH_OP_BADDR;
+			code++;
+			code->op = FETCH_OP_DEREF;
+			code->offset = 0;
+			*pcode = code;
+			return 0;
+		}
+		err = TP_ERR_BAD_VAR;
+		goto inval;
+	}
+
 	if (str_has_prefix(arg, "retval")) {
 		if (!(ctx->flags & TPARG_FL_RETURN)) {
 			err = TP_ERR_RETVAL_ON_PROBE;
@@ -1098,7 +1116,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
 		break;
 
 	case '%':	/* named register */
-		if (ctx->flags & (TPARG_FL_TEVENT | TPARG_FL_FPROBE)) {
+		if (ctx->flags & (TPARG_FL_TEVENT | TPARG_FL_FPROBE | TPARG_FL_WPROBE)) {
 			/* eprobe and fprobe do not handle registers */
 			trace_probe_log_err(ctx->offset, BAD_VAR);
 			break;
kernel/trace/trace_probe.h +7 -1
index 76bf2dee8071..13c9dbc4d0e2 100644
@@ -89,6 +89,7 @@ enum fetch_op {
 	FETCH_OP_STACK,		/* Stack : .param = index */
 	FETCH_OP_STACKP,	/* Stack pointer */
 	FETCH_OP_RETVAL,	/* Return value */
+	FETCH_OP_BADDR,		/* Break address */
 	FETCH_OP_IMM,		/* Immediate : .immediate */
 	FETCH_OP_COMM,		/* Current comm */
 	FETCH_OP_ARG,		/* Function argument : .param */
@@ -396,6 +397,7 @@ static inline int traceprobe_get_entry_data_size(struct trace_probe *tp)
 #define TPARG_FL_USER   BIT(4)
 #define TPARG_FL_FPROBE BIT(5)
 #define TPARG_FL_TPOINT BIT(6)
+#define TPARG_FL_WPROBE BIT(7)
 #define TPARG_FL_LOC_MASK	GENMASK(4, 0)
 
 static inline bool tparg_is_function_entry(unsigned int flags)
@@ -556,7 +558,11 @@ extern int traceprobe_define_arg_fields(struct trace_event_call *event_call,
 	C(BAD_TYPE4STR,		"This type does not fit for string."),\
 	C(NEED_STRING_TYPE,	"$comm and immediate-string only accepts string type"),\
 	C(TOO_MANY_ARGS,	"Too many arguments are specified"),	\
-	C(TOO_MANY_EARGS,	"Too many entry arguments specified"),
+	C(TOO_MANY_EARGS,	"Too many entry arguments specified"),	\
+	C(BAD_ACCESS_FMT,	"Access memory address requires @"),	\
+	C(BAD_ACCESS_TYPE,	"Bad memory access type"),	\
+	C(BAD_ACCESS_LEN,	"This memory access length is not supported"), \
+	C(BAD_ACCESS_ADDR,	"Invalid access memory address"),
 
 #undef C
 #define C(a, b)		TP_ERR_##a
kernel/trace/trace_wprobe.c new file +685 -0

685 lines not on this page · raw message

#2 lore raw

Re: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint

kernel test robot noticed the following build warnings:

Hi Masami,

kernel test robot noticed the following build warnings:

[auto build test WARNING on trace/for-next]
[also build test WARNING on tip/x86/core perf-tools-next/perf-tools-next tip/perf/core perf-tools/perf-tools peterz-queue/sched/core linus/master v6.17-rc5 next-20250908] [cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu-Google/tracing-wprobe-Add-watchpoint-probe-event-based-on-hardware-breakpoint/20250905-230532
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/175708429018.64001.14265428106568623070.stgit%40devnote2
patch subject: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint
config: x86_64-defconfig (https://download.01.org/0day-ci/archive/20250908/[email protected]/config)
compiler: gcc-14 (Debian 14.2.0-19) 14.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250908/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All warnings (new ones prefixed by >>):

kernel/trace/trace_wprobe.c: In function '__register_trace_wprobe':

>> kernel/trace/trace_wprobe.c:176:20: warning: cast to generic address space pointer from disjoint '__seg_gs' address space pointer
     176 |         if (IS_ERR((void * __force)tw->bp_event)) {
         |                    ^
   kernel/trace/trace_wprobe.c:177:35: warning: cast to generic address space pointer from disjoint '__seg_gs' address space pointer
     177 |                 int ret = PTR_ERR((void * __force)tw->bp_event);
         |                                   ^

vim +/__seg_gs +176 kernel/trace/trace_wprobe.c

162
163 static int __register_trace_wprobe(struct trace_wprobe *tw)
164 {
165 struct perf_event_attr attr;
166
167 if (tw->bp_event)
168 return -EINVAL;
169
170 hw_breakpoint_init(&attr);
171 attr.bp_addr = tw->addr;
172 attr.bp_len = tw->len;
173 attr.bp_type = tw->type;
174
175 tw->bp_event = register_wide_hw_breakpoint(&attr, wprobe_perf_handler, tw);

 > 176		if (IS_ERR((void * __force)tw->bp_event)) {

177 int ret = PTR_ERR((void * __force)tw->bp_event);
178
179 tw->bp_event = NULL;
180 return ret;
181 }
182
183 return 0;
184 }
185

Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
#3 lore raw

Re: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint

In reply to Masami Hiramatsu (Google)
kernel test robot noticed the following build errors:

Hi Masami,

kernel test robot noticed the following build errors:

[auto build test ERROR on trace/for-next]
[also build test ERROR on tip/x86/core perf-tools-next/perf-tools-next tip/perf/core perf-tools/perf-tools peterz-queue/sched/core linus/master v6.17-rc5 next-20250909] [cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu-Google/tracing-wprobe-Add-watchpoint-probe-event-based-on-hardware-breakpoint/20250905-230532
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/175708429018.64001.14265428106568623070.stgit%40devnote2
patch subject: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint
config: xtensa-allyesconfig (https://download.01.org/0day-ci/archive/20250909/[email protected]/config)
compiler: xtensa-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250909/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

kernel/trace/trace_probe.c: In function 'parse_probe_arg':

>> kernel/trace/trace_probe.c:1124:23: error: implicit declaration of function 'regs_query_register_offset'; did you mean 'ftrace_regs_query_register_offset'? [-Wimplicit-function-declaration]
    1124 |                 ret = regs_query_register_offset(arg + 1);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                       ftrace_regs_query_register_offset

vim +1124 kernel/trace/trace_probe.c

a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1099  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1100  /* Recursive argument parser */
533059281ee594f Masami Hiramatsu          2018-04-25  1101  static int
533059281ee594f Masami Hiramatsu          2018-04-25  1102  parse_probe_arg(char *arg, const struct fetch_type *type,
533059281ee594f Masami Hiramatsu          2018-04-25  1103  		struct fetch_insn **pcode, struct fetch_insn *end,
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1104) 		struct traceprobe_parse_context *ctx)
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1105  {
533059281ee594f Masami Hiramatsu          2018-04-25  1106  	struct fetch_insn *code = *pcode;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1107  	unsigned long param;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1108  	int deref = FETCH_OP_DEREF;
bf173ca92da9786 Steven Rostedt (VMware    2018-10-12  1109) 	long offset = 0;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1110  	char *tmp;
34fee3a104cea1c Namhyung Kim              2013-11-26  1111  	int ret = 0;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1112  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1113  	switch (arg[0]) {
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1114  	case '$':
d157d7694460b9a Masami Hiramatsu (Google  2023-08-23  1115) 		ret = parse_probe_vars(arg, type, pcode, end, ctx);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1116  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1117  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1118  	case '%':	/* named register */
57cb2426dbf36f2 Masami Hiramatsu (Google  2025-09-05  1119) 		if (ctx->flags & (TPARG_FL_TEVENT | TPARG_FL_FPROBE | TPARG_FL_WPROBE)) {
334e5519c375701 Masami Hiramatsu (Google  2023-06-06  1120) 			/* eprobe and fprobe do not handle registers */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1121) 			trace_probe_log_err(ctx->offset, BAD_VAR);
2673c60ee67e71f Steven Rostedt (Google    2022-08-20  1122) 			break;
2673c60ee67e71f Steven Rostedt (Google    2022-08-20  1123) 		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09 @1124  		ret = regs_query_register_offset(arg + 1);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1125  		if (ret >= 0) {
533059281ee594f Masami Hiramatsu          2018-04-25  1126  			code->op = FETCH_OP_REG;
533059281ee594f Masami Hiramatsu          2018-04-25  1127  			code->param = (unsigned int)ret;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1128  			ret = 0;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1129  		} else
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1130) 			trace_probe_log_err(ctx->offset, BAD_REG_NAME);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1131  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1132  
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1133  	case '@':	/* memory, file-offset or symbol */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1134  		if (isdigit(arg[1])) {
bcd83ea6cbfee54 Daniel Walter             2012-09-26  1135  			ret = kstrtoul(arg + 1, 0, &param);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1136  			if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1137) 				trace_probe_log_err(ctx->offset, BAD_MEM_ADDR);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1138  				break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1139  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1140  			/* load address */
533059281ee594f Masami Hiramatsu          2018-04-25  1141  			code->op = FETCH_OP_IMM;
533059281ee594f Masami Hiramatsu          2018-04-25  1142  			code->immediate = param;
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1143  		} else if (arg[1] == '+') {
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1144  			/* kprobes don't support file offsets */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1145) 			if (ctx->flags & TPARG_FL_KERNEL) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1146) 				trace_probe_log_err(ctx->offset, FILE_ON_KPROBE);
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1147  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1148  			}
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1149  			ret = kstrtol(arg + 2, 0, &offset);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1150  			if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1151) 				trace_probe_log_err(ctx->offset, BAD_FILE_OFFS);
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1152  				break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1153  			}
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1154  
533059281ee594f Masami Hiramatsu          2018-04-25  1155  			code->op = FETCH_OP_FOFFS;
533059281ee594f Masami Hiramatsu          2018-04-25  1156  			code->immediate = (unsigned long)offset;  // imm64?
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1157  		} else {
b079d374fd84637 Namhyung Kim              2013-07-03  1158  			/* uprobes don't support symbols */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1159) 			if (!(ctx->flags & TPARG_FL_KERNEL)) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1160) 				trace_probe_log_err(ctx->offset, SYM_ON_UPROBE);
b079d374fd84637 Namhyung Kim              2013-07-03  1161  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1162  			}
a6682814f37124e Masami Hiramatsu          2018-08-29  1163  			/* Preserve symbol for updating */
a6682814f37124e Masami Hiramatsu          2018-08-29  1164  			code->op = FETCH_NOP_SYMBOL;
a6682814f37124e Masami Hiramatsu          2018-08-29  1165  			code->data = kstrdup(arg + 1, GFP_KERNEL);
a6682814f37124e Masami Hiramatsu          2018-08-29  1166  			if (!code->data)
a6682814f37124e Masami Hiramatsu          2018-08-29  1167  				return -ENOMEM;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1168  			if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1169) 				trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1170  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1171  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1172  			code->op = FETCH_OP_IMM;
a6682814f37124e Masami Hiramatsu          2018-08-29  1173  			code->immediate = 0;
533059281ee594f Masami Hiramatsu          2018-04-25  1174  		}
533059281ee594f Masami Hiramatsu          2018-04-25  1175  		/* These are fetching from memory */
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1176  		if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1177) 			trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1178  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1179  		}
533059281ee594f Masami Hiramatsu          2018-04-25  1180  		*pcode = code;
533059281ee594f Masami Hiramatsu          2018-04-25  1181  		code->op = FETCH_OP_DEREF;
533059281ee594f Masami Hiramatsu          2018-04-25  1182  		code->offset = offset;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1183  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1184  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1185  	case '+':	/* deref memory */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1186  	case '-':
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1187  		if (arg[1] == 'u') {
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1188  			deref = FETCH_OP_UDEREF;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1189  			arg[1] = arg[0];
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1190  			arg++;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1191  		}
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1192  		if (arg[0] == '+')
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1193  			arg++;	/* Skip '+', because kstrtol() rejects it. */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1194  		tmp = strchr(arg, '(');
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1195  		if (!tmp) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1196) 			trace_probe_log_err(ctx->offset, DEREF_NEED_BRACE);
533059281ee594f Masami Hiramatsu          2018-04-25  1197  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1198  		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1199  		*tmp = '\0';
bcd83ea6cbfee54 Daniel Walter             2012-09-26  1200  		ret = kstrtol(arg, 0, &offset);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1201  		if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1202) 			trace_probe_log_err(ctx->offset, BAD_DEREF_OFFS);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1203  			break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1204  		}
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1205) 		ctx->offset += (tmp + 1 - arg) + (arg[0] != '-' ? 1 : 0);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1206  		arg = tmp + 1;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1207  		tmp = strrchr(arg, ')');
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1208  		if (!tmp) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1209) 			trace_probe_log_err(ctx->offset + strlen(arg),
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1210  					    DEREF_OPEN_BRACE);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1211  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1212  		} else {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1213) 			const struct fetch_type *t2 = find_fetch_type(NULL, ctx->flags);
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1214) 			int cur_offs = ctx->offset;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1215  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1216  			*tmp = '\0';
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1217) 			ret = parse_probe_arg(arg, t2, &code, end, ctx);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1218  			if (ret)
533059281ee594f Masami Hiramatsu          2018-04-25  1219  				break;
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1220) 			ctx->offset = cur_offs;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1221  			if (code->op == FETCH_OP_COMM ||
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1222  			    code->op == FETCH_OP_DATA) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1223) 				trace_probe_log_err(ctx->offset, COMM_CANT_DEREF);
533059281ee594f Masami Hiramatsu          2018-04-25  1224  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1225  			}
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1226  			if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1227) 				trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1228  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1229  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1230  			*pcode = code;
533059281ee594f Masami Hiramatsu          2018-04-25  1231  
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1232  			code->op = deref;
533059281ee594f Masami Hiramatsu          2018-04-25  1233  			code->offset = offset;
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1234) 			/* Reset the last type if used */
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1235) 			ctx->last_type = NULL;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1236  		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1237  		break;
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1238  	case '\\':	/* Immediate value */
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1239  		if (arg[1] == '"') {	/* Immediate string */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1240) 			ret = __parse_imm_string(arg + 2, &tmp, ctx->offset + 2);
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1241  			if (ret)
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1242  				break;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1243  			code->op = FETCH_OP_DATA;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1244  			code->data = tmp;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1245  		} else {
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1246  			ret = str_to_immediate(arg + 1, &code->immediate);
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1247  			if (ret)
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1248) 				trace_probe_log_err(ctx->offset + 1, BAD_IMM);
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1249  			else
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1250  				code->op = FETCH_OP_IMM;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1251  		}
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1252  		break;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1253) 	default:
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1254) 		if (isalpha(arg[0]) || arg[0] == '_') {	/* BTF variable */
25f00e40ce7953d Masami Hiramatsu (Google  2024-03-04  1255) 			if (!tparg_is_function_entry(ctx->flags) &&
25f00e40ce7953d Masami Hiramatsu (Google  2024-03-04  1256) 			    !tparg_is_function_return(ctx->flags)) {
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1257) 				trace_probe_log_err(ctx->offset, NOSUP_BTFARG);
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1258) 				return -EINVAL;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1259) 			}
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1260) 			ret = parse_btf_arg(arg, pcode, end, ctx);
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1261) 			break;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1262) 		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1263  	}
533059281ee594f Masami Hiramatsu          2018-04-25  1264  	if (!ret && code->op == FETCH_OP_NOP) {
533059281ee594f Masami Hiramatsu          2018-04-25  1265  		/* Parsed, but do not find fetch method */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1266) 		trace_probe_log_err(ctx->offset, BAD_FETCH_ARG);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1267  		ret = -EINVAL;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1268  	}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1269  	return ret;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1270  }
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1271  
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
author maintainer
#4 lore raw

Re: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint

Quoted 24 lines · On Tue, 9 Sep 2025 21:11:26 +0800 kernel test robot <[email protected]> wrote:

Hi Masami,

kernel test robot noticed the following build errors:

[auto build test ERROR on trace/for-next]
[also build test ERROR on tip/x86/core perf-tools-next/perf-tools-next tip/perf/core perf-tools/perf-tools peterz-queue/sched/core linus/master v6.17-rc5 next-20250909] [cannot apply to acme/perf/core]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Masami-Hiramatsu-Google/tracing-wprobe-Add-watchpoint-probe-event-based-on-hardware-breakpoint/20250905-230532
base:   https://git.kernel.org/pub/scm/linux/kernel/git/trace/linux-trace for-next
patch link:    https://lore.kernel.org/r/175708429018.64001.14265428106568623070.stgit%40devnote2
patch subject: [PATCH v2 1/6] tracing: wprobe: Add watchpoint probe event based on hardware breakpoint
config: xtensa-allyesconfig (https://download.01.org/0day-ci/archive/20250909/[email protected]/config)
compiler: xtensa-linux-gcc (GCC) 15.1.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250909/[email protected]/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

Quoted 7 lines

All errors (new ones prefixed by >>):

kernel/trace/trace_probe.c: In function 'parse_probe_arg':

Quoted 1 line
Quoted 1 line

kernel/trace/trace_probe.c:1124:23: error: implicit declaration of function 'regs_query_register_offset'; did you mean 'ftrace_regs_query_register_offset'? [-Wimplicit-function-declaration]

    1124 |                 ret = regs_query_register_offset(arg + 1);
         |                       ^~~~~~~~~~~~~~~~~~~~~~~~~~
         |                       ftrace_regs_query_register_offset

This is a bug, and maybe activated by this patch because

+config WPROBE_EVENTS
+ bool "Enable wprobe-based dynamic events"
+ depends on TRACING
+ depends on HAVE_HW_BREAKPOINT
+ select PROBE_EVENTS
+ select DYNAMIC_EVENTS

if xtensa has no register access API but HAVE_HW_BREAKPOINT, it will select PROBE_EVENT.

I think this part (%regs support) should be enclosed by #ifdef CONFIG_HAVE_REGS_AND_STACK_ACCESS_API. (Note that fprobe event and eprobe event do not support it too.)

Thank you,

Quoted 181 lines

vim +1124 kernel/trace/trace_probe.c

a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1099  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1100  /* Recursive argument parser */
533059281ee594f Masami Hiramatsu          2018-04-25  1101  static int
533059281ee594f Masami Hiramatsu          2018-04-25  1102  parse_probe_arg(char *arg, const struct fetch_type *type,
533059281ee594f Masami Hiramatsu          2018-04-25  1103  		struct fetch_insn **pcode, struct fetch_insn *end,
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1104) 		struct traceprobe_parse_context *ctx)
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1105  {
533059281ee594f Masami Hiramatsu          2018-04-25  1106  	struct fetch_insn *code = *pcode;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1107  	unsigned long param;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1108  	int deref = FETCH_OP_DEREF;
bf173ca92da9786 Steven Rostedt (VMware    2018-10-12  1109) 	long offset = 0;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1110  	char *tmp;
34fee3a104cea1c Namhyung Kim              2013-11-26  1111  	int ret = 0;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1112  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1113  	switch (arg[0]) {
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1114  	case '$':
d157d7694460b9a Masami Hiramatsu (Google  2023-08-23  1115) 		ret = parse_probe_vars(arg, type, pcode, end, ctx);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1116  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1117  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1118  	case '%':	/* named register */
57cb2426dbf36f2 Masami Hiramatsu (Google  2025-09-05  1119) 		if (ctx->flags & (TPARG_FL_TEVENT | TPARG_FL_FPROBE | TPARG_FL_WPROBE)) {
334e5519c375701 Masami Hiramatsu (Google  2023-06-06  1120) 			/* eprobe and fprobe do not handle registers */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1121) 			trace_probe_log_err(ctx->offset, BAD_VAR);
2673c60ee67e71f Steven Rostedt (Google    2022-08-20  1122) 			break;
2673c60ee67e71f Steven Rostedt (Google    2022-08-20  1123) 		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09 @1124  		ret = regs_query_register_offset(arg + 1);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1125  		if (ret >= 0) {
533059281ee594f Masami Hiramatsu          2018-04-25  1126  			code->op = FETCH_OP_REG;
533059281ee594f Masami Hiramatsu          2018-04-25  1127  			code->param = (unsigned int)ret;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1128  			ret = 0;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1129  		} else
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1130) 			trace_probe_log_err(ctx->offset, BAD_REG_NAME);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1131  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1132  
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1133  	case '@':	/* memory, file-offset or symbol */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1134  		if (isdigit(arg[1])) {
bcd83ea6cbfee54 Daniel Walter             2012-09-26  1135  			ret = kstrtoul(arg + 1, 0, &param);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1136  			if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1137) 				trace_probe_log_err(ctx->offset, BAD_MEM_ADDR);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1138  				break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1139  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1140  			/* load address */
533059281ee594f Masami Hiramatsu          2018-04-25  1141  			code->op = FETCH_OP_IMM;
533059281ee594f Masami Hiramatsu          2018-04-25  1142  			code->immediate = param;
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1143  		} else if (arg[1] == '+') {
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1144  			/* kprobes don't support file offsets */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1145) 			if (ctx->flags & TPARG_FL_KERNEL) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1146) 				trace_probe_log_err(ctx->offset, FILE_ON_KPROBE);
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1147  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1148  			}
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1149  			ret = kstrtol(arg + 2, 0, &offset);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1150  			if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1151) 				trace_probe_log_err(ctx->offset, BAD_FILE_OFFS);
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1152  				break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1153  			}
b7e0bf341f6cfa9 Namhyung Kim              2013-11-25  1154  
533059281ee594f Masami Hiramatsu          2018-04-25  1155  			code->op = FETCH_OP_FOFFS;
533059281ee594f Masami Hiramatsu          2018-04-25  1156  			code->immediate = (unsigned long)offset;  // imm64?
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1157  		} else {
b079d374fd84637 Namhyung Kim              2013-07-03  1158  			/* uprobes don't support symbols */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1159) 			if (!(ctx->flags & TPARG_FL_KERNEL)) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1160) 				trace_probe_log_err(ctx->offset, SYM_ON_UPROBE);
b079d374fd84637 Namhyung Kim              2013-07-03  1161  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1162  			}
a6682814f37124e Masami Hiramatsu          2018-08-29  1163  			/* Preserve symbol for updating */
a6682814f37124e Masami Hiramatsu          2018-08-29  1164  			code->op = FETCH_NOP_SYMBOL;
a6682814f37124e Masami Hiramatsu          2018-08-29  1165  			code->data = kstrdup(arg + 1, GFP_KERNEL);
a6682814f37124e Masami Hiramatsu          2018-08-29  1166  			if (!code->data)
a6682814f37124e Masami Hiramatsu          2018-08-29  1167  				return -ENOMEM;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1168  			if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1169) 				trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1170  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1171  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1172  			code->op = FETCH_OP_IMM;
a6682814f37124e Masami Hiramatsu          2018-08-29  1173  			code->immediate = 0;
533059281ee594f Masami Hiramatsu          2018-04-25  1174  		}
533059281ee594f Masami Hiramatsu          2018-04-25  1175  		/* These are fetching from memory */
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1176  		if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1177) 			trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1178  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1179  		}
533059281ee594f Masami Hiramatsu          2018-04-25  1180  		*pcode = code;
533059281ee594f Masami Hiramatsu          2018-04-25  1181  		code->op = FETCH_OP_DEREF;
533059281ee594f Masami Hiramatsu          2018-04-25  1182  		code->offset = offset;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1183  		break;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1184  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1185  	case '+':	/* deref memory */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1186  	case '-':
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1187  		if (arg[1] == 'u') {
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1188  			deref = FETCH_OP_UDEREF;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1189  			arg[1] = arg[0];
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1190  			arg++;
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1191  		}
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1192  		if (arg[0] == '+')
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1193  			arg++;	/* Skip '+', because kstrtol() rejects it. */
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1194  		tmp = strchr(arg, '(');
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1195  		if (!tmp) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1196) 			trace_probe_log_err(ctx->offset, DEREF_NEED_BRACE);
533059281ee594f Masami Hiramatsu          2018-04-25  1197  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1198  		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1199  		*tmp = '\0';
bcd83ea6cbfee54 Daniel Walter             2012-09-26  1200  		ret = kstrtol(arg, 0, &offset);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1201  		if (ret) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1202) 			trace_probe_log_err(ctx->offset, BAD_DEREF_OFFS);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1203  			break;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1204  		}
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1205) 		ctx->offset += (tmp + 1 - arg) + (arg[0] != '-' ? 1 : 0);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1206  		arg = tmp + 1;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1207  		tmp = strrchr(arg, ')');
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1208  		if (!tmp) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1209) 			trace_probe_log_err(ctx->offset + strlen(arg),
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1210  					    DEREF_OPEN_BRACE);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1211  			return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1212  		} else {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1213) 			const struct fetch_type *t2 = find_fetch_type(NULL, ctx->flags);
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1214) 			int cur_offs = ctx->offset;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1215  
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1216  			*tmp = '\0';
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1217) 			ret = parse_probe_arg(arg, t2, &code, end, ctx);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1218  			if (ret)
533059281ee594f Masami Hiramatsu          2018-04-25  1219  				break;
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1220) 			ctx->offset = cur_offs;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1221  			if (code->op == FETCH_OP_COMM ||
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1222  			    code->op == FETCH_OP_DATA) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1223) 				trace_probe_log_err(ctx->offset, COMM_CANT_DEREF);
533059281ee594f Masami Hiramatsu          2018-04-25  1224  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1225  			}
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1226  			if (++code == end) {
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1227) 				trace_probe_log_err(ctx->offset, TOO_MANY_OPS);
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1228  				return -EINVAL;
ab105a4fb89496c Masami Hiramatsu          2019-03-31  1229  			}
533059281ee594f Masami Hiramatsu          2018-04-25  1230  			*pcode = code;
533059281ee594f Masami Hiramatsu          2018-04-25  1231  
e65f7ae7f4da566 Masami Hiramatsu          2019-05-15  1232  			code->op = deref;
533059281ee594f Masami Hiramatsu          2018-04-25  1233  			code->offset = offset;
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1234) 			/* Reset the last type if used */
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1235) 			ctx->last_type = NULL;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1236  		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1237  		break;
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1238  	case '\\':	/* Immediate value */
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1239  		if (arg[1] == '"') {	/* Immediate string */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1240) 			ret = __parse_imm_string(arg + 2, &tmp, ctx->offset + 2);
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1241  			if (ret)
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1242  				break;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1243  			code->op = FETCH_OP_DATA;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1244  			code->data = tmp;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1245  		} else {
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1246  			ret = str_to_immediate(arg + 1, &code->immediate);
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1247  			if (ret)
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1248) 				trace_probe_log_err(ctx->offset + 1, BAD_IMM);
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1249  			else
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1250  				code->op = FETCH_OP_IMM;
a42e3c4de9642d5 Masami Hiramatsu          2019-06-20  1251  		}
6218bf9f4d2942e Masami Hiramatsu          2019-06-20  1252  		break;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1253) 	default:
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1254) 		if (isalpha(arg[0]) || arg[0] == '_') {	/* BTF variable */
25f00e40ce7953d Masami Hiramatsu (Google  2024-03-04  1255) 			if (!tparg_is_function_entry(ctx->flags) &&
25f00e40ce7953d Masami Hiramatsu (Google  2024-03-04  1256) 			    !tparg_is_function_return(ctx->flags)) {
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1257) 				trace_probe_log_err(ctx->offset, NOSUP_BTFARG);
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1258) 				return -EINVAL;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1259) 			}
c440adfbe30257d Masami Hiramatsu (Google  2023-08-23  1260) 			ret = parse_btf_arg(arg, pcode, end, ctx);
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1261) 			break;
b576e09701c7d04 Masami Hiramatsu (Google  2023-06-06  1262) 		}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1263  	}
533059281ee594f Masami Hiramatsu          2018-04-25  1264  	if (!ret && code->op == FETCH_OP_NOP) {
533059281ee594f Masami Hiramatsu          2018-04-25  1265  		/* Parsed, but do not find fetch method */
1b8b0cd754cdbb5 Masami Hiramatsu (Google  2023-06-06  1266) 		trace_probe_log_err(ctx->offset, BAD_FETCH_ARG);
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1267  		ret = -EINVAL;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1268  	}
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1269  	return ret;
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1270  }
8ab83f56475ec91 Srikar Dronamraju         2012-04-09  1271  
Signature · 2 lines
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Signature · 1 line
Masami Hiramatsu (Google) <[email protected]>
author maintainer
#5 lore raw

PATCH v2 2/6 x86/HWBP: introduce arch_reinstall_hw_breakpoint() for atomic context

In reply to Masami Hiramatsu (Google)

From: Jinchao Wang <[email protected]>

Introduce arch_reinstall_hw_breakpoint() to update hardware breakpoint parameters (address, length, type) without freeing and reallocating the debug register slot.

This allows atomic updates in contexts where memory allocation is not permitted, such as kprobe handlers.

---
 arch/x86/include/asm/hw_breakpoint.h |    1 +
 arch/x86/kernel/hw_breakpoint.c      |   50 ++++++++++++++++++++++++++++++++++
 2 files changed, 51 insertions(+)
arch/x86/include/asm/hw_breakpoint.h +1 -0
index 0bc931cd0698..bb7c70ad22fe 100644
@@ -59,6 +59,7 @@ extern int hw_breakpoint_exceptions_notify(struct notifier_block *unused,
 
 
 int arch_install_hw_breakpoint(struct perf_event *bp);
+int arch_reinstall_hw_breakpoint(struct perf_event *bp);
 void arch_uninstall_hw_breakpoint(struct perf_event *bp);
 void hw_breakpoint_pmu_read(struct perf_event *bp);
 void hw_breakpoint_pmu_unthrottle(struct perf_event *bp);
arch/x86/kernel/hw_breakpoint.c +50 -0

56 lines not on this page · raw message

author maintainer
#6 lore raw

PATCH v2 3/6 HWBP: Add modify_wide_hw_breakpoint_local() API

In reply to Masami Hiramatsu (Google)

From: Masami Hiramatsu (Google) <[email protected]>

Add modify_wide_hw_breakpoint_local() arch-wide interface which allows hwbp users to update watch address on-line. This is available if the arch supports CONFIG_HAVE_REINSTALL_HW_BREAKPOINT.
Note that this allows to change the type only for compatible types, because it does not release and reserve the hwbp slot based on type. For instance, you can not change HW_BREAKPOINT_W to HW_BREAKPOINT_X.

---
Changes in v2:
- Check type compatibility by checking slot. (Thanks Jinchao!)

---
 arch/Kconfig                  |   10 ++++++++++
 arch/x86/Kconfig              |    1 +
 include/linux/hw_breakpoint.h |    6 ++++++
 kernel/events/hw_breakpoint.c |   36 ++++++++++++++++++++++++++++++++++++
 4 files changed, 53 insertions(+)
arch/Kconfig +10 -0
index d1b4ffd6e085..e4787fc814df 100644
@@ -418,6 +418,16 @@ config HAVE_MIXED_BREAKPOINTS_REGS
 	  Select this option if your arch implements breakpoints under the
 	  latter fashion.
 
+config HAVE_REINSTALL_HW_BREAKPOINT
+	bool
+	depends on HAVE_HW_BREAKPOINT
+	help
+	  Depending on the arch implementation of hardware breakpoints,
+	  some of them are able to update the breakpoint configuration
+	  without release and reserve the hardware breakpoint register.
+	  What configuration is able to update depends on hardware and
+	  software implementation.
+
 config HAVE_USER_RETURN_NOTIFIER
 	bool
 
arch/x86/Kconfig +1 -0
index 58d890fe2100..49d4ce2af94c 100644
@@ -247,6 +247,7 @@ config X86
 	select HAVE_FUNCTION_TRACER
 	select HAVE_GCC_PLUGINS
 	select HAVE_HW_BREAKPOINT
+	select HAVE_REINSTALL_HW_BREAKPOINT
 	select HAVE_IOREMAP_PROT
 	select HAVE_IRQ_EXIT_ON_IRQ_STACK	if X86_64
 	select HAVE_IRQ_TIME_ACCOUNTING
include/linux/hw_breakpoint.h +6 -0
index db199d653dd1..ea373f2587f8 100644
@@ -81,6 +81,9 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr,
 			    perf_overflow_handler_t triggered,
 			    void *context);
 
+extern int modify_wide_hw_breakpoint_local(struct perf_event *bp,
+					   struct perf_event_attr *attr);
+
 extern int register_perf_hw_breakpoint(struct perf_event *bp);
 extern void unregister_hw_breakpoint(struct perf_event *bp);
 extern void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events);
@@ -124,6 +127,9 @@ register_wide_hw_breakpoint(struct perf_event_attr *attr,
 			    perf_overflow_handler_t triggered,
 			    void *context)		{ return NULL; }
 static inline int
+modify_wide_hw_breakpoint_local(struct perf_event *bp,
+				struct perf_event_attr *attr) { return -ENOSYS; }
+static inline int
 register_perf_hw_breakpoint(struct perf_event *bp)	{ return -ENOSYS; }
 static inline void unregister_hw_breakpoint(struct perf_event *bp)	{ }
 static inline void
kernel/events/hw_breakpoint.c +36 -0
index 8ec2cb688903..ef9bab968b2c 100644
@@ -887,6 +887,42 @@ void unregister_wide_hw_breakpoint(struct perf_event * __percpu *cpu_events)
 }
 EXPORT_SYMBOL_GPL(unregister_wide_hw_breakpoint);
 
+/**
+ * modify_wide_hw_breakpoint_local - update breakpoint config for local cpu
+ * @bp: the hwbp perf event for this cpu
+ * @attr: the new attribute for @bp
+ *
+ * This does not release and reserve the slot of HWBP, just reuse the current
+ * slot on local CPU. So the users must update the other CPUs by themselves.
+ * Also, since this does not release/reserve the slot, this can not change the
+ * type to incompatible type of the HWBP.
+ * Return err if attr is invalid or the cpu fails to update debug register
+ * for new @attr.
+ */
+#ifdef CONFIG_HAVE_REINSTALL_HW_BREAKPOINT
+int modify_wide_hw_breakpoint_local(struct perf_event *bp,
+				    struct perf_event_attr *attr)
+{
+	int ret;
+
+	if (find_slot_idx(bp->attr.bp_type) != find_slot_idx(attr->bp_type))
+		return -EINVAL;
+
+	ret = hw_breakpoint_arch_parse(bp, attr, counter_arch_bp(bp));
+	if (ret)
+		return ret;
+
+	return arch_reinstall_hw_breakpoint(bp);
+}
+#else
+int modify_wide_hw_breakpoint_local(struct perf_event *bp,
+				    struct perf_event_attr *attr)
+{
+	return -EOPNOTSUPP;
+}
+#endif
+EXPORT_SYMBOL_GPL(modify_wide_hw_breakpoint_local);
+
 /**
  * hw_breakpoint_is_used - check if breakpoints are currently used
  *
author maintainer
#7 lore raw

PATCH v2 4/6 tracing: wprobe: Add wprobe event trigger

In reply to Masami Hiramatsu (Google)

From: Masami Hiramatsu (Google) <[email protected]>

Add wprobe event trigger to set and clear the watch event dynamically. This allows us to set an watchpoint on a given local variables and a slab object instead of static objects.

The trigger syntax is below;

set_wprobe:WPROBE:FIELD[+offset] [if FILTER]
clear_wprobe:WPROBE

As you can see, this only sets the address of wprobe, not changing type and length. That should be set when a new wprobe is created. Also, the WPROBE event must be disabled when setting the new trigger and it will be busy afterwards. Recommended usage is to add a new wprobe at NULL address and keep disabled.

---
Changes in v2:
- Getting local cpu perf_event from trace_wprobe directly.
- Remove trace_wprobe_local_perf() because it is conditionally unused.
- Make CONFIG_WPROBE_TRIGGERS a hidden config.

---
 Documentation/trace/wprobetrace.rst |   60 +++++
 include/linux/trace_events.h        |    1 
 kernel/trace/Kconfig                |   10 +
 kernel/trace/trace_wprobe.c         |  419 +++++++++++++++++++++++++++++++++++
 4 files changed, 490 insertions(+)
Documentation/trace/wprobetrace.rst +60 -0
index 9774f57e2947..67dbf2566289 100644
@@ -67,3 +67,63 @@ Here is an example to add a wprobe event on a variable `jiffies`.
            <idle>-0       [000] d.Z1.  717.026373: my_jiffies: (tick_do_update_jiffies64+0xbe/0x130)
 
 You can see the code which writes to `jiffies` is `do_timer()`.
+
+Combination with trigger action
+-------------------------------
+The event trigger action can extend the utilization of this wprobe.
+
+- set_wprobe:WPEVENT:FIELD[+|-ADJUST]
+- clear_wprobe:WPEVENT
+
+Set these triggers to the target event, then the WPROBE event will be
+setup to trace the memory access at FIELD[+|-ADJUST] address.
+
+For example, trace the first 8 byte of the dentry data structure passed
+to do_truncate() until it is deleted by __dentry_kill().
+(Note: all tracefs setup uses '>>' so that it does not kick do_truncate())
+
+  # echo 'w:watch rw@0:8 address=$addr value=+0($addr)' > dynamic_events
+
+  # echo 'f:truncate do_truncate dentry=$arg2' >> dynamic_events
+  # echo 'set_wprobe:watch:dentry' >> events/fprobes/truncate/trigger
+
+  # echo 'f:dentry_kill __dentry_kill dentry=$arg1' >> dynamic_events
+  # echo 'clear_wprobe:watch' >> events/fprobes/dentry_kill/trigger
+
+  # echo 1 >> events/fprobes/truncate/enable
+  # echo 1 >> events/fprobes/dentry_kill/enable
+
+  # echo aaa > /tmp/hoge
+  # echo bbb > /tmp/hoge
+  # echo ccc > /tmp/hoge
+  # rm /tmp/hoge
+
+Then, the trace data will show;
+
+# tracer: nop
+#
+# entries-in-buffer/entries-written: 16/16   #P:8
+#
+#                                _-----=> irqs-off/BH-disabled
+#                               / _----=> need-resched
+#                              | / _---=> hardirq/softirq
+#                              || / _--=> preempt-depth
+#                              ||| / _-=> migrate-disable
+#                              |||| /     delay
+#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
+#    [    7.026136] sh (113) used greatest stack depth: 12912 bytes left
+          | |         |   |||||     |         |
+              sh-113     [002] .....     7.024402: truncate: (do_truncate+0x4/0x120) dentry=0xffff8880069194b8
+              sh-113     [002] ..Zff     7.024822: watch: (lookup_fast+0xaa/0x150) address=0xffff8880069194b8 value=0x200008
+              sh-113     [002] ..Zff     7.024830: watch: (step_into+0x82/0x360) address=0xffff8880069194b8 value=0x200008
+              sh-113     [002] ..Zff     7.024834: watch: (step_into+0x9f/0x360) address=0xffff8880069194b8 value=0x200008
+              sh-113     [002] ..Zff     7.024839: watch: (path_openat+0xb3a/0xe70) address=0xffff8880069194b8 value=0x200008
+              sh-113     [002] ..Zff     7.024843: watch: (path_openat+0xb9a/0xe70) address=0xffff8880069194b8 value=0x200008
+              sh-113     [002] .....     7.024847: truncate: (do_truncate+0x4/0x120) dentry=0xffff8880069194b8
+              sh-113     [002] ...1.     7.025364: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff888006919380
+              sh-113     [002] ...1.     7.025511: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880069195f0
+              rm-118     [003] ...1.     7.027543: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880069194b8
+              sh-113     [002] ...2.     7.027825: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff8880044429c0
+              sh-113     [002] ...2.     7.027833: dentry_kill: (__dentry_kill+0x0/0x220) dentry=0xffff888004442270
+
+You can see the watch event is correctly configured on the dentry.
include/linux/trace_events.h +1 -0
index 7c65f2f73ff4..6517c5d7e03e 100644
@@ -720,6 +720,7 @@ enum event_trigger_type {
 	ETT_EVENT_HIST		= (1 << 4),
 	ETT_HIST_ENABLE		= (1 << 5),
 	ETT_EVENT_EPROBE	= (1 << 6),
+	ETT_EVENT_WPROBE	= (1 << 7),
 };
 
 extern int filter_match_preds(struct event_filter *filter, void *rec);
kernel/trace/Kconfig +10 -0
index dd8919386425..6eb972d9f745 100644
@@ -821,6 +821,16 @@ config WPROBE_EVENTS
 	  Those events can be inserted wherever hardware breakpoints can be
 	  set, and record various register and memory values.
 
+config WPROBE_TRIGGERS
+	depends on WPROBE_EVENTS
+	depends on HAVE_REINSTALL_HW_BREAKPOINT
+	bool
+	default y
+	help
+	  This adds an event trigger which will set the wprobe on a specific
+	  field of an event. This allows user to trace the memory access of
+	  an address pointed by the event field.
+
 config BPF_EVENTS
 	depends on BPF_SYSCALL
 	depends on (KPROBE_EVENTS || UPROBE_EVENTS) && PERF_EVENTS
kernel/trace/trace_wprobe.c +419 -0

439 lines not on this page · raw message

author maintainer
#8 lore raw

Re: [PATCH v2 4/6] tracing: wprobe: Add wprobe event trigger

Quoted 5 lines · On Fri, 5 Sep 2025 23:58:44 +0900 "Masami Hiramatsu (Google)"…
kernel/trace/trace_wprobe.c +5 -0
+static void wprobe_unregister_trigger(char *glob,
+				      struct event_trigger_data *data,
+				      struct trace_event_file *file)
+{
+	lockdep_assert_held(&event_mutex);

kernel/trace/trace_wprobe.c static __init int init_wprobe_trace(void) · line 1052

Quoted 10 lines
kernel/trace/trace_wprobe.c +10 -0
+
+	if (wprobe_trigger_exist_same(data, file)) {
+		list_del_rcu(&data->list);
+		trace_event_trigger_enable_disable(file, 0);
+		update_cond_flag(file);
+	}
+
+	if (data && data->ops->free)
+		data->ops->free(data);
+}

This function is wrongly free the passed trigger_data instead of trigger_data on the event. The passed @data is a dummy data to find the actual data from @file.
Thanks Jinchao to find it!

Thank you,

Signature · 1 line
Masami Hiramatsu (Google) <[email protected]>
author maintainer
#9 lore raw

PATCH v2 5/6 selftests: tracing: Add a basic testcase for wprobe

In reply to Masami Hiramatsu (Google)

From: Masami Hiramatsu (Google) <[email protected]>

Add 'add_remove_wprobe.tc' testcase for testing wprobe event that tests adding and removing operations of the wprobe event.

---
 .../ftrace/test.d/dynevent/add_remove_wprobe.tc    |   68 ++++++++++++++++++++
 1 file changed, 68 insertions(+)
 create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/add_remove_wprobe.tc
tools/testing/selftests/ftrace/test.d/dynevent/add_remove_wprobe.tc new file +68 -0
new file mode 100644
index 000000000000..20774c7f69f8
@@ -0,0 +1,68 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Generic dynamic event - add/remove wprobe events
+# requires: dynamic_events "w[:[<group>/][<event>]] [r|w|rw]@<addr>[:<len>]":README
+
+echo 0 > events/enable
+echo > dynamic_events
+
+# Use jiffies as a variable that is frequently written to.
+TARGET=jiffies
+
+echo "w:my_wprobe w@$TARGET" >> dynamic_events
+
+grep -q my_wprobe dynamic_events
+if [ $? -ne 0 ]; then
+    echo "Failed to create wprobe event"
+    exit_fail
+fi
+
+test -d events/wprobes/my_wprobe
+if [ $? -ne 0 ]; then
+    echo "Failed to create wprobe event directory"
+    exit_fail
+fi
+
+echo 1 > events/wprobes/my_wprobe/enable
+
+# Check if the event is enabled
+cat events/wprobes/my_wprobe/enable | grep -q 1
+if [ $? -ne 0 ]; then
+    echo "Failed to enable wprobe event"
+    exit_fail
+fi
+
+# Let some time pass to trigger the breakpoint
+sleep 1
+
+# Check if we got any trace output
+if !grep -q my_wprobe trace; then
+    echo "wprobe event was not triggered"
+fi
+
+echo 0 > events/wprobes/my_wprobe/enable
+
+# Check if the event is disabled
+cat events/wprobes/my_wprobe/enable | grep -q 0
+if [ $? -ne 0 ]; then
+    echo "Failed to disable wprobe event"
+    exit_fail
+fi
+
+echo "-:my_wprobe" >> dynamic_events
+
+! grep -q my_wprobe dynamic_events
+if [ $? -ne 0 ]; then
+    echo "Failed to remove wprobe event"
+    exit_fail
+fi
+
+! test -d events/wprobes/my_wprobe
+if [ $? -ne 0 ]; then
+    echo "Failed to remove wprobe event directory"
+    exit_fail
+fi
+
+clear_trace
+
+exit 0
author maintainer
#10 lore raw

PATCH v2 6/6 selftests: tracing: Add syntax testcase for wprobe

In reply to Masami Hiramatsu (Google)

From: Masami Hiramatsu (Google) <[email protected]>

Add "wprobe_syntax_errors.tc" testcase for testing syntax errors of the watch probe events.

---
 .../test.d/dynevent/wprobes_syntax_errors.tc       |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
 create mode 100644 tools/testing/selftests/ftrace/test.d/dynevent/wprobes_syntax_errors.tc
tools/testing/selftests/ftrace/test.d/dynevent/wprobes_syntax_errors.tc new file +20 -0
new file mode 100644
index 000000000000..82a273d9efb4
@@ -0,0 +1,20 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Watch probe event parser error log check
+# requires: dynamic_events "w[:[<group>/][<event>]] [r|w|rw]@<addr>[:<len>]":README
+
+check_error() { # command-with-error-pos-by-^
+    ftrace_errlog_check 'event_probe' "$1" 'dynamic_events'
+}
+
+check_error 'w ^symbol'			# BAD_ACCESS_FMT
+check_error 'w ^a@symbol'		# BAD_ACCESS_TYPE
+check_error 'w w@^symbol'		# BAD_ACCESS_ADDR
+check_error 'w w@^jiffies+offset'	# BAD_ACCESS_ADDR
+check_error 'w w@jiffies:^100'		# BAD_ACCESS_LEN
+check_error 'w w@jiffies ^$arg1'	# BAD_VAR
+check_error 'w w@jiffies ^$retval'	# BAD_VAR
+check_error 'w w@jiffies ^$stack'	# BAD_VAR
+check_error 'w w@jiffies ^%ax'		# BAD_VAR
+
+exit 0