linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [for-next][PATCH 00/16] tracing: Updates for the next merge window
@ 2019-05-26 19:18 Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 01/16] ftrace: Make enable and update parameters bool when applicable Steven Rostedt
                   ` (15 more replies)
  0 siblings, 16 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git
for-next

Head SHA1: a124692b698b00026a58d89831ceda2331b2e1d0


Cheng Jian (1):
      ftrace: Enable trampoline when rec count returns back to one

Masami Hiramatsu (10):
      x86/uaccess: Allow access_ok() in irq context if pagefault_disabled
      uaccess: Add non-pagefault user-space read functions
      tracing/probe: Add ustring type for user-space string
      tracing/probe: Support user-space dereference
      selftests/ftrace: Add user-memory access syntax testcase
      perf-probe: Add user memory access attribute support
      uaccess: Add a prototype of non-static __probe_user_read()
      tracing/kprobe: Cast user-space address correctly
      kprobes: Initialize kprobes at postcore_initcall
      tracing/kprobe: Add kprobe_event= boot parameter

Matthias Kaehlcke (1):
      tracing: Use correct function name in trace_filter_add_remove_task() comment

Steven Rostedt (VMware) (4):
      ftrace: Make enable and update parameters bool when applicable
      x86/ftrace: Make enable parameter bool where applicable
      tracing: Make a separate config for trace event self tests
      tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline

----
 Documentation/admin-guide/kernel-parameters.txt    |  13 +++
 Documentation/trace/kprobetrace.rst                |  42 ++++++-
 Documentation/trace/uprobetracer.rst               |  10 +-
 arch/x86/include/asm/uaccess.h                     |   4 +-
 arch/x86/kernel/ftrace.c                           |   6 +-
 include/linux/ftrace.h                             |   4 +-
 include/linux/uaccess.h                            |  20 +++-
 kernel/kprobes.c                                   |   3 +-
 kernel/trace/Kconfig                               |  12 +-
 kernel/trace/ftrace.c                              |  48 ++++----
 kernel/trace/trace.c                               |   9 +-
 kernel/trace/trace_events.c                        |   2 +-
 kernel/trace/trace_kprobe.c                        | 112 ++++++++++++++++++-
 kernel/trace/trace_probe.c                         |  37 +++++--
 kernel/trace/trace_probe.h                         |   3 +
 kernel/trace/trace_probe_tmpl.h                    |  36 +++++-
 kernel/trace/trace_uprobe.c                        |  19 ++++
 mm/maccess.c                                       | 122 ++++++++++++++++++++-
 tools/perf/Documentation/perf-probe.txt            |   3 +-
 tools/perf/util/probe-event.c                      |  11 ++
 tools/perf/util/probe-event.h                      |   2 +
 tools/perf/util/probe-file.c                       |   7 ++
 tools/perf/util/probe-file.h                       |   1 +
 tools/perf/util/probe-finder.c                     |  19 ++--
 .../ftrace/test.d/kprobe/kprobe_args_user.tc       |  32 ++++++
 25 files changed, 500 insertions(+), 77 deletions(-)
 create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [for-next][PATCH 01/16] ftrace: Make enable and update parameters bool when applicable
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 02/16] x86/ftrace: Make enable parameter bool where applicable Steven Rostedt
                   ` (14 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Naveen N. Rao

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

The code modification functions have "enable" and "update" variables that
are sometimes "int" but used as "bool". Remove the ambiguity and make them
"bool" when they are only used for true or false values.

Link: http://lkml.kernel.org/r/e1429923d9eda92a3cf5ee9e33c7eacce539781d.1558115654.git.naveen.n.rao@linux.vnet.ibm.com

Reported-by: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/linux/ftrace.h |  4 ++--
 kernel/trace/ftrace.c  | 20 ++++++++++----------
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/include/linux/ftrace.h b/include/linux/ftrace.h
index 25e2995d4a4c..8a8cb3c401b2 100644
--- a/include/linux/ftrace.h
+++ b/include/linux/ftrace.h
@@ -427,8 +427,8 @@ struct dyn_ftrace *ftrace_rec_iter_record(struct ftrace_rec_iter *iter);
 	     iter = ftrace_rec_iter_next(iter))
 
 
-int ftrace_update_record(struct dyn_ftrace *rec, int enable);
-int ftrace_test_record(struct dyn_ftrace *rec, int enable);
+int ftrace_update_record(struct dyn_ftrace *rec, bool enable);
+int ftrace_test_record(struct dyn_ftrace *rec, bool enable);
 void ftrace_run_stop_machine(int command);
 unsigned long ftrace_location(unsigned long ip);
 unsigned long ftrace_location_range(unsigned long start, unsigned long end);
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index a12aff849c04..4f2c26bebe2a 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1768,7 +1768,7 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
 		count++;
 
 		/* Must match FTRACE_UPDATE_CALLS in ftrace_modify_all_code() */
-		update |= ftrace_test_record(rec, 1) != FTRACE_UPDATE_IGNORE;
+		update |= ftrace_test_record(rec, true) != FTRACE_UPDATE_IGNORE;
 
 		/* Shortcut, if we handled all records, we are done. */
 		if (!all && count == hash->count)
@@ -2047,7 +2047,7 @@ void ftrace_bug(int failed, struct dyn_ftrace *rec)
 	}
 }
 
-static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update)
+static int ftrace_check_record(struct dyn_ftrace *rec, bool enable, bool update)
 {
 	unsigned long flag = 0UL;
 
@@ -2146,28 +2146,28 @@ static int ftrace_check_record(struct dyn_ftrace *rec, int enable, int update)
 /**
  * ftrace_update_record, set a record that now is tracing or not
  * @rec: the record to update
- * @enable: set to 1 if the record is tracing, zero to force disable
+ * @enable: set to true if the record is tracing, false to force disable
  *
  * The records that represent all functions that can be traced need
  * to be updated when tracing has been enabled.
  */
-int ftrace_update_record(struct dyn_ftrace *rec, int enable)
+int ftrace_update_record(struct dyn_ftrace *rec, bool enable)
 {
-	return ftrace_check_record(rec, enable, 1);
+	return ftrace_check_record(rec, enable, true);
 }
 
 /**
  * ftrace_test_record, check if the record has been enabled or not
  * @rec: the record to test
- * @enable: set to 1 to check if enabled, 0 if it is disabled
+ * @enable: set to true to check if enabled, false if it is disabled
  *
  * The arch code may need to test if a record is already set to
  * tracing to determine how to modify the function code that it
  * represents.
  */
-int ftrace_test_record(struct dyn_ftrace *rec, int enable)
+int ftrace_test_record(struct dyn_ftrace *rec, bool enable)
 {
-	return ftrace_check_record(rec, enable, 0);
+	return ftrace_check_record(rec, enable, false);
 }
 
 static struct ftrace_ops *
@@ -2356,7 +2356,7 @@ unsigned long ftrace_get_addr_curr(struct dyn_ftrace *rec)
 }
 
 static int
-__ftrace_replace_code(struct dyn_ftrace *rec, int enable)
+__ftrace_replace_code(struct dyn_ftrace *rec, bool enable)
 {
 	unsigned long ftrace_old_addr;
 	unsigned long ftrace_addr;
@@ -2395,7 +2395,7 @@ void __weak ftrace_replace_code(int mod_flags)
 {
 	struct dyn_ftrace *rec;
 	struct ftrace_page *pg;
-	int enable = mod_flags & FTRACE_MODIFY_ENABLE_FL;
+	bool enable = mod_flags & FTRACE_MODIFY_ENABLE_FL;
 	int schedulable = mod_flags & FTRACE_MODIFY_MAY_SLEEP_FL;
 	int failed;
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 02/16] x86/ftrace: Make enable parameter bool where applicable
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 01/16] ftrace: Make enable and update parameters bool when applicable Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 03/16] x86/uaccess: Allow access_ok() in irq context if pagefault_disabled Steven Rostedt
                   ` (13 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Naveen N. Rao

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

The code modification functions have an "enable" parameter that is an "int"
but used as a boolean. Switch its type to "bool" to remove the ambiguity
that "int" causes.

Link: http://lkml.kernel.org/r/e1429923d9eda92a3cf5ee9e33c7eacce539781d.1558115654.git.naveen.n.rao@linux.vnet.ibm.com

Reported-by: "Naveen N. Rao" <naveen.n.rao@linux.vnet.ibm.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 arch/x86/kernel/ftrace.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/x86/kernel/ftrace.c b/arch/x86/kernel/ftrace.c
index 0927bb158ffc..ba37bcb7f92b 100644
--- a/arch/x86/kernel/ftrace.c
+++ b/arch/x86/kernel/ftrace.c
@@ -370,7 +370,7 @@ static int add_brk_on_nop(struct dyn_ftrace *rec)
 	return add_break(rec->ip, old);
 }
 
-static int add_breakpoints(struct dyn_ftrace *rec, int enable)
+static int add_breakpoints(struct dyn_ftrace *rec, bool enable)
 {
 	unsigned long ftrace_addr;
 	int ret;
@@ -478,7 +478,7 @@ static int add_update_nop(struct dyn_ftrace *rec)
 	return add_update_code(ip, new);
 }
 
-static int add_update(struct dyn_ftrace *rec, int enable)
+static int add_update(struct dyn_ftrace *rec, bool enable)
 {
 	unsigned long ftrace_addr;
 	int ret;
@@ -524,7 +524,7 @@ static int finish_update_nop(struct dyn_ftrace *rec)
 	return ftrace_write(ip, new, 1);
 }
 
-static int finish_update(struct dyn_ftrace *rec, int enable)
+static int finish_update(struct dyn_ftrace *rec, bool enable)
 {
 	unsigned long ftrace_addr;
 	int ret;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 03/16] x86/uaccess: Allow access_ok() in irq context if pagefault_disabled
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 01/16] ftrace: Make enable and update parameters bool when applicable Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 02/16] x86/ftrace: Make enable parameter bool where applicable Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 04/16] uaccess: Add non-pagefault user-space read functions Steven Rostedt
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

WARN_ON_IN_IRQ() assumes that the access_ok() and following
user memory access can sleep. But this assumption is not
always correct; when the pagefault is disabled, following
memory access will just returns -EFAULT and never sleep.

Add pagefault_disabled() check in WARN_ON_ONCE() so that
it can ignore the case we call it with disabling pagefault.
For this purpose, this modified pagefault_disabled() as
an inline function.

Link: http://lkml.kernel.org/r/155789868664.26965.7932665824135793317.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 arch/x86/include/asm/uaccess.h | 4 +++-
 include/linux/uaccess.h        | 5 ++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h
index c82abd6e4ca3..9c4435307ff8 100644
--- a/arch/x86/include/asm/uaccess.h
+++ b/arch/x86/include/asm/uaccess.h
@@ -66,7 +66,9 @@ static inline bool __chk_range_not_ok(unsigned long addr, unsigned long size, un
 })
 
 #ifdef CONFIG_DEBUG_ATOMIC_SLEEP
-# define WARN_ON_IN_IRQ()	WARN_ON_ONCE(!in_task())
+static inline bool pagefault_disabled(void);
+# define WARN_ON_IN_IRQ()	\
+	WARN_ON_ONCE(!in_task() && !pagefault_disabled())
 #else
 # define WARN_ON_IN_IRQ()
 #endif
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 2b70130af585..5a43ef7db492 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -203,7 +203,10 @@ static inline void pagefault_enable(void)
 /*
  * Is the pagefault handler disabled? If so, user access methods will not sleep.
  */
-#define pagefault_disabled() (current->pagefault_disabled != 0)
+static inline bool pagefault_disabled(void)
+{
+	return current->pagefault_disabled != 0;
+}
 
 /*
  * The pagefault handler is in general disabled by pagefault_disable() or
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 04/16] uaccess: Add non-pagefault user-space read functions
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (2 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 03/16] x86/uaccess: Allow access_ok() in irq context if pagefault_disabled Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 05/16] tracing/probe: Add ustring type for user-space string Steven Rostedt
                   ` (11 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Add probe_user_read(), strncpy_from_unsafe_user() and
strnlen_unsafe_user() which allows caller to access user-space
in IRQ context.

Current probe_kernel_read() and strncpy_from_unsafe() are
not available for user-space memory, because it sets
KERNEL_DS while accessing data. On some arch, user address
space and kernel address space can be co-exist, but others
can not. In that case, setting KERNEL_DS means given
address is treated as a kernel address space.
Also strnlen_user() is only available from user context since
it can sleep if pagefault is enabled.

To access user-space memory without pagefault, we need
these new functions which sets USER_DS while accessing
the data.

Link: http://lkml.kernel.org/r/155789869802.26965.4940338412595759063.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/linux/uaccess.h |  14 +++++
 mm/maccess.c            | 122 ++++++++++++++++++++++++++++++++++++++--
 2 files changed, 130 insertions(+), 6 deletions(-)

diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 5a43ef7db492..9c435c3f2105 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -242,6 +242,17 @@ static inline unsigned long __copy_from_user_inatomic_nocache(void *to,
 extern long probe_kernel_read(void *dst, const void *src, size_t size);
 extern long __probe_kernel_read(void *dst, const void *src, size_t size);
 
+/*
+ * probe_user_read(): safely attempt to read from a location in user space
+ * @dst: pointer to the buffer that shall take the data
+ * @src: address to read from
+ * @size: size of the data chunk
+ *
+ * Safely read from address @src to the buffer at @dst.  If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+extern long probe_user_read(void *dst, const void __user *src, size_t size);
+
 /*
  * probe_kernel_write(): safely attempt to write to a location
  * @dst: address to write to
@@ -255,6 +266,9 @@ extern long notrace probe_kernel_write(void *dst, const void *src, size_t size);
 extern long notrace __probe_kernel_write(void *dst, const void *src, size_t size);
 
 extern long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count);
+extern long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr,
+				     long count);
+extern long strnlen_unsafe_user(const void __user *unsafe_addr, long count);
 
 /**
  * probe_kernel_address(): safely attempt to read from a location
diff --git a/mm/maccess.c b/mm/maccess.c
index ec00be51a24f..19c8c3dc14df 100644
--- a/mm/maccess.c
+++ b/mm/maccess.c
@@ -5,8 +5,20 @@
 #include <linux/mm.h>
 #include <linux/uaccess.h>
 
+static __always_inline long
+probe_read_common(void *dst, const void __user *src, size_t size)
+{
+	long ret;
+
+	pagefault_disable();
+	ret = __copy_from_user_inatomic(dst, src, size);
+	pagefault_enable();
+
+	return ret ? -EFAULT : 0;
+}
+
 /**
- * probe_kernel_read(): safely attempt to read from a location
+ * probe_kernel_read(): safely attempt to read from a kernel-space location
  * @dst: pointer to the buffer that shall take the data
  * @src: address to read from
  * @size: size of the data chunk
@@ -29,16 +41,40 @@ long __probe_kernel_read(void *dst, const void *src, size_t size)
 	mm_segment_t old_fs = get_fs();
 
 	set_fs(KERNEL_DS);
-	pagefault_disable();
-	ret = __copy_from_user_inatomic(dst,
-			(__force const void __user *)src, size);
-	pagefault_enable();
+	ret = probe_read_common(dst, (__force const void __user *)src, size);
 	set_fs(old_fs);
 
-	return ret ? -EFAULT : 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(probe_kernel_read);
 
+/**
+ * probe_user_read(): safely attempt to read from a user-space location
+ * @dst: pointer to the buffer that shall take the data
+ * @src: address to read from. This must be a user address.
+ * @size: size of the data chunk
+ *
+ * Safely read from user address @src to the buffer at @dst. If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+
+long __weak probe_user_read(void *dst, const void __user *src, size_t size)
+    __attribute__((alias("__probe_user_read")));
+
+long __probe_user_read(void *dst, const void __user *src, size_t size)
+{
+	long ret = -EFAULT;
+	mm_segment_t old_fs = get_fs();
+
+	set_fs(USER_DS);
+	if (access_ok(src, size))
+		ret = probe_read_common(dst, src, size);
+	set_fs(old_fs);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(probe_user_read);
+
 /**
  * probe_kernel_write(): safely attempt to write to a location
  * @dst: address to write to
@@ -66,6 +102,7 @@ long __probe_kernel_write(void *dst, const void *src, size_t size)
 }
 EXPORT_SYMBOL_GPL(probe_kernel_write);
 
+
 /**
  * strncpy_from_unsafe: - Copy a NUL terminated string from unsafe address.
  * @dst:   Destination address, in kernel space.  This buffer must be at
@@ -105,3 +142,76 @@ long strncpy_from_unsafe(char *dst, const void *unsafe_addr, long count)
 
 	return ret ? -EFAULT : src - unsafe_addr;
 }
+
+/**
+ * strncpy_from_unsafe_user: - Copy a NUL terminated string from unsafe user
+ *				address.
+ * @dst:   Destination address, in kernel space.  This buffer must be at
+ *         least @count bytes long.
+ * @unsafe_addr: Unsafe user address.
+ * @count: Maximum number of bytes to copy, including the trailing NUL.
+ *
+ * Copies a NUL-terminated string from unsafe user address to kernel buffer.
+ *
+ * On success, returns the length of the string INCLUDING the trailing NUL.
+ *
+ * If access fails, returns -EFAULT (some data may have been copied
+ * and the trailing NUL added).
+ *
+ * If @count is smaller than the length of the string, copies @count-1 bytes,
+ * sets the last byte of @dst buffer to NUL and returns @count.
+ */
+long strncpy_from_unsafe_user(char *dst, const void __user *unsafe_addr,
+			      long count)
+{
+	mm_segment_t old_fs = get_fs();
+	long ret;
+
+	if (unlikely(count <= 0))
+		return 0;
+
+	set_fs(USER_DS);
+	pagefault_disable();
+	ret = strncpy_from_user(dst, unsafe_addr, count);
+	pagefault_enable();
+	set_fs(old_fs);
+
+	if (ret >= count) {
+		ret = count;
+		dst[ret - 1] = '\0';
+	} else if (ret > 0) {
+		ret++;
+	}
+
+	return ret;
+}
+
+/**
+ * strnlen_unsafe_user: - Get the size of a user string INCLUDING final NUL.
+ * @unsafe_addr: The string to measure.
+ * @count: Maximum count (including NUL)
+ *
+ * Get the size of a NUL-terminated string in user space without pagefault.
+ *
+ * Returns the size of the string INCLUDING the terminating NUL.
+ *
+ * If the string is too long, returns a number larger than @count. User
+ * has to check the return value against "> count".
+ * On exception (or invalid count), returns 0.
+ *
+ * Unlike strnlen_user, this can be used from IRQ handler etc. because
+ * it disables pagefaults.
+ */
+long strnlen_unsafe_user(const void __user *unsafe_addr, long count)
+{
+	mm_segment_t old_fs = get_fs();
+	int ret;
+
+	set_fs(USER_DS);
+	pagefault_disable();
+	ret = strnlen_user(unsafe_addr, count);
+	pagefault_enable();
+	set_fs(old_fs);
+
+	return ret;
+}
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 05/16] tracing/probe: Add ustring type for user-space string
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (3 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 04/16] uaccess: Add non-pagefault user-space read functions Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 06/16] tracing/probe: Support user-space dereference Steven Rostedt
                   ` (10 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Add "ustring" type for fetching user-space string from kprobe event.
User can specify ustring type at uprobe event, and it is same as
"string" for uprobe.

Note that probe-event provides this option but it doesn't choose the
correct type automatically since we have not way to decide the address
is in user-space or not on some arch (and on some other arch, you can
fetch the string by "string" type). So user must carefully check the
target code (e.g. if you see __user on the target variable) and
use this new type.

Link: http://lkml.kernel.org/r/155789871009.26965.14167558859557329331.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/trace/kprobetrace.rst |  9 +++++--
 kernel/trace/trace.c                |  2 +-
 kernel/trace/trace_kprobe.c         | 42 ++++++++++++++++++++++++++---
 kernel/trace/trace_probe.c          | 14 +++++++---
 kernel/trace/trace_probe.h          |  1 +
 kernel/trace/trace_probe_tmpl.h     | 14 +++++++++-
 kernel/trace/trace_uprobe.c         | 12 +++++++++
 7 files changed, 84 insertions(+), 10 deletions(-)

diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst
index 235ce2ab131a..a3ac7c9ac242 100644
--- a/Documentation/trace/kprobetrace.rst
+++ b/Documentation/trace/kprobetrace.rst
@@ -55,7 +55,8 @@ Synopsis of kprobe_events
   NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
 		  (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
-		  (x8/x16/x32/x64), "string" and bitfield are supported.
+		  (x8/x16/x32/x64), "string", "ustring" and bitfield
+		  are supported.
 
   (\*1) only for the probe on function entry (offs == 0).
   (\*2) only for return probe.
@@ -77,7 +78,11 @@ apply it to registers/stack-entries etc. (for example, '$stack1:x8[8]' is
 wrong, but '+8($stack):x8[8]' is OK.)
 String type is a special type, which fetches a "null-terminated" string from
 kernel space. This means it will fail and store NULL if the string container
-has been paged out.
+has been paged out. "ustring" type is an alternative of string for user-space.
+Note that kprobe-event provides string/ustring types, but doesn't change it
+automatically. So user has to decide if the targe string in kernel or in user
+space carefully. On some arch, if you choose wrong one, it always fails to
+record string data.
 The string array type is a bit different from other types. For other base
 types, <base-type>[1] is equal to <base-type> (e.g. +0(%di):x32[1] is same
 as +0(%di):x32.) But string[1] is not equal to string. The string type itself
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 1c80521fd436..d3a477a16e70 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4847,7 +4847,7 @@ static const char readme_msg[] =
 	"\t           $stack<index>, $stack, $retval, $comm\n"
 #endif
 	"\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n"
-	"\t           b<bit-width>@<bit-offset>/<container-size>,\n"
+	"\t           b<bit-width>@<bit-offset>/<container-size>, ustring,\n"
 	"\t           <type>\\[<array-size>\\]\n"
 #ifdef CONFIG_HIST_TRIGGERS
 	"\t    field: <stype> <name>;\n"
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 7d736248a070..439bf04d14ce 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -886,6 +886,15 @@ fetch_store_strlen(unsigned long addr)
 	return (ret < 0) ? ret : len;
 }
 
+/* Return the length of string -- including null terminal byte */
+static nokprobe_inline int
+fetch_store_strlen_user(unsigned long addr)
+{
+	const void __user *uaddr =  (__force const void __user *)addr;
+
+	return strnlen_unsafe_user(uaddr, MAX_STRING_SIZE);
+}
+
 /*
  * Fetch a null-terminated string. Caller MUST set *(u32 *)buf with max
  * length and relative data location.
@@ -894,19 +903,46 @@ static nokprobe_inline int
 fetch_store_string(unsigned long addr, void *dest, void *base)
 {
 	int maxlen = get_loc_len(*(u32 *)dest);
-	u8 *dst = get_loc_data(dest, base);
+	void *__dest;
 	long ret;
 
 	if (unlikely(!maxlen))
 		return -ENOMEM;
+
+	__dest = get_loc_data(dest, base);
+
 	/*
 	 * Try to get string again, since the string can be changed while
 	 * probing.
 	 */
-	ret = strncpy_from_unsafe(dst, (void *)addr, maxlen);
+	ret = strncpy_from_unsafe(__dest, (void *)addr, maxlen);
+	if (ret >= 0)
+		*(u32 *)dest = make_data_loc(ret, __dest - base);
+
+	return ret;
+}
 
+/*
+ * Fetch a null-terminated string from user. Caller MUST set *(u32 *)buf
+ * with max length and relative data location.
+ */
+static nokprobe_inline int
+fetch_store_string_user(unsigned long addr, void *dest, void *base)
+{
+	const void __user *uaddr =  (__force const void __user *)addr;
+	int maxlen = get_loc_len(*(u32 *)dest);
+	void *__dest;
+	long ret;
+
+	if (unlikely(!maxlen))
+		return -ENOMEM;
+
+	__dest = get_loc_data(dest, base);
+
+	ret = strncpy_from_unsafe_user(__dest, uaddr, maxlen);
 	if (ret >= 0)
-		*(u32 *)dest = make_data_loc(ret, (void *)dst - base);
+		*(u32 *)dest = make_data_loc(ret, __dest - base);
+
 	return ret;
 }
 
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index a347faced959..5a0470f7b9de 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -78,6 +78,8 @@ static const struct fetch_type probe_fetch_types[] = {
 	/* Special types */
 	__ASSIGN_FETCH_TYPE("string", string, string, sizeof(u32), 1,
 			    "__data_loc char[]"),
+	__ASSIGN_FETCH_TYPE("ustring", string, string, sizeof(u32), 1,
+			    "__data_loc char[]"),
 	/* Basic types */
 	ASSIGN_FETCH_TYPE(u8,  u8,  0),
 	ASSIGN_FETCH_TYPE(u16, u16, 0),
@@ -569,7 +571,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 		goto fail;
 
 	/* Store operation */
-	if (!strcmp(parg->type->name, "string")) {
+	if (!strcmp(parg->type->name, "string") ||
+	    !strcmp(parg->type->name, "ustring")) {
 		if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
 		    code->op != FETCH_OP_COMM) {
 			trace_probe_log_err(offset + (t ? (t - arg) : 0),
@@ -590,7 +593,11 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 				goto fail;
 			}
 		}
-		code->op = FETCH_OP_ST_STRING;	/* In DEREF case, replace it */
+		/* If op == DEREF, replace it with STRING */
+		if (!strcmp(parg->type->name, "ustring"))
+			code->op = FETCH_OP_ST_USTRING;
+		else
+			code->op = FETCH_OP_ST_STRING;
 		code->size = parg->type->size;
 		parg->dynamic = true;
 	} else if (code->op == FETCH_OP_DEREF) {
@@ -618,7 +625,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 	/* Loop(Array) operation */
 	if (parg->count) {
 		if (scode->op != FETCH_OP_ST_MEM &&
-		    scode->op != FETCH_OP_ST_STRING) {
+		    scode->op != FETCH_OP_ST_STRING &&
+		    scode->op != FETCH_OP_ST_USTRING) {
 			trace_probe_log_err(offset + (t ? (t - arg) : 0),
 					    BAD_STRING);
 			ret = -EINVAL;
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index f9a8c632188b..c7546e7ff8e2 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -96,6 +96,7 @@ enum fetch_op {
 	FETCH_OP_ST_RAW,	/* Raw: .size */
 	FETCH_OP_ST_MEM,	/* Mem: .offset, .size */
 	FETCH_OP_ST_STRING,	/* String: .offset, .size */
+	FETCH_OP_ST_USTRING,	/* User String: .offset, .size */
 	// Stage 4 (modify) op
 	FETCH_OP_MOD_BF,	/* Bitfield: .basesize, .lshift, .rshift */
 	// Stage 5 (loop) op
diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h
index c30c61f12ddd..2e9e4dae8839 100644
--- a/kernel/trace/trace_probe_tmpl.h
+++ b/kernel/trace/trace_probe_tmpl.h
@@ -59,6 +59,9 @@ process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs,
 static nokprobe_inline int fetch_store_strlen(unsigned long addr);
 static nokprobe_inline int
 fetch_store_string(unsigned long addr, void *dest, void *base);
+static nokprobe_inline int fetch_store_strlen_user(unsigned long addr);
+static nokprobe_inline int
+fetch_store_string_user(unsigned long addr, void *dest, void *base);
 static nokprobe_inline int
 probe_mem_read(void *dest, void *src, size_t size);
 
@@ -91,6 +94,10 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
 			ret = fetch_store_strlen(val + code->offset);
 			code++;
 			goto array;
+		} else if (code->op == FETCH_OP_ST_USTRING) {
+			ret += fetch_store_strlen_user(val + code->offset);
+			code++;
+			goto array;
 		} else
 			return -EILSEQ;
 	}
@@ -106,6 +113,10 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
 		loc = *(u32 *)dest;
 		ret = fetch_store_string(val + code->offset, dest, base);
 		break;
+	case FETCH_OP_ST_USTRING:
+		loc = *(u32 *)dest;
+		ret = fetch_store_string_user(val + code->offset, dest, base);
+		break;
 	default:
 		return -EILSEQ;
 	}
@@ -123,7 +134,8 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
 		total += ret;
 		if (++i < code->param) {
 			code = s3;
-			if (s3->op != FETCH_OP_ST_STRING) {
+			if (s3->op != FETCH_OP_ST_STRING &&
+			    s3->op != FETCH_OP_ST_USTRING) {
 				dest += s3->size;
 				val += s3->size;
 				goto stage3;
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index eb7e06b54741..852e998051f6 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -176,6 +176,12 @@ fetch_store_string(unsigned long addr, void *dest, void *base)
 	return ret;
 }
 
+static nokprobe_inline int
+fetch_store_string_user(unsigned long addr, void *dest, void *base)
+{
+	return fetch_store_string(addr, dest, base);
+}
+
 /* Return the length of string -- including null terminal byte */
 static nokprobe_inline int
 fetch_store_strlen(unsigned long addr)
@@ -191,6 +197,12 @@ fetch_store_strlen(unsigned long addr)
 	return (len > MAX_STRING_SIZE) ? 0 : len;
 }
 
+static nokprobe_inline int
+fetch_store_strlen_user(unsigned long addr)
+{
+	return fetch_store_strlen(addr);
+}
+
 static unsigned long translate_user_vaddr(unsigned long file_offset)
 {
 	unsigned long base_addr;
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 06/16] tracing/probe: Support user-space dereference
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (4 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 05/16] tracing/probe: Add ustring type for user-space string Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 07/16] selftests/ftrace: Add user-memory access syntax testcase Steven Rostedt
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Support user-space dereference syntax for probe event arguments
to dereference the data-structure or array in user-space.

The syntax is just adding 'u' before an offset value.

 +|-u<OFFSET>(<FETCHARG>)

e.g. +u8(%ax), +u0(+0(%si))

For example, if you probe do_sched_setscheduler(pid, policy,
param) and record param->sched_priority, you can add new
probe as below;

 p do_sched_setscheduler priority=+u0($arg3)

Note that kprobe event provides this and it doesn't change the
dereference method automatically because we do not know whether
the given address is in userspace or kernel on some archs.

So as same as "ustring", this is an option for user, who has to
carefully choose the dereference method.

Link: http://lkml.kernel.org/r/155789872187.26965.4468456816590888687.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 Documentation/trace/kprobetrace.rst  | 27 ++++++++++++++++++++++-----
 Documentation/trace/uprobetracer.rst | 10 ++++++----
 kernel/trace/trace.c                 |  5 +++--
 kernel/trace/trace_kprobe.c          |  6 ++++++
 kernel/trace/trace_probe.c           | 25 ++++++++++++++++++-------
 kernel/trace/trace_probe.h           |  2 ++
 kernel/trace/trace_probe_tmpl.h      | 22 +++++++++++++++++-----
 kernel/trace/trace_uprobe.c          |  7 +++++++
 8 files changed, 81 insertions(+), 23 deletions(-)

diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst
index a3ac7c9ac242..09ff474493e1 100644
--- a/Documentation/trace/kprobetrace.rst
+++ b/Documentation/trace/kprobetrace.rst
@@ -51,7 +51,7 @@ Synopsis of kprobe_events
   $argN		: Fetch the Nth function argument. (N >= 1) (\*1)
   $retval	: Fetch return value.(\*2)
   $comm		: Fetch current task comm.
-  +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(\*3)
+  +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*3)(\*4)
   NAME=FETCHARG : Set NAME as the argument name of FETCHARG.
   FETCHARG:TYPE : Set TYPE as the type of FETCHARG. Currently, basic types
 		  (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
@@ -61,6 +61,7 @@ Synopsis of kprobe_events
   (\*1) only for the probe on function entry (offs == 0).
   (\*2) only for return probe.
   (\*3) this is useful for fetching a field of data structures.
+  (\*4) "u" means user-space dereference. See :ref:`user_mem_access`.
 
 Types
 -----
@@ -79,10 +80,7 @@ wrong, but '+8($stack):x8[8]' is OK.)
 String type is a special type, which fetches a "null-terminated" string from
 kernel space. This means it will fail and store NULL if the string container
 has been paged out. "ustring" type is an alternative of string for user-space.
-Note that kprobe-event provides string/ustring types, but doesn't change it
-automatically. So user has to decide if the targe string in kernel or in user
-space carefully. On some arch, if you choose wrong one, it always fails to
-record string data.
+See :ref:`user_mem_access` for more info..
 The string array type is a bit different from other types. For other base
 types, <base-type>[1] is equal to <base-type> (e.g. +0(%di):x32[1] is same
 as +0(%di):x32.) But string[1] is not equal to string. The string type itself
@@ -97,6 +95,25 @@ Symbol type('symbol') is an alias of u32 or u64 type (depends on BITS_PER_LONG)
 which shows given pointer in "symbol+offset" style.
 For $comm, the default type is "string"; any other type is invalid.
 
+.. _user_mem_access:
+User Memory Access
+------------------
+Kprobe events supports user-space memory access. For that purpose, you can use
+either user-space dereference syntax or 'ustring' type.
+
+The user-space dereference syntax allows you to access a field of a data
+structure in user-space. This is done by adding the "u" prefix to the
+dereference syntax. For example, +u4(%si) means it will read memory from the
+address in the register %si offset by 4, and the memory is expected to be in
+user-space. You can use this for strings too, e.g. +u0(%si):string will read
+a string from the address in the register %si that is expected to be in user-
+space. 'ustring' is a shortcut way of performing the same task. That is,
++0(%si):ustring is equivalent to +u0(%si):string.
+
+Note that kprobe-event provides the user-memory access syntax but it doesn't
+use it transparently. This means if you use normal dereference or string type
+for user memory, it might fail, and may always fail on some archs. The user
+has to carefully check if the target data is in kernel or user space.
 
 Per-Probe Event Filtering
 -------------------------
diff --git a/Documentation/trace/uprobetracer.rst b/Documentation/trace/uprobetracer.rst
index 4346e23e3ae7..ab13319c66ac 100644
--- a/Documentation/trace/uprobetracer.rst
+++ b/Documentation/trace/uprobetracer.rst
@@ -42,16 +42,18 @@ Synopsis of uprobe_tracer
    @+OFFSET	: Fetch memory at OFFSET (OFFSET from same file as PATH)
    $stackN	: Fetch Nth entry of stack (N >= 0)
    $stack	: Fetch stack address.
-   $retval	: Fetch return value.(*)
+   $retval	: Fetch return value.(\*1)
    $comm	: Fetch current task comm.
-   +|-offs(FETCHARG) : Fetch memory at FETCHARG +|- offs address.(**)
+   +|-[u]OFFS(FETCHARG) : Fetch memory at FETCHARG +|- OFFS address.(\*2)(\*3)
    NAME=FETCHARG     : Set NAME as the argument name of FETCHARG.
    FETCHARG:TYPE     : Set TYPE as the type of FETCHARG. Currently, basic types
 		       (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal types
 		       (x8/x16/x32/x64), "string" and bitfield are supported.
 
-  (*) only for return probe.
-  (**) this is useful for fetching a field of data structures.
+  (\*1) only for return probe.
+  (\*2) this is useful for fetching a field of data structures.
+  (\*3) Unlike kprobe event, "u" prefix will just be ignored, becuse uprobe
+        events can access only user-space memory.
 
 Types
 -----
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index d3a477a16e70..6b3b5b0495a8 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -4842,10 +4842,11 @@ static const char readme_msg[] =
 	"\t     args: <name>=fetcharg[:type]\n"
 	"\t fetcharg: %<register>, @<address>, @<symbol>[+|-<offset>],\n"
 #ifdef CONFIG_HAVE_FUNCTION_ARG_ACCESS_API
-	"\t           $stack<index>, $stack, $retval, $comm, $arg<N>\n"
+	"\t           $stack<index>, $stack, $retval, $comm, $arg<N>,\n"
 #else
-	"\t           $stack<index>, $stack, $retval, $comm\n"
+	"\t           $stack<index>, $stack, $retval, $comm,\n"
 #endif
+	"\t           +|-[u]<offset>(<fetcharg>)\n"
 	"\t     type: s8/16/32/64, u8/16/32/64, x8/16/32/64, string, symbol,\n"
 	"\t           b<bit-width>@<bit-offset>/<container-size>, ustring,\n"
 	"\t           <type>\\[<array-size>\\]\n"
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 439bf04d14ce..ff14eb011c1c 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -952,6 +952,12 @@ probe_mem_read(void *dest, void *src, size_t size)
 	return probe_kernel_read(dest, src, size);
 }
 
+static nokprobe_inline int
+probe_mem_read_user(void *dest, void *src, size_t size)
+{
+	return probe_user_read(dest, src, size);
+}
+
 /* Note that we don't verify it, since the code does not come from user space */
 static int
 process_fetch_insn(struct fetch_insn *code, struct pt_regs *regs, void *dest,
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index 5a0470f7b9de..b6b0593844cd 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -324,6 +324,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
 {
 	struct fetch_insn *code = *pcode;
 	unsigned long param;
+	int deref = FETCH_OP_DEREF;
 	long offset = 0;
 	char *tmp;
 	int ret = 0;
@@ -396,9 +397,14 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
 		break;
 
 	case '+':	/* deref memory */
-		arg++;	/* Skip '+', because kstrtol() rejects it. */
-		/* fall through */
 	case '-':
+		if (arg[1] == 'u') {
+			deref = FETCH_OP_UDEREF;
+			arg[1] = arg[0];
+			arg++;
+		}
+		if (arg[0] == '+')
+			arg++;	/* Skip '+', because kstrtol() rejects it. */
 		tmp = strchr(arg, '(');
 		if (!tmp) {
 			trace_probe_log_err(offs, DEREF_NEED_BRACE);
@@ -434,7 +440,7 @@ parse_probe_arg(char *arg, const struct fetch_type *type,
 			}
 			*pcode = code;
 
-			code->op = FETCH_OP_DEREF;
+			code->op = deref;
 			code->offset = offset;
 		}
 		break;
@@ -573,14 +579,15 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 	/* Store operation */
 	if (!strcmp(parg->type->name, "string") ||
 	    !strcmp(parg->type->name, "ustring")) {
-		if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_IMM &&
-		    code->op != FETCH_OP_COMM) {
+		if (code->op != FETCH_OP_DEREF && code->op != FETCH_OP_UDEREF &&
+		    code->op != FETCH_OP_IMM && code->op != FETCH_OP_COMM) {
 			trace_probe_log_err(offset + (t ? (t - arg) : 0),
 					    BAD_STRING);
 			ret = -EINVAL;
 			goto fail;
 		}
-		if (code->op != FETCH_OP_DEREF || parg->count) {
+		if ((code->op == FETCH_OP_IMM || code->op == FETCH_OP_COMM) ||
+		     parg->count) {
 			/*
 			 * IMM and COMM is pointing actual address, those must
 			 * be kept, and if parg->count != 0, this is an array
@@ -594,7 +601,8 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 			}
 		}
 		/* If op == DEREF, replace it with STRING */
-		if (!strcmp(parg->type->name, "ustring"))
+		if (!strcmp(parg->type->name, "ustring") ||
+		    code->op == FETCH_OP_UDEREF)
 			code->op = FETCH_OP_ST_USTRING;
 		else
 			code->op = FETCH_OP_ST_STRING;
@@ -603,6 +611,9 @@ static int traceprobe_parse_probe_arg_body(char *arg, ssize_t *size,
 	} else if (code->op == FETCH_OP_DEREF) {
 		code->op = FETCH_OP_ST_MEM;
 		code->size = parg->type->size;
+	} else if (code->op == FETCH_OP_UDEREF) {
+		code->op = FETCH_OP_ST_UMEM;
+		code->size = parg->type->size;
 	} else {
 		code++;
 		if (code->op != FETCH_OP_NOP) {
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index c7546e7ff8e2..42816358dd48 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -92,9 +92,11 @@ enum fetch_op {
 	FETCH_OP_FOFFS,		/* File offset: .immediate */
 	// Stage 2 (dereference) op
 	FETCH_OP_DEREF,		/* Dereference: .offset */
+	FETCH_OP_UDEREF,	/* User-space Dereference: .offset */
 	// Stage 3 (store) ops
 	FETCH_OP_ST_RAW,	/* Raw: .size */
 	FETCH_OP_ST_MEM,	/* Mem: .offset, .size */
+	FETCH_OP_ST_UMEM,	/* Mem: .offset, .size */
 	FETCH_OP_ST_STRING,	/* String: .offset, .size */
 	FETCH_OP_ST_USTRING,	/* User String: .offset, .size */
 	// Stage 4 (modify) op
diff --git a/kernel/trace/trace_probe_tmpl.h b/kernel/trace/trace_probe_tmpl.h
index 2e9e4dae8839..e5282828f4a6 100644
--- a/kernel/trace/trace_probe_tmpl.h
+++ b/kernel/trace/trace_probe_tmpl.h
@@ -64,6 +64,8 @@ static nokprobe_inline int
 fetch_store_string_user(unsigned long addr, void *dest, void *base);
 static nokprobe_inline int
 probe_mem_read(void *dest, void *src, size_t size);
+static nokprobe_inline int
+probe_mem_read_user(void *dest, void *src, size_t size);
 
 /* From the 2nd stage, routine is same */
 static nokprobe_inline int
@@ -77,14 +79,21 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
 
 stage2:
 	/* 2nd stage: dereference memory if needed */
-	while (code->op == FETCH_OP_DEREF) {
-		lval = val;
-		ret = probe_mem_read(&val, (void *)val + code->offset,
-					sizeof(val));
+	do {
+		if (code->op == FETCH_OP_DEREF) {
+			lval = val;
+			ret = probe_mem_read(&val, (void *)val + code->offset,
+					     sizeof(val));
+		} else if (code->op == FETCH_OP_UDEREF) {
+			lval = val;
+			ret = probe_mem_read_user(&val,
+				 (void *)val + code->offset, sizeof(val));
+		} else
+			break;
 		if (ret)
 			return ret;
 		code++;
-	}
+	} while (1);
 
 	s3 = code;
 stage3:
@@ -109,6 +118,9 @@ process_fetch_insn_bottom(struct fetch_insn *code, unsigned long val,
 	case FETCH_OP_ST_MEM:
 		probe_mem_read(dest, (void *)val + code->offset, code->size);
 		break;
+	case FETCH_OP_ST_UMEM:
+		probe_mem_read_user(dest, (void *)val + code->offset, code->size);
+		break;
 	case FETCH_OP_ST_STRING:
 		loc = *(u32 *)dest;
 		ret = fetch_store_string(val + code->offset, dest, base);
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 852e998051f6..3d6b868830f3 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -140,6 +140,13 @@ probe_mem_read(void *dest, void *src, size_t size)
 
 	return copy_from_user(dest, vaddr, size) ? -EFAULT : 0;
 }
+
+static nokprobe_inline int
+probe_mem_read_user(void *dest, void *src, size_t size)
+{
+	return probe_mem_read(dest, src, size);
+}
+
 /*
  * Fetch a null-terminated string. Caller MUST set *(u32 *)dest with max
  * length and relative data location.
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 07/16] selftests/ftrace: Add user-memory access syntax testcase
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (5 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 06/16] tracing/probe: Support user-space dereference Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 08/16] perf-probe: Add user memory access attribute support Steven Rostedt
                   ` (8 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Add a user-memory access syntax testcase which checks
new user-memory access syntax and ustring type.

Link: http://lkml.kernel.org/r/155789873385.26965.9557271156179140676.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 .../ftrace/test.d/kprobe/kprobe_args_user.tc  | 32 +++++++++++++++++++
 1 file changed, 32 insertions(+)
 create mode 100644 tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc

diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
new file mode 100644
index 000000000000..0f60087583d8
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args_user.tc
@@ -0,0 +1,32 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: Kprobe event user-memory access
+
+[ -f kprobe_events ] || exit_unsupported # this is configurable
+
+grep -q '\$arg<N>' README || exit_unresolved # depends on arch
+grep -A10 "fetcharg:" README | grep -q 'ustring' || exit_unsupported
+grep -A10 "fetcharg:" README | grep -q '\[u\]<offset>' || exit_unsupported
+
+:;: "user-memory access syntax and ustring working on user memory";:
+echo 'p:myevent do_sys_open path=+0($arg2):ustring path2=+u0($arg2):string' \
+	> kprobe_events
+
+grep myevent kprobe_events | \
+	grep -q 'path=+0($arg2):ustring path2=+u0($arg2):string'
+echo 1 > events/kprobes/myevent/enable
+echo > /dev/null
+echo 0 > events/kprobes/myevent/enable
+
+grep myevent trace | grep -q 'path="/dev/null" path2="/dev/null"'
+
+:;: "user-memory access syntax and ustring not working with kernel memory";:
+echo 'p:myevent vfs_symlink path=+0($arg3):ustring path2=+u0($arg3):string' \
+	> kprobe_events
+echo 1 > events/kprobes/myevent/enable
+ln -s foo $TMPDIR/bar
+echo 0 > events/kprobes/myevent/enable
+
+grep myevent trace | grep -q 'path=(fault) path2=(fault)'
+
+exit 0
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 08/16] perf-probe: Add user memory access attribute support
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (6 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 07/16] selftests/ftrace: Add user-memory access syntax testcase Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 09/16] tracing: Use correct function name in trace_filter_add_remove_task() comment Steven Rostedt
                   ` (7 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Add user memory access attribute for kprobe event arguments.
If a given 'local variable' is in user-space, User can
specify memory access method by '@user' suffix. This is
not only for string but also for data structure.

If we access a field of data structure in user memory from
kernel on some arch, it will fail. e.g.

 perf probe -a "sched_setscheduler param->sched_priority"

This will fail to access the "param->sched_priority" because
the param is __user pointer. Instead, we can now specify
@user suffix for such argument.

 perf probe -a "sched_setscheduler param->sched_priority@user"

Note that kernel memory access with "@user" must always fail
on any arch.

Link: http://lkml.kernel.org/r/155789874562.26965.10836126971405890891.stgit@devnote2

Acked-by: Ingo Molnar <mingo@kernel.org>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 tools/perf/Documentation/perf-probe.txt |  3 ++-
 tools/perf/util/probe-event.c           | 11 +++++++++++
 tools/perf/util/probe-event.h           |  2 ++
 tools/perf/util/probe-file.c            |  7 +++++++
 tools/perf/util/probe-file.h            |  1 +
 tools/perf/util/probe-finder.c          | 19 ++++++++++++-------
 6 files changed, 35 insertions(+), 8 deletions(-)

diff --git a/tools/perf/Documentation/perf-probe.txt b/tools/perf/Documentation/perf-probe.txt
index b6866a05edd2..ed3ecfa422e1 100644
--- a/tools/perf/Documentation/perf-probe.txt
+++ b/tools/perf/Documentation/perf-probe.txt
@@ -194,12 +194,13 @@ PROBE ARGUMENT
 --------------
 Each probe argument follows below syntax.
 
- [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE]
+ [NAME=]LOCALVAR|$retval|%REG|@SYMBOL[:TYPE][@user]
 
 'NAME' specifies the name of this argument (optional). You can use the name of local variable, local data structure member (e.g. var->field, var.field2), local array with fixed index (e.g. array[1], var->array[0], var->pointer[2]), or kprobe-tracer argument format (e.g. $retval, %ax, etc). Note that the name of this argument will be set as the last member name if you specify a local data structure member (e.g. field2 for 'var->field1.field2'.)
 '$vars' and '$params' special arguments are also available for NAME, '$vars' is expanded to the local variables (including function parameters) which can access at given probe point. '$params' is expanded to only the function parameters.
 'TYPE' casts the type of this argument (optional). If omitted, perf probe automatically set the type based on debuginfo (*). Currently, basic types (u8/u16/u32/u64/s8/s16/s32/s64), hexadecimal integers (x/x8/x16/x32/x64), signedness casting (u/s), "string" and bitfield are supported. (see TYPES for detail)
 On x86 systems %REG is always the short form of the register: for example %AX. %RAX or %EAX is not valid.
+"@user" is a special attribute which means the LOCALVAR will be treated as a user-space memory. This is only valid for kprobe event.
 
 TYPES
 -----
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 198e09ff611e..a7ca17be5fc5 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -1577,6 +1577,17 @@ static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
 		str = tmp + 1;
 	}
 
+	tmp = strchr(str, '@');
+	if (tmp && tmp != str && strcmp(tmp + 1, "user")) { /* user attr */
+		if (!user_access_is_supported()) {
+			semantic_error("ftrace does not support user access\n");
+			return -EINVAL;
+		}
+		*tmp = '\0';
+		arg->user_access = true;
+		pr_debug("user_access ");
+	}
+
 	tmp = strchr(str, ':');
 	if (tmp) {	/* Type setting */
 		*tmp = '\0';
diff --git a/tools/perf/util/probe-event.h b/tools/perf/util/probe-event.h
index 05c8d571a901..96a319cd2378 100644
--- a/tools/perf/util/probe-event.h
+++ b/tools/perf/util/probe-event.h
@@ -37,6 +37,7 @@ struct probe_trace_point {
 struct probe_trace_arg_ref {
 	struct probe_trace_arg_ref	*next;	/* Next reference */
 	long				offset;	/* Offset value */
+	bool				user_access;	/* User-memory access */
 };
 
 /* kprobe-tracer and uprobe-tracer tracing argument */
@@ -82,6 +83,7 @@ struct perf_probe_arg {
 	char				*var;	/* Variable name */
 	char				*type;	/* Type name */
 	struct perf_probe_arg_field	*field;	/* Structure fields */
+	bool				user_access;	/* User-memory access */
 };
 
 /* Perf probe probing event (point + arg) */
diff --git a/tools/perf/util/probe-file.c b/tools/perf/util/probe-file.c
index 4062bc4412a9..89ce1a9c3798 100644
--- a/tools/perf/util/probe-file.c
+++ b/tools/perf/util/probe-file.c
@@ -1015,6 +1015,7 @@ enum ftrace_readme {
 	FTRACE_README_PROBE_TYPE_X = 0,
 	FTRACE_README_KRETPROBE_OFFSET,
 	FTRACE_README_UPROBE_REF_CTR,
+	FTRACE_README_USER_ACCESS,
 	FTRACE_README_END,
 };
 
@@ -1027,6 +1028,7 @@ static struct {
 	DEFINE_TYPE(FTRACE_README_PROBE_TYPE_X, "*type: * x8/16/32/64,*"),
 	DEFINE_TYPE(FTRACE_README_KRETPROBE_OFFSET, "*place (kretprobe): *"),
 	DEFINE_TYPE(FTRACE_README_UPROBE_REF_CTR, "*ref_ctr_offset*"),
+	DEFINE_TYPE(FTRACE_README_USER_ACCESS, "*[u]<offset>*"),
 };
 
 static bool scan_ftrace_readme(enum ftrace_readme type)
@@ -1087,3 +1089,8 @@ bool uprobe_ref_ctr_is_supported(void)
 {
 	return scan_ftrace_readme(FTRACE_README_UPROBE_REF_CTR);
 }
+
+bool user_access_is_supported(void)
+{
+	return scan_ftrace_readme(FTRACE_README_USER_ACCESS);
+}
diff --git a/tools/perf/util/probe-file.h b/tools/perf/util/probe-file.h
index 2a249182f2a6..986c1c94f64f 100644
--- a/tools/perf/util/probe-file.h
+++ b/tools/perf/util/probe-file.h
@@ -70,6 +70,7 @@ int probe_cache__show_all_caches(struct strfilter *filter);
 bool probe_type_is_available(enum probe_type type);
 bool kretprobe_offset_is_supported(void);
 bool uprobe_ref_ctr_is_supported(void);
+bool user_access_is_supported(void);
 #else	/* ! HAVE_LIBELF_SUPPORT */
 static inline struct probe_cache *probe_cache__new(const char *tgt __maybe_unused, struct nsinfo *nsi __maybe_unused)
 {
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index c37fbef1711d..c202027716d0 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -294,7 +294,7 @@ static int convert_variable_location(Dwarf_Die *vr_die, Dwarf_Addr addr,
 
 static int convert_variable_type(Dwarf_Die *vr_die,
 				 struct probe_trace_arg *tvar,
-				 const char *cast)
+				 const char *cast, bool user_access)
 {
 	struct probe_trace_arg_ref **ref_ptr = &tvar->ref;
 	Dwarf_Die type;
@@ -334,7 +334,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
 	pr_debug("%s type is %s.\n",
 		 dwarf_diename(vr_die), dwarf_diename(&type));
 
-	if (cast && strcmp(cast, "string") == 0) {	/* String type */
+	if (cast && (!strcmp(cast, "string") || !strcmp(cast, "ustring"))) {
+		/* String type */
 		ret = dwarf_tag(&type);
 		if (ret != DW_TAG_pointer_type &&
 		    ret != DW_TAG_array_type) {
@@ -357,6 +358,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
 				pr_warning("Out of memory error\n");
 				return -ENOMEM;
 			}
+			(*ref_ptr)->user_access = user_access;
 		}
 		if (!die_compare_name(&type, "char") &&
 		    !die_compare_name(&type, "unsigned char")) {
@@ -411,7 +413,7 @@ static int convert_variable_type(Dwarf_Die *vr_die,
 static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 				    struct perf_probe_arg_field *field,
 				    struct probe_trace_arg_ref **ref_ptr,
-				    Dwarf_Die *die_mem)
+				    Dwarf_Die *die_mem, bool user_access)
 {
 	struct probe_trace_arg_ref *ref = *ref_ptr;
 	Dwarf_Die type;
@@ -448,6 +450,7 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 				*ref_ptr = ref;
 		}
 		ref->offset += dwarf_bytesize(&type) * field->index;
+		ref->user_access = user_access;
 		goto next;
 	} else if (tag == DW_TAG_pointer_type) {
 		/* Check the pointer and dereference */
@@ -519,17 +522,18 @@ static int convert_variable_fields(Dwarf_Die *vr_die, const char *varname,
 		}
 	}
 	ref->offset += (long)offs;
+	ref->user_access = user_access;
 
 	/* If this member is unnamed, we need to reuse this field */
 	if (!dwarf_diename(die_mem))
 		return convert_variable_fields(die_mem, varname, field,
-						&ref, die_mem);
+						&ref, die_mem, user_access);
 
 next:
 	/* Converting next field */
 	if (field->next)
 		return convert_variable_fields(die_mem, field->name,
-					field->next, &ref, die_mem);
+				field->next, &ref, die_mem, user_access);
 	else
 		return 0;
 }
@@ -555,11 +559,12 @@ static int convert_variable(Dwarf_Die *vr_die, struct probe_finder *pf)
 	else if (ret == 0 && pf->pvar->field) {
 		ret = convert_variable_fields(vr_die, pf->pvar->var,
 					      pf->pvar->field, &pf->tvar->ref,
-					      &die_mem);
+					      &die_mem, pf->pvar->user_access);
 		vr_die = &die_mem;
 	}
 	if (ret == 0)
-		ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type);
+		ret = convert_variable_type(vr_die, pf->tvar, pf->pvar->type,
+					    pf->pvar->user_access);
 	/* *expr will be cached in libdw. Don't free it. */
 	return ret;
 }
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 09/16] tracing: Use correct function name in trace_filter_add_remove_task() comment
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (7 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 08/16] perf-probe: Add user memory access attribute support Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 10/16] uaccess: Add a prototype of non-static __probe_user_read() Steven Rostedt
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Matthias Kaehlcke

From: Matthias Kaehlcke <mka@chromium.org>

The comment of trace_filter_add_remove_task() refers to the function as
'trace_pid_filter_add_remove_task', use the correct name.

Link: http://lkml.kernel.org/r/20190523192628.134406-1-mka@chromium.org

Signed-off-by: Matthias Kaehlcke <mka@chromium.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/trace.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index 6b3b5b0495a8..77b9c4ca5faa 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -366,7 +366,7 @@ trace_ignore_this_task(struct trace_pid_list *filtered_pids, struct task_struct
 }
 
 /**
- * trace_pid_filter_add_remove_task - Add or remove a task from a pid_list
+ * trace_filter_add_remove_task - Add or remove a task from a pid_list
  * @pid_list: The list to modify
  * @self: The current task for fork or NULL for exit
  * @task: The task to add or remove
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 10/16] uaccess: Add a prototype of non-static __probe_user_read()
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (8 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 09/16] tracing: Use correct function name in trace_filter_add_remove_task() comment Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 11/16] tracing/kprobe: Cast user-space address correctly Steven Rostedt
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, kbuild test robot, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Declare a prototype of non-static __probe_user_read() as
same as __probe_kernel_read() at uaccess.h.

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 include/linux/uaccess.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 9c435c3f2105..34a038563d97 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -252,6 +252,7 @@ extern long __probe_kernel_read(void *dst, const void *src, size_t size);
  * happens, handle that and return -EFAULT.
  */
 extern long probe_user_read(void *dst, const void __user *src, size_t size);
+extern long __probe_user_read(void *dst, const void __user *src, size_t size);
 
 /*
  * probe_kernel_write(): safely attempt to write to a location
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 11/16] tracing/kprobe: Cast user-space address correctly
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (9 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 10/16] uaccess: Add a prototype of non-static __probe_user_read() Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall Steven Rostedt
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel
  Cc: Ingo Molnar, Andrew Morton, kbuild test robot, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Cast user-space address correctly to pass to probe_user_read().

Reported-by: kbuild test robot <lkp@intel.com>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/trace_kprobe.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index ff14eb011c1c..2c5357dddb92 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -955,7 +955,9 @@ probe_mem_read(void *dest, void *src, size_t size)
 static nokprobe_inline int
 probe_mem_read_user(void *dest, void *src, size_t size)
 {
-	return probe_user_read(dest, src, size);
+	const void __user *uaddr =  (__force const void __user *)src;
+
+	return probe_user_read(dest, uaddr, size);
 }
 
 /* Note that we don't verify it, since the code does not come from user space */
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (10 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 11/16] tracing/kprobe: Cast user-space address correctly Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-07-02 16:50   ` Mark Rutland
  2019-05-26 19:18 ` [for-next][PATCH 13/16] tracing/kprobe: Add kprobe_event= boot parameter Steven Rostedt
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Initialize kprobes at postcore_initcall level instead of module_init
since kprobes is not a module, and it depends on only subsystems
initialized in core_initcall.
This will allow ftrace kprobe event to add new events when it is
initializing because ftrace kprobe event is initialized at
later initcall level.

Link: http://lkml.kernel.org/r/155851394736.15728.13626739508905120098.stgit@devnote2

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/kprobes.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index b1ea30a5540e..54aaaad00a47 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
 		init_test_probes();
 	return err;
 }
+postcore_initcall(init_kprobes);
 
 #ifdef CONFIG_DEBUG_FS
 static void report_probe(struct seq_file *pi, struct kprobe *p,
@@ -2614,5 +2615,3 @@ static int __init debugfs_kprobe_init(void)
 
 late_initcall(debugfs_kprobe_init);
 #endif /* CONFIG_DEBUG_FS */
-
-module_init(init_kprobes);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 13/16] tracing/kprobe: Add kprobe_event= boot parameter
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (11 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 14/16] tracing: Make a separate config for trace event self tests Steven Rostedt
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Masami Hiramatsu

From: Masami Hiramatsu <mhiramat@kernel.org>

Add kprobe_event= boot parameter to define kprobe events
at boot time.
The definition syntax is similar to tracefs/kprobe_events
interface, but use ',' and ';' instead of ' ' and '\n'
respectively. e.g.

  kprobe_event=p,vfs_read,$arg1,$arg2

This puts a probe on vfs_read with argument1 and 2, and
enable the new event.

Link: http://lkml.kernel.org/r/155851395498.15728.830529496248543583.stgit@devnote2

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 .../admin-guide/kernel-parameters.txt         | 13 +++++
 Documentation/trace/kprobetrace.rst           | 14 +++++
 kernel/trace/trace_kprobe.c                   | 54 +++++++++++++++++++
 3 files changed, 81 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 138f6664b2e2..11b9ffb265eb 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2007,6 +2007,19 @@
 			Built with CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF=y,
 			the default is off.
 
+	kprobe_event=[probe-list]
+			[FTRACE] Add kprobe events and enable at boot time.
+			The probe-list is a semicolon delimited list of probe
+			definitions. Each definition is same as kprobe_events
+			interface, but the parameters are comma delimited.
+			For example, to add a kprobe event on vfs_read with
+			arg1 and arg2, add to the command line;
+
+			      kprobe_event=p,vfs_read,$arg1,$arg2
+
+			See also Documentation/trace/kprobetrace.rst "Kernel
+			Boot Parameter" section.
+
 	kpti=		[ARM64] Control page table isolation of user
 			and kernel address spaces.
 			Default: enabled on cores which need mitigation.
diff --git a/Documentation/trace/kprobetrace.rst b/Documentation/trace/kprobetrace.rst
index 09ff474493e1..af776989caca 100644
--- a/Documentation/trace/kprobetrace.rst
+++ b/Documentation/trace/kprobetrace.rst
@@ -146,6 +146,20 @@ You can check the total number of probe hits and probe miss-hits via
 The first column is event name, the second is the number of probe hits,
 the third is the number of probe miss-hits.
 
+Kernel Boot Parameter
+---------------------
+You can add and enable new kprobe events when booting up the kernel by
+"kprobe_event=" parameter. The parameter accepts a semicolon-delimited
+kprobe events, which format is similar to the kprobe_events.
+The difference is that the probe definition parameters are comma-delimited
+instead of space. For example, adding myprobe event on do_sys_open like below
+
+  p:myprobe do_sys_open dfd=%ax filename=%dx flags=%cx mode=+4($stack)
+
+should be below for kernel boot parameter (just replace spaces with comma)
+
+  p:myprobe,do_sys_open,dfd=%ax,filename=%dx,flags=%cx,mode=+4($stack)
+
 
 Usage examples
 --------------
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 2c5357dddb92..004fffd24ec1 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -12,6 +12,8 @@
 #include <linux/rculist.h>
 #include <linux/error-injection.h>
 
+#include <asm/setup.h>  /* for COMMAND_LINE_SIZE */
+
 #include "trace_dynevent.h"
 #include "trace_kprobe_selftest.h"
 #include "trace_probe.h"
@@ -19,6 +21,17 @@
 
 #define KPROBE_EVENT_SYSTEM "kprobes"
 #define KRETPROBE_MAXACTIVE_MAX 4096
+#define MAX_KPROBE_CMDLINE_SIZE 1024
+
+/* Kprobe early definition from command line */
+static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata;
+
+static int __init set_kprobe_boot_events(char *str)
+{
+	strlcpy(kprobe_boot_events_buf, str, COMMAND_LINE_SIZE);
+	return 0;
+}
+__setup("kprobe_event=", set_kprobe_boot_events);
 
 static int trace_kprobe_create(int argc, const char **argv);
 static int trace_kprobe_show(struct seq_file *m, struct dyn_event *ev);
@@ -1494,6 +1507,44 @@ void destroy_local_trace_kprobe(struct trace_event_call *event_call)
 }
 #endif /* CONFIG_PERF_EVENTS */
 
+static __init void enable_boot_kprobe_events(void)
+{
+	struct trace_array *tr = top_trace_array();
+	struct trace_event_file *file;
+	struct trace_kprobe *tk;
+	struct dyn_event *pos;
+
+	mutex_lock(&event_mutex);
+	for_each_trace_kprobe(tk, pos) {
+		list_for_each_entry(file, &tr->events, list)
+			if (file->event_call == &tk->tp.call)
+				trace_event_enable_disable(file, 1, 0);
+	}
+	mutex_unlock(&event_mutex);
+}
+
+static __init void setup_boot_kprobe_events(void)
+{
+	char *p, *cmd = kprobe_boot_events_buf;
+	int ret;
+
+	strreplace(kprobe_boot_events_buf, ',', ' ');
+
+	while (cmd && *cmd != '\0') {
+		p = strchr(cmd, ';');
+		if (p)
+			*p++ = '\0';
+
+		ret = trace_run_command(cmd, create_or_delete_trace_kprobe);
+		if (ret)
+			pr_warn("Failed to add event(%d): %s\n", ret, cmd);
+
+		cmd = p;
+	}
+
+	enable_boot_kprobe_events();
+}
+
 /* Make a tracefs interface for controlling probe points */
 static __init int init_kprobe_trace(void)
 {
@@ -1525,6 +1576,9 @@ static __init int init_kprobe_trace(void)
 
 	if (!entry)
 		pr_warn("Could not create tracefs 'kprobe_profile' entry\n");
+
+	setup_boot_kprobe_events();
+
 	return 0;
 }
 fs_initcall(init_kprobe_trace);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 14/16] tracing: Make a separate config for trace event self tests
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (12 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 13/16] tracing/kprobe: Add kprobe_event= boot parameter Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 15/16] tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 16/16] ftrace: Enable trampoline when rec count returns back to one Steven Rostedt
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

The trace event self tests enable loop through *all* events, enables each
one, one at a time, runs some code to trigger various events (not
necessarily the same events), and checks if anything went wrong. The issue
is that trace events are usually the least likely start up test to cause a
problem, but they take the longest to run (because there are so many
events). When one of the other tests trigger a bug, the trace event start up
tests causes the bisect to take much longer, because it takes 10s of seconds
to get through the trace event tests.

By making them a separate config (even though they are enabled by default if
start up tests are set), it is possible to turn them off and still run the
other tracing start up tests much quicker.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/Kconfig        | 12 +++++++++++-
 kernel/trace/trace_events.c |  2 +-
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/kernel/trace/Kconfig b/kernel/trace/Kconfig
index 5d965cef6c77..07d22c61b634 100644
--- a/kernel/trace/Kconfig
+++ b/kernel/trace/Kconfig
@@ -596,9 +596,19 @@ config FTRACE_STARTUP_TEST
 	  functioning properly. It will do tests on all the configured
 	  tracers of ftrace.
 
+config EVENT_TRACE_STARTUP_TEST
+	bool "Run selftest on trace events"
+	depends on FTRACE_STARTUP_TEST
+	default y
+	help
+	  This option performs a test on all trace events in the system.
+	  It basically just enables each event and runs some code that
+	  will trigger events (not necessarily the event it enables)
+	  This may take some time run as there are a lot of events.
+
 config EVENT_TRACE_TEST_SYSCALLS
 	bool "Run selftest on syscall events"
-	depends on FTRACE_STARTUP_TEST
+	depends on EVENT_TRACE_STARTUP_TEST
 	help
 	 This option will also enable testing every syscall event.
 	 It only enables the event and disables it and runs various loads
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 0ce3db67f556..edc72f3b080c 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -3190,7 +3190,7 @@ void __init trace_event_init(void)
 	event_trace_enable();
 }
 
-#ifdef CONFIG_FTRACE_STARTUP_TEST
+#ifdef CONFIG_EVENT_TRACE_STARTUP_TEST
 
 static DEFINE_SPINLOCK(test_spinlock);
 static DEFINE_SPINLOCK(test_spinlock_irq);
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 15/16] tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (13 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 14/16] tracing: Make a separate config for trace event self tests Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  2019-05-26 19:18 ` [for-next][PATCH 16/16] ftrace: Enable trampoline when rec count returns back to one Steven Rostedt
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>

When having kprobe trace event start up tests enabled and adding a
kprobe_event on the kernel command line, it produced the following:

 trace_kprobe: Testing kprobe tracing:
 WARNING: CPU: 5 PID: 1 at kernel/trace/trace_kprobe.c:1724 kprobe_trace_self_tests_init+0x32d/0x36b
 Modules linked in:
 CPU: 5 PID: 1 Comm: swapper/0 Not tainted 5.2.0-rc1-test+ #249
 Hardware name: Hewlett-Packard HP Compaq Pro 6300 SFF/339A, BIOS K01 v03.03 07/14/2016
 RIP: 0010:kprobe_trace_self_tests_init+0x32d/0x36b
 Code: b7 e8 4f 8d a2 fe 85 c0 74 10 0f 0b 48 c7 c7 c8 1b 0d b7 ff c3 e8 19 af 99 fe 48 c7 c7 40 93 27 b7 e8 7f 1a a5 fe 85 c0 74 10 <0f> 0b 48 c7 c7 f8 1b 0d b7 ff c3 e8 f9 ae
9 a0 fe 85
 RSP: 0018:ffffb36e40653e08 EFLAGS: 00010286
 RAX: 00000000fffffff0 RBX: 0000000000000000 RCX: ffffb36e40653d5c
 RDX: 0000000000000000 RSI: ffffffffb72776e0 RDI: 0000000000000246
 RBP: ffff98414fe58ff8 R08: 0000000000000000 R09: 0000000000000000
 R10: 0000000000000000 R11: ffff98415d8aa940 R12: 0000000000000000
 R13: ffffffffb737c1b0 R14: 0000000000000000 R15: 0000000000000000
 FS:  0000000000000000(0000) GS:ffff98415ea80000(0000) knlGS:0000000000000000
 CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 CR2: 00007f959ce741b8 CR3: 000000011a210002 CR4: 00000000001606e0
 Call Trace:
  ? init_kprobe_trace+0x19e/0x19e
  ? do_early_param+0x8e/0x8e
  do_one_initcall+0x6f/0x2b4
  ? do_early_param+0x8e/0x8e
  kernel_init_freeable+0x21d/0x2c6
  ? rest_init+0x146/0x146
  kernel_init+0xa/0x10a
  ret_from_fork+0x3a/0x50
 ---[ end trace 488430c083a4c956 ]---

As with the trace events, if a trace event is set on the kernel command
line, the trace events start up tests are suspended. The kprobe start up
tests should do the same when a kprobe is enabled on the kernel command
line.

Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/trace_kprobe.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c
index 004fffd24ec1..7958da2fd922 100644
--- a/kernel/trace/trace_kprobe.c
+++ b/kernel/trace/trace_kprobe.c
@@ -25,6 +25,7 @@
 
 /* Kprobe early definition from command line */
 static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata;
+static bool kprobe_boot_events_enabled __initdata;
 
 static int __init set_kprobe_boot_events(char *str)
 {
@@ -1538,6 +1539,8 @@ static __init void setup_boot_kprobe_events(void)
 		ret = trace_run_command(cmd, create_or_delete_trace_kprobe);
 		if (ret)
 			pr_warn("Failed to add event(%d): %s\n", ret, cmd);
+		else
+			kprobe_boot_events_enabled = true;
 
 		cmd = p;
 	}
@@ -1611,6 +1614,11 @@ static __init int kprobe_trace_self_tests_init(void)
 	if (tracing_is_disabled())
 		return -ENODEV;
 
+	if (kprobe_boot_events_enabled) {
+		pr_info("Skipping kprobe tests due to kprobe_event on cmdline\n");
+		return 0;
+	}
+
 	target = kprobe_trace_selftest_target;
 
 	pr_info("Testing kprobe tracing: ");
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [for-next][PATCH 16/16] ftrace: Enable trampoline when rec count returns back to one
  2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
                   ` (14 preceding siblings ...)
  2019-05-26 19:18 ` [for-next][PATCH 15/16] tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline Steven Rostedt
@ 2019-05-26 19:18 ` Steven Rostedt
  15 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-05-26 19:18 UTC (permalink / raw)
  To: linux-kernel; +Cc: Ingo Molnar, Andrew Morton, Cheng Jian

From: Cheng Jian <cj.chengjian@huawei.com>

Custom trampolines can only be enabled if there is only a single ops
attached to it. If there's only a single callback registered to a function,
and the ops has a trampoline registered for it, then we can call the
trampoline directly. This is very useful for improving the performance of
ftrace and livepatch.

If more than one callback is registered to a function, the general
trampoline is used, and the custom trampoline is not restored back to the
direct call even if all the other callbacks were unregistered and we are
back to one callback for the function.

To fix this, set FTRACE_FL_TRAMP flag if rec count is decremented
to one, and the ops that left has a trampoline.

Testing After this patch :

insmod livepatch_unshare_files.ko
cat /sys/kernel/debug/tracing/enabled_functions

	unshare_files (1) R I	tramp: 0xffffffffc0000000(klp_ftrace_handler+0x0/0xa0) ->ftrace_ops_assist_func+0x0/0xf0

echo unshare_files > /sys/kernel/debug/tracing/set_ftrace_filter
echo function > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/enabled_functions

	unshare_files (2) R I ->ftrace_ops_list_func+0x0/0x150

echo nop > /sys/kernel/debug/tracing/current_tracer
cat /sys/kernel/debug/tracing/enabled_functions

	unshare_files (1) R I	tramp: 0xffffffffc0000000(klp_ftrace_handler+0x0/0xa0) ->ftrace_ops_assist_func+0x0/0xf0

Link: http://lkml.kernel.org/r/1556969979-111047-1-git-send-email-cj.chengjian@huawei.com

Signed-off-by: Cheng Jian <cj.chengjian@huawei.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/trace/ftrace.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 4f2c26bebe2a..5c3eadb143ed 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1622,6 +1622,11 @@ static bool test_rec_ops_needs_regs(struct dyn_ftrace *rec)
 	return  keep_regs;
 }
 
+static struct ftrace_ops *
+ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
+static struct ftrace_ops *
+ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
+
 static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
 				     int filter_hash,
 				     bool inc)
@@ -1750,15 +1755,17 @@ static bool __ftrace_hash_rec_update(struct ftrace_ops *ops,
 			}
 
 			/*
-			 * If the rec had TRAMP enabled, then it needs to
-			 * be cleared. As TRAMP can only be enabled iff
-			 * there is only a single ops attached to it.
-			 * In otherwords, always disable it on decrementing.
-			 * In the future, we may set it if rec count is
-			 * decremented to one, and the ops that is left
-			 * has a trampoline.
+			 * The TRAMP needs to be set only if rec count
+			 * is decremented to one, and the ops that is
+			 * left has a trampoline. As TRAMP can only be
+			 * enabled if there is only a single ops attached
+			 * to it.
 			 */
-			rec->flags &= ~FTRACE_FL_TRAMP;
+			if (ftrace_rec_count(rec) == 1 &&
+			    ftrace_find_tramp_ops_any(rec))
+				rec->flags |= FTRACE_FL_TRAMP;
+			else
+				rec->flags &= ~FTRACE_FL_TRAMP;
 
 			/*
 			 * flags will be cleared in ftrace_check_record()
@@ -1951,11 +1958,6 @@ static void print_ip_ins(const char *fmt, const unsigned char *p)
 		printk(KERN_CONT "%s%02x", i ? ":" : "", p[i]);
 }
 
-static struct ftrace_ops *
-ftrace_find_tramp_ops_any(struct dyn_ftrace *rec);
-static struct ftrace_ops *
-ftrace_find_tramp_ops_next(struct dyn_ftrace *rec, struct ftrace_ops *ops);
-
 enum ftrace_bug_type ftrace_bug_type;
 const void *ftrace_expected;
 
-- 
2.20.1



^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-05-26 19:18 ` [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall Steven Rostedt
@ 2019-07-02 16:50   ` Mark Rutland
  2019-07-03 13:50     ` Catalin Marinas
  2019-07-03 14:02     ` Steven Rostedt
  0 siblings, 2 replies; 32+ messages in thread
From: Mark Rutland @ 2019-07-02 16:50 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Catalin Marinas

On Sun, May 26, 2019 at 03:18:40PM -0400, Steven Rostedt wrote:
> From: Masami Hiramatsu <mhiramat@kernel.org>
> 
> Initialize kprobes at postcore_initcall level instead of module_init
> since kprobes is not a module, and it depends on only subsystems
> initialized in core_initcall.
> This will allow ftrace kprobe event to add new events when it is
> initializing because ftrace kprobe event is initialized at
> later initcall level.
> 
> Link: http://lkml.kernel.org/r/155851394736.15728.13626739508905120098.stgit@devnote2
> 
> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> ---
>  kernel/kprobes.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index b1ea30a5540e..54aaaad00a47 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
>  		init_test_probes();
>  	return err;
>  }
> +postcore_initcall(init_kprobes);

As a heads-up, this is causing boot-time failures on arm64.

On arm64 kprobes depends on the BRK handler we register in
debug_traps_init(), which is an arch_initcall.

As of this change, init_krprobes() calls init_test_probes() before
that's registered, so we end up hitting a BRK before we can handle it.

Thanks,
Mark.

>  
>  #ifdef CONFIG_DEBUG_FS
>  static void report_probe(struct seq_file *pi, struct kprobe *p,
> @@ -2614,5 +2615,3 @@ static int __init debugfs_kprobe_init(void)
>  
>  late_initcall(debugfs_kprobe_init);
>  #endif /* CONFIG_DEBUG_FS */
> -
> -module_init(init_kprobes);
> -- 
> 2.20.1
> 
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-02 16:50   ` Mark Rutland
@ 2019-07-03 13:50     ` Catalin Marinas
  2019-07-03 14:02     ` Steven Rostedt
  1 sibling, 0 replies; 32+ messages in thread
From: Catalin Marinas @ 2019-07-03 13:50 UTC (permalink / raw)
  To: Mark Rutland
  Cc: Steven Rostedt, linux-kernel, Ingo Molnar, Andrew Morton,
	Masami Hiramatsu

On Tue, Jul 02, 2019 at 05:50:09PM +0100, Mark Rutland wrote:
> On Sun, May 26, 2019 at 03:18:40PM -0400, Steven Rostedt wrote:
> > From: Masami Hiramatsu <mhiramat@kernel.org>
> > 
> > Initialize kprobes at postcore_initcall level instead of module_init
> > since kprobes is not a module, and it depends on only subsystems
> > initialized in core_initcall.
> > This will allow ftrace kprobe event to add new events when it is
> > initializing because ftrace kprobe event is initialized at
> > later initcall level.
> > 
> > Link: http://lkml.kernel.org/r/155851394736.15728.13626739508905120098.stgit@devnote2
> > 
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> > ---
> >  kernel/kprobes.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > index b1ea30a5540e..54aaaad00a47 100644
> > --- a/kernel/kprobes.c
> > +++ b/kernel/kprobes.c
> > @@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
> >  		init_test_probes();
> >  	return err;
> >  }
> > +postcore_initcall(init_kprobes);
> 
> As a heads-up, this is causing boot-time failures on arm64.
> 
> On arm64 kprobes depends on the BRK handler we register in
> debug_traps_init(), which is an arch_initcall.
> 
> As of this change, init_krprobes() calls init_test_probes() before
> that's registered, so we end up hitting a BRK before we can handle it.

Thanks Mark for identifying this.

So we either revert the above commit in -next or queue the one below
together with the rest of the kprobes changes (I can queue it via the
arm64 for-next/core assuming that the above commit id remains stable):

--------------8<------------------------------------
From de4f4d30bab3d77d6643a6fa9ba1deff73dac7f2 Mon Sep 17 00:00:00 2001
From: Catalin Marinas <catalin.marinas@arm.com>
Date: Wed, 3 Jul 2019 14:44:23 +0100
Subject: [PATCH] arm64: Initialise the debug traps earlier

Commit b5f8b32c93b2 ("kprobes: Initialize kprobes at postcore_initcall")
makes init_kprobes() a postcore_initcall while the arm64 handling of the
BRK instruction is initialised at arch_initcall level. Make the arm64
debug_traps_init() a core_initcall.

Fixes: b5f8b32c93b2 ("kprobes: Initialize kprobes at postcore_initcall")
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/kernel/debug-monitors.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm64/kernel/debug-monitors.c b/arch/arm64/kernel/debug-monitors.c
index f8719bd30850..81770105cd8e 100644
--- a/arch/arm64/kernel/debug-monitors.c
+++ b/arch/arm64/kernel/debug-monitors.c
@@ -382,7 +382,7 @@ static int __init debug_traps_init(void)
 			      TRAP_BRKPT, "ptrace BRK handler");
 	return 0;
 }
-arch_initcall(debug_traps_init);
+core_initcall(debug_traps_init);
 
 /* Re-enable single step for syscall restarting. */
 void user_rewind_single_step(struct task_struct *task)

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-02 16:50   ` Mark Rutland
  2019-07-03 13:50     ` Catalin Marinas
@ 2019-07-03 14:02     ` Steven Rostedt
  2019-07-03 14:08       ` Catalin Marinas
  2019-07-09 12:30       ` Masami Hiramatsu
  1 sibling, 2 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-07-03 14:02 UTC (permalink / raw)
  To: Mark Rutland
  Cc: linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu,
	Catalin Marinas

On Tue, 2 Jul 2019 17:50:09 +0100
Mark Rutland <mark.rutland@arm.com> wrote:

> On Sun, May 26, 2019 at 03:18:40PM -0400, Steven Rostedt wrote:
> > From: Masami Hiramatsu <mhiramat@kernel.org>
> > 
> > Initialize kprobes at postcore_initcall level instead of module_init
> > since kprobes is not a module, and it depends on only subsystems
> > initialized in core_initcall.
> > This will allow ftrace kprobe event to add new events when it is
> > initializing because ftrace kprobe event is initialized at
> > later initcall level.
> > 
> > Link: http://lkml.kernel.org/r/155851394736.15728.13626739508905120098.stgit@devnote2
> > 
> > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> > ---
> >  kernel/kprobes.c | 3 +--
> >  1 file changed, 1 insertion(+), 2 deletions(-)
> > 
> > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > index b1ea30a5540e..54aaaad00a47 100644
> > --- a/kernel/kprobes.c
> > +++ b/kernel/kprobes.c
> > @@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
> >  		init_test_probes();
> >  	return err;
> >  }
> > +postcore_initcall(init_kprobes);  
> 
> As a heads-up, this is causing boot-time failures on arm64.

Thanks for the report.

> 
> On arm64 kprobes depends on the BRK handler we register in
> debug_traps_init(), which is an arch_initcall.
> 
> As of this change, init_krprobes() calls init_test_probes() before
> that's registered, so we end up hitting a BRK before we can handle it.
> 

Would something like this help?

-- Steve

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5471efbeb937..0ca6f53c8505 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
 extern unsigned long __start_kprobe_blacklist[];
 extern unsigned long __stop_kprobe_blacklist[];
 
+static bool run_kprobe_tests __initdata;
+
 static int __init init_kprobes(void)
 {
 	int i, err = 0;
@@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
 	kprobes_initialized = (err == 0);
 
 	if (!err)
-		init_test_probes();
+		run_kprobe_tests = true;
 	return err;
 }
 subsys_initcall(init_kprobes);
 
+static int __init run_init_test_probes(void)
+{
+	if (run_kprobe_tests)
+		init_test_probes();
+}
+module_init(run_init_test_probes);
+
 #ifdef CONFIG_DEBUG_FS
 static void report_probe(struct seq_file *pi, struct kprobe *p,
 		const char *sym, int offset, char *modname, struct kprobe *pp)


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:02     ` Steven Rostedt
@ 2019-07-03 14:08       ` Catalin Marinas
  2019-07-03 14:24         ` Steven Rostedt
  2019-07-09 15:15         ` Steven Rostedt
  2019-07-09 12:30       ` Masami Hiramatsu
  1 sibling, 2 replies; 32+ messages in thread
From: Catalin Marinas @ 2019-07-03 14:08 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

On Wed, Jul 03, 2019 at 10:02:05AM -0400, Steven Rostedt wrote:
> > On arm64 kprobes depends on the BRK handler we register in
> > debug_traps_init(), which is an arch_initcall.
> > 
> > As of this change, init_krprobes() calls init_test_probes() before
> > that's registered, so we end up hitting a BRK before we can handle it.
> 
> Would something like this help?
> 
> -- Steve
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 5471efbeb937..0ca6f53c8505 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
>  extern unsigned long __start_kprobe_blacklist[];
>  extern unsigned long __stop_kprobe_blacklist[];
>  
> +static bool run_kprobe_tests __initdata;
> +
>  static int __init init_kprobes(void)
>  {
>  	int i, err = 0;
> @@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
>  	kprobes_initialized = (err == 0);
>  
>  	if (!err)
> -		init_test_probes();
> +		run_kprobe_tests = true;
>  	return err;
>  }
>  subsys_initcall(init_kprobes);
>  
> +static int __init run_init_test_probes(void)
> +{
> +	if (run_kprobe_tests)
> +		init_test_probes();

A return 0 here.

> +}
> +module_init(run_init_test_probes);

This does the trick. I prefer your fix as it leaves the arch code
unchanged. In case you need it:

Tested-by: Catalin Marinas <catalin.marinas@arm.com>

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:08       ` Catalin Marinas
@ 2019-07-03 14:24         ` Steven Rostedt
  2019-07-03 14:25           ` Steven Rostedt
  2019-07-09 15:15         ` Steven Rostedt
  1 sibling, 1 reply; 32+ messages in thread
From: Steven Rostedt @ 2019-07-03 14:24 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

On Wed, 3 Jul 2019 15:08:32 +0100
Catalin Marinas <catalin.marinas@arm.com> wrote:


> > +static int __init run_init_test_probes(void)
> > +{
> > +	if (run_kprobe_tests)
> > +		init_test_probes();  
> 
> A return 0 here.

Will update (would have triggered a failure on my test suite anyway ;-)

> 
> > +}
> > +module_init(run_init_test_probes);  
> 
> This does the trick. I prefer your fix as it leaves the arch code
> unchanged. In case you need it:
> 
> Tested-by: Catalin Marinas <catalin.marinas@arm.com>
> 

Great! Thanks.

-- Steve

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:24         ` Steven Rostedt
@ 2019-07-03 14:25           ` Steven Rostedt
  2019-07-03 14:37             ` Steven Rostedt
  2019-07-09 12:51             ` Masami Hiramatsu
  0 siblings, 2 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-07-03 14:25 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Catalin Marinas, Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton

On Wed, 3 Jul 2019 10:24:02 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Wed, 3 Jul 2019 15:08:32 +0100
> Catalin Marinas <catalin.marinas@arm.com> wrote:
> 
> 
> > > +static int __init run_init_test_probes(void)
> > > +{
> > > +	if (run_kprobe_tests)
> > > +		init_test_probes();    
> > 
> > A return 0 here.  
> 
> Will update (would have triggered a failure on my test suite anyway ;-)
> 
> >   
> > > +}
> > > +module_init(run_init_test_probes);    
> > 
> > This does the trick. I prefer your fix as it leaves the arch code
> > unchanged. In case you need it:
> > 
> > Tested-by: Catalin Marinas <catalin.marinas@arm.com>
> >   
>

Masami,

If you give me an Acked-by, I'll add it to my tree.

-- Steve

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:25           ` Steven Rostedt
@ 2019-07-03 14:37             ` Steven Rostedt
  2019-07-09 12:51             ` Masami Hiramatsu
  1 sibling, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-07-03 14:37 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Catalin Marinas, Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton

This would be the official patch:

From: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
Subject: [PATCH] kprobes: Run init_test_probes() later in boot up

It was reported that the moving of the kprobe initialization earlier in the
boot process caused arm64 to crash. This was due to arm64 depending on the
BRK handler being registered first, but the init_test_probes() can be called
before that happens.

By moving the init_test_probes() to later in the boot process, the BRK
handler is now guaranteed to be initialized before init_test_probes() is
called.

Link: http://lkml.kernel.org/r/20190702165008.GC34718@lakrids.cambridge.arm.com

Tested-by: Catalin Marinas <catalin.marinas@arm.com>
Reported-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
---
 kernel/kprobes.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 5471efbeb937..5a6ecd7bfd73 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
 extern unsigned long __start_kprobe_blacklist[];
 extern unsigned long __stop_kprobe_blacklist[];
 
+static bool run_kprobe_tests __initdata;
+
 static int __init init_kprobes(void)
 {
 	int i, err = 0;
@@ -2286,11 +2288,19 @@ static int __init init_kprobes(void)
 	kprobes_initialized = (err == 0);
 
 	if (!err)
-		init_test_probes();
+		run_kprobe_tests = true;
 	return err;
 }
 subsys_initcall(init_kprobes);
 
+static int __init run_init_test_probes(void)
+{
+	if (run_kprobe_tests)
+		init_test_probes();
+	return 0;
+}
+module_init(run_init_test_probes);
+
 #ifdef CONFIG_DEBUG_FS
 static void report_probe(struct seq_file *pi, struct kprobe *p,
 		const char *sym, int offset, char *modname, struct kprobe *pp)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:02     ` Steven Rostedt
  2019-07-03 14:08       ` Catalin Marinas
@ 2019-07-09 12:30       ` Masami Hiramatsu
  2019-07-22 12:34         ` Catalin Marinas
  1 sibling, 1 reply; 32+ messages in thread
From: Masami Hiramatsu @ 2019-07-09 12:30 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton,
	Masami Hiramatsu, Catalin Marinas

Hi Steve,

On Wed, 3 Jul 2019 10:02:05 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Tue, 2 Jul 2019 17:50:09 +0100
> Mark Rutland <mark.rutland@arm.com> wrote:
> 
> > On Sun, May 26, 2019 at 03:18:40PM -0400, Steven Rostedt wrote:
> > > From: Masami Hiramatsu <mhiramat@kernel.org>
> > > 
> > > Initialize kprobes at postcore_initcall level instead of module_init
> > > since kprobes is not a module, and it depends on only subsystems
> > > initialized in core_initcall.
> > > This will allow ftrace kprobe event to add new events when it is
> > > initializing because ftrace kprobe event is initialized at
> > > later initcall level.
> > > 
> > > Link: http://lkml.kernel.org/r/155851394736.15728.13626739508905120098.stgit@devnote2
> > > 
> > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> > > ---
> > >  kernel/kprobes.c | 3 +--
> > >  1 file changed, 1 insertion(+), 2 deletions(-)
> > > 
> > > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > > index b1ea30a5540e..54aaaad00a47 100644
> > > --- a/kernel/kprobes.c
> > > +++ b/kernel/kprobes.c
> > > @@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
> > >  		init_test_probes();
> > >  	return err;
> > >  }
> > > +postcore_initcall(init_kprobes);  
> > 
> > As a heads-up, this is causing boot-time failures on arm64.
> 
> Thanks for the report.
> 
> > 
> > On arm64 kprobes depends on the BRK handler we register in
> > debug_traps_init(), which is an arch_initcall.
> > 
> > As of this change, init_krprobes() calls init_test_probes() before
> > that's registered, so we end up hitting a BRK before we can handle it.
> > 
> 
> Would something like this help?
> 
> -- Steve
> 
> diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> index 5471efbeb937..0ca6f53c8505 100644
> --- a/kernel/kprobes.c
> +++ b/kernel/kprobes.c
> @@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
>  extern unsigned long __start_kprobe_blacklist[];
>  extern unsigned long __stop_kprobe_blacklist[];
>  
> +static bool run_kprobe_tests __initdata;
> +
>  static int __init init_kprobes(void)
>  {
>  	int i, err = 0;
> @@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
>  	kprobes_initialized = (err == 0);
>  
>  	if (!err)
> -		init_test_probes();
> +		run_kprobe_tests = true;
>  	return err;
>  }
>  subsys_initcall(init_kprobes);


Just out of curious, if arm64's handler code initialized in arch_initcall,
why this subsys_initcall() function causes a problem?

This is actually related to my boot-time tracing series, so I would like
fix this issue without this patch.

Thank you,

>  
> +static int __init run_init_test_probes(void)
> +{
> +	if (run_kprobe_tests)
> +		init_test_probes();
> +}
> +module_init(run_init_test_probes);
> +
>  #ifdef CONFIG_DEBUG_FS
>  static void report_probe(struct seq_file *pi, struct kprobe *p,
>  		const char *sym, int offset, char *modname, struct kprobe *pp)
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:25           ` Steven Rostedt
  2019-07-03 14:37             ` Steven Rostedt
@ 2019-07-09 12:51             ` Masami Hiramatsu
  2019-07-09 15:18               ` Steven Rostedt
  1 sibling, 1 reply; 32+ messages in thread
From: Masami Hiramatsu @ 2019-07-09 12:51 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Catalin Marinas, Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton

On Wed, 3 Jul 2019 10:25:04 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Wed, 3 Jul 2019 10:24:02 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> > On Wed, 3 Jul 2019 15:08:32 +0100
> > Catalin Marinas <catalin.marinas@arm.com> wrote:
> > 
> > 
> > > > +static int __init run_init_test_probes(void)
> > > > +{
> > > > +	if (run_kprobe_tests)
> > > > +		init_test_probes();    
> > > 
> > > A return 0 here.  
> > 
> > Will update (would have triggered a failure on my test suite anyway ;-)
> > 
> > >   
> > > > +}
> > > > +module_init(run_init_test_probes);    
> > > 
> > > This does the trick. I prefer your fix as it leaves the arch code
> > > unchanged. In case you need it:
> > > 
> > > Tested-by: Catalin Marinas <catalin.marinas@arm.com>
> > >   
> >
> 
> Masami,
> 
> If you give me an Acked-by, I'll add it to my tree.

Sorry for late reply, but I want to keep the test running right after
initialization as the first user of kprobes at that timing, since
other user can start using kprobes right after init_kprobes().
So this issue must be fixed in moving the init_kprobes() itself
right after arch_initcall() (and that is subsys_initcall)

Catalin, Mark, could you ensure the below patch can fix your issue?

https://lore.kernel.org/lkml/20190625191545.245259106@goodmis.org/

And if so, Steve, could you push above one (which seems already in your
tree) to next as a fix?

Thank you,

-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-03 14:08       ` Catalin Marinas
  2019-07-03 14:24         ` Steven Rostedt
@ 2019-07-09 15:15         ` Steven Rostedt
  2019-07-22 12:42           ` Catalin Marinas
  1 sibling, 1 reply; 32+ messages in thread
From: Steven Rostedt @ 2019-07-09 15:15 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

On Wed, 3 Jul 2019 15:08:32 +0100
Catalin Marinas <catalin.marinas@arm.com> wrote:

 
> > -- Steve
> > 
> > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > index 5471efbeb937..0ca6f53c8505 100644
> > --- a/kernel/kprobes.c
> > +++ b/kernel/kprobes.c
> > @@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
> >  extern unsigned long __start_kprobe_blacklist[];
> >  extern unsigned long __stop_kprobe_blacklist[];
> >  
> > +static bool run_kprobe_tests __initdata;
> > +
> >  static int __init init_kprobes(void)
> >  {
> >  	int i, err = 0;
> > @@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
> >  	kprobes_initialized = (err == 0);
> >  
> >  	if (!err)
> > -		init_test_probes();
> > +		run_kprobe_tests = true;
> >  	return err;
> >  }
> >  subsys_initcall(init_kprobes);
> >  
> > +static int __init run_init_test_probes(void)
> > +{
> > +	if (run_kprobe_tests)
> > +		init_test_probes();  
> 
> A return 0 here.
> 
> > +}
> > +module_init(run_init_test_probes);  
> 
> This does the trick. I prefer your fix as it leaves the arch code
> unchanged. In case you need it:

And I actually think yours is better for the opposite reason ;-)

I agree with Masami, that the selftest actually caught a bug here. I
think the arch code may need to change as the purpose of Masami's
changes was to enable kprobes earlier in boot. The selftest failing
means that an early kprobe will fail too.

-- Steve


> 
> Tested-by: Catalin Marinas <catalin.marinas@arm.com>
> 
> Thanks.
> 


^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-09 12:51             ` Masami Hiramatsu
@ 2019-07-09 15:18               ` Steven Rostedt
  0 siblings, 0 replies; 32+ messages in thread
From: Steven Rostedt @ 2019-07-09 15:18 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Catalin Marinas, Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton

On Tue, 9 Jul 2019 21:51:24 +0900
Masami Hiramatsu <mhiramat@kernel.org> wrote:

> > Masami,
> > 
> > If you give me an Acked-by, I'll add it to my tree.  
> 
> Sorry for late reply, but I want to keep the test running right after
> initialization as the first user of kprobes at that timing, since
> other user can start using kprobes right after init_kprobes().
> So this issue must be fixed in moving the init_kprobes() itself
> right after arch_initcall() (and that is subsys_initcall)
> 
> Catalin, Mark, could you ensure the below patch can fix your issue?
> 
> https://lore.kernel.org/lkml/20190625191545.245259106@goodmis.org/
> 
> And if so, Steve, could you push above one (which seems already in your
> tree) to next as a fix?

Bah, I forgot to push. I usually do that right after I send the series.

I just pushed to my for-next branch:

  git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-trace.git

Can you see if that fixes the issue. If so, then we don't need to do
anything.

Thanks!

-- Steve

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-09 12:30       ` Masami Hiramatsu
@ 2019-07-22 12:34         ` Catalin Marinas
  0 siblings, 0 replies; 32+ messages in thread
From: Catalin Marinas @ 2019-07-22 12:34 UTC (permalink / raw)
  To: Masami Hiramatsu
  Cc: Steven Rostedt, Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton

On Tue, Jul 09, 2019 at 09:30:49PM +0900, Masami Hiramatsu wrote:
> On Wed, 3 Jul 2019 10:02:05 -0400 Steven Rostedt <rostedt@goodmis.org>
> wrote:
> > On Tue, 2 Jul 2019 17:50:09 +0100 Mark Rutland
> > <mark.rutland@arm.com> wrote:
> > > On Sun, May 26, 2019 at 03:18:40PM -0400, Steven Rostedt wrote:
> > > > Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> > > > Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org>
> > > > ---
> > > >  kernel/kprobes.c | 3 +--
> > > >  1 file changed, 1 insertion(+), 2 deletions(-)
> > > > 
> > > > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > > > index b1ea30a5540e..54aaaad00a47 100644
> > > > --- a/kernel/kprobes.c
> > > > +++ b/kernel/kprobes.c
> > > > @@ -2289,6 +2289,7 @@ static int __init init_kprobes(void)
> > > >  		init_test_probes();
> > > >  	return err;
> > > >  }
> > > > +postcore_initcall(init_kprobes);  
[...]
> > > On arm64 kprobes depends on the BRK handler we register in
> > > debug_traps_init(), which is an arch_initcall.
> > > 
> > > As of this change, init_krprobes() calls init_test_probes() before
> > > that's registered, so we end up hitting a BRK before we can handle it.
[...]
> > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > index 5471efbeb937..0ca6f53c8505 100644
> > --- a/kernel/kprobes.c
> > +++ b/kernel/kprobes.c
> > @@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
> >  extern unsigned long __start_kprobe_blacklist[];
> >  extern unsigned long __stop_kprobe_blacklist[];
> >  
> > +static bool run_kprobe_tests __initdata;
> > +
> >  static int __init init_kprobes(void)
> >  {
> >  	int i, err = 0;
> > @@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
> >  	kprobes_initialized = (err == 0);
> >  
> >  	if (!err)
> > -		init_test_probes();
> > +		run_kprobe_tests = true;
> >  	return err;
> >  }
> >  subsys_initcall(init_kprobes);
> 
> Just out of curious, if arm64's handler code initialized in arch_initcall,
> why this subsys_initcall() function causes a problem?

It doesn't but patch 12/16 in this series changes it to
postcore_initcall().

-- 
Catalin

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-09 15:15         ` Steven Rostedt
@ 2019-07-22 12:42           ` Catalin Marinas
  2019-07-22 15:00             ` Steven Rostedt
  0 siblings, 1 reply; 32+ messages in thread
From: Catalin Marinas @ 2019-07-22 12:42 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

Hi Steve,

On Tue, Jul 09, 2019 at 11:15:20AM -0400, Steven Rostedt wrote:
> On Wed, 3 Jul 2019 15:08:32 +0100
> Catalin Marinas <catalin.marinas@arm.com> wrote:
> > > diff --git a/kernel/kprobes.c b/kernel/kprobes.c
> > > index 5471efbeb937..0ca6f53c8505 100644
> > > --- a/kernel/kprobes.c
> > > +++ b/kernel/kprobes.c
> > > @@ -2235,6 +2235,8 @@ static struct notifier_block kprobe_module_nb = {
> > >  extern unsigned long __start_kprobe_blacklist[];
> > >  extern unsigned long __stop_kprobe_blacklist[];
> > >  
> > > +static bool run_kprobe_tests __initdata;
> > > +
> > >  static int __init init_kprobes(void)
> > >  {
> > >  	int i, err = 0;
> > > @@ -2286,11 +2288,18 @@ static int __init init_kprobes(void)
> > >  	kprobes_initialized = (err == 0);
> > >  
> > >  	if (!err)
> > > -		init_test_probes();
> > > +		run_kprobe_tests = true;
> > >  	return err;
> > >  }
> > >  subsys_initcall(init_kprobes);
> > >  
> > > +static int __init run_init_test_probes(void)
> > > +{
> > > +	if (run_kprobe_tests)
> > > +		init_test_probes();  
> > 
> > A return 0 here.
> > 
> > > +}
> > > +module_init(run_init_test_probes);  
> > 
> > This does the trick. I prefer your fix as it leaves the arch code
> > unchanged. In case you need it:
> 
> And I actually think yours is better for the opposite reason ;-)
> 
> I agree with Masami, that the selftest actually caught a bug here. I
> think the arch code may need to change as the purpose of Masami's
> changes was to enable kprobes earlier in boot. The selftest failing
> means that an early kprobe will fail too.

I just got back from holiday and catching up with emails. Do I still
need to merge the arm64 fix making the debug initialisation a
core_initcall()?

Can we actually get kprobes invoked before init_kprobes() has been
called?

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-22 12:42           ` Catalin Marinas
@ 2019-07-22 15:00             ` Steven Rostedt
  2019-07-22 16:01               ` Catalin Marinas
  0 siblings, 1 reply; 32+ messages in thread
From: Steven Rostedt @ 2019-07-22 15:00 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

On Mon, 22 Jul 2019 13:42:02 +0100
Catalin Marinas <catalin.marinas@arm.com> wrote:

> > I agree with Masami, that the selftest actually caught a bug here. I
> > think the arch code may need to change as the purpose of Masami's
> > changes was to enable kprobes earlier in boot. The selftest failing
> > means that an early kprobe will fail too.  
> 
> I just got back from holiday and catching up with emails. Do I still
> need to merge the arm64 fix making the debug initialisation a
> core_initcall()?
> 
> Can we actually get kprobes invoked before init_kprobes() has been
> called?

Bah, I can't remember everything that we discussed. I thought there was
some more patches that obsoleted my work around. Everything has been
pushed to Linus, can you see if the upstream still has issues for you?

Thanks!

-- Steve

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall
  2019-07-22 15:00             ` Steven Rostedt
@ 2019-07-22 16:01               ` Catalin Marinas
  0 siblings, 0 replies; 32+ messages in thread
From: Catalin Marinas @ 2019-07-22 16:01 UTC (permalink / raw)
  To: Steven Rostedt
  Cc: Mark Rutland, linux-kernel, Ingo Molnar, Andrew Morton, Masami Hiramatsu

On Mon, Jul 22, 2019 at 11:00:10AM -0400, Steven Rostedt wrote:
> On Mon, 22 Jul 2019 13:42:02 +0100
> Catalin Marinas <catalin.marinas@arm.com> wrote:
> 
> > > I agree with Masami, that the selftest actually caught a bug here. I
> > > think the arch code may need to change as the purpose of Masami's
> > > changes was to enable kprobes earlier in boot. The selftest failing
> > > means that an early kprobe will fail too.  
> > 
> > I just got back from holiday and catching up with emails. Do I still
> > need to merge the arm64 fix making the debug initialisation a
> > core_initcall()?
> > 
> > Can we actually get kprobes invoked before init_kprobes() has been
> > called?
> 
> Bah, I can't remember everything that we discussed. I thought there was
> some more patches that obsoleted my work around. Everything has been
> pushed to Linus, can you see if the upstream still has issues for you?

Upstream is fine since you reverted the postcore_initcall(init_kprobes)
change and used subsys_initcall() instead. So I don't think we need any
arch changes.

-- 
Catalin

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2019-07-22 16:01 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-26 19:18 [for-next][PATCH 00/16] tracing: Updates for the next merge window Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 01/16] ftrace: Make enable and update parameters bool when applicable Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 02/16] x86/ftrace: Make enable parameter bool where applicable Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 03/16] x86/uaccess: Allow access_ok() in irq context if pagefault_disabled Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 04/16] uaccess: Add non-pagefault user-space read functions Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 05/16] tracing/probe: Add ustring type for user-space string Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 06/16] tracing/probe: Support user-space dereference Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 07/16] selftests/ftrace: Add user-memory access syntax testcase Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 08/16] perf-probe: Add user memory access attribute support Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 09/16] tracing: Use correct function name in trace_filter_add_remove_task() comment Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 10/16] uaccess: Add a prototype of non-static __probe_user_read() Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 11/16] tracing/kprobe: Cast user-space address correctly Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 12/16] kprobes: Initialize kprobes at postcore_initcall Steven Rostedt
2019-07-02 16:50   ` Mark Rutland
2019-07-03 13:50     ` Catalin Marinas
2019-07-03 14:02     ` Steven Rostedt
2019-07-03 14:08       ` Catalin Marinas
2019-07-03 14:24         ` Steven Rostedt
2019-07-03 14:25           ` Steven Rostedt
2019-07-03 14:37             ` Steven Rostedt
2019-07-09 12:51             ` Masami Hiramatsu
2019-07-09 15:18               ` Steven Rostedt
2019-07-09 15:15         ` Steven Rostedt
2019-07-22 12:42           ` Catalin Marinas
2019-07-22 15:00             ` Steven Rostedt
2019-07-22 16:01               ` Catalin Marinas
2019-07-09 12:30       ` Masami Hiramatsu
2019-07-22 12:34         ` Catalin Marinas
2019-05-26 19:18 ` [for-next][PATCH 13/16] tracing/kprobe: Add kprobe_event= boot parameter Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 14/16] tracing: Make a separate config for trace event self tests Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 15/16] tracing/kprobe: Do not run kprobe boot tests if kprobe_event is on cmdline Steven Rostedt
2019-05-26 19:18 ` [for-next][PATCH 16/16] ftrace: Enable trampoline when rec count returns back to one Steven Rostedt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).