Linux Trace Kernel
 help / color / mirror / Atom feed
* Re: [PATCH v4 RESEND 2/7] riscv: stacktrace: disable KASAN and KCOV instrumentation for stacktrace.o
From: Shuai Xue @ 2026-07-08  8:07 UTC (permalink / raw)
  To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Alexandre Ghiti, linux-riscv, Oleg Nesterov, Steven Rostedt,
	Masami Hiramatsu, Mark Rutland, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
	Shuah Khan, oliver.yang, zhuo.song, jkchen, Marcos Paulo de Souza,
	linux-kernel, linux-trace-kernel, linux-perf-users, live-patching,
	linux-kselftest
In-Reply-To: <20260629072713.3273743-3-wanghan@linux.alibaba.com>



On 6/29/26 3:27 PM, Wang Han wrote:
> KASAN records stack traces for every alloc/free, which means it walks
> the unwinder very frequently. Instrumenting the stack trace collection
> code itself adds substantial overhead and makes the traces themselves
> noisier.
> 
> KCOV instruments every basic-block edge. The unwinder is a hot path,
> especially with KASAN enabled, so KCOV instrumentation has the same kind
> of cost and noise problem here.
> 
> Mark stacktrace.o as not KASAN- or KCOV-instrumented, matching the x86
> treatment of its stack unwinding code. RISC-V keeps the relevant unwinder
> code in stacktrace.o, so a single translation-unit annotation covers the
> equivalent scope. This is a prerequisite preference for the upcoming
> reliable unwinder, but the change is valid on its own.
> 
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
>   arch/riscv/kernel/Makefile | 6 ++++++
>   1 file changed, 6 insertions(+)
> 
> diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile
> index cabb99cadfb6..c565a72a36f3 100644
> --- a/arch/riscv/kernel/Makefile
> +++ b/arch/riscv/kernel/Makefile
> @@ -44,6 +44,12 @@ CFLAGS_REMOVE_return_address.o	= $(CC_FLAGS_FTRACE)
>   CFLAGS_REMOVE_sbi_ecall.o = $(CC_FLAGS_FTRACE)
>   endif
>   
> +# When KASAN is enabled, a stack trace is recorded for every alloc/free, which
> +# can significantly impact performance. Avoid instrumenting the stack trace
> +# collection code to minimize this impact.
> +KASAN_SANITIZE_stacktrace.o := n
> +KCOV_INSTRUMENT_stacktrace.o := n
> +
>   always-$(KBUILD_BUILTIN) += vmlinux.lds
>   
>   obj-y	+= head.o

Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>

Thanks.
Shuai

^ permalink raw reply

* Re: [PATCH v4 RESEND 1/7] riscv: stacktrace: Add frame record metadata
From: Shuai Xue @ 2026-07-08  7:59 UTC (permalink / raw)
  To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Alexandre Ghiti, linux-riscv, Oleg Nesterov, Steven Rostedt,
	Masami Hiramatsu, Mark Rutland, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
	Shuah Khan, oliver.yang, zhuo.song, jkchen, Marcos Paulo de Souza,
	linux-kernel, linux-trace-kernel, linux-perf-users, live-patching,
	linux-kselftest
In-Reply-To: <20260629072713.3273743-2-wanghan@linux.alibaba.com>



On 6/29/26 3:27 PM, Wang Han wrote:
> Reliable frame-pointer unwinding needs an explicit way to identify
> exception boundaries and the final entry frame. The existing unwinder
> infers those boundaries from return addresses, which is too loose for a
> future reliable unwinder.
> 
> Add a small metadata frame record to pt_regs and initialize it on
> exception entry, kernel stack overflow, kernel thread fork, user fork,
> and early idle task setup. The record uses a zero {fp, ra} sentinel plus
> a type field so a later unwinder can distinguish a final user-to-kernel
> boundary from a nested kernel pt_regs boundary.
> 
> This follows the arm64 metadata frame-record model, adapted to the
> RISC-V {fp, ra} frame record convention.
> 
> The metadata is established at the RISC-V entry boundaries that need an
> explicit unwind marker:
> 
>    * exception entry clears the metadata {fp, ra} pair and uses SPP
>      (or MPP in M-mode) to record whether the pt_regs frame is the final
>      user-to-kernel boundary or a nested kernel boundary;
>    * the kernel stack overflow path builds a nested pt_regs metadata
>      record on the overflow stack so an unwinder can resume from the
>      pre-overflow s0 saved in PT_S0;
>    * _start_kernel builds the init task's final metadata record, while
>      the secondary CPU path sets up s0 before smp_callin() so idle-task
>      unwinding does not inherit an undefined caller frame;
>    * copy_thread creates matching final metadata records for new kernel
>      and user tasks, and keeps s0 available for the frame-pointer chain.
> 
> Keep the embedded metadata-record field offsets distinct from the
> s0-relative STACKFRAME_* offsets used by call_on_irq_stack(), because
> the latter describe a frame record relative to s0 rather than to the
> record base.
> 
> These changes keep s0 reserved for the frame-pointer chain at task and
> exception boundaries.


Overall the patch looks good to me. One nit below:

> 
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
>   arch/riscv/include/asm/ptrace.h           |  9 ++++
>   arch/riscv/include/asm/stacktrace/frame.h | 53 +++++++++++++++++++++++
>   arch/riscv/kernel/asm-offsets.c           |  6 +++
>   arch/riscv/kernel/entry.S                 | 39 ++++++++++++++++-
>   arch/riscv/kernel/head.S                  | 23 ++++++++++
>   arch/riscv/kernel/process.c               | 33 +++++++++++++-
>   6 files changed, 159 insertions(+), 4 deletions(-)
>   create mode 100644 arch/riscv/include/asm/stacktrace/frame.h
> 
> diff --git a/arch/riscv/include/asm/ptrace.h b/arch/riscv/include/asm/ptrace.h
> index addc8188152f..4b9b0f279214 100644
> --- a/arch/riscv/include/asm/ptrace.h
> +++ b/arch/riscv/include/asm/ptrace.h
> @@ -8,6 +8,7 @@
>   
>   #include <uapi/asm/ptrace.h>
>   #include <asm/csr.h>
> +#include <asm/stacktrace/frame.h>
>   #include <linux/compiler.h>
>   
>   #ifndef __ASSEMBLER__
> @@ -53,6 +54,14 @@ struct pt_regs {
>   	unsigned long cause;
>   	/* a0 value before the syscall */
>   	unsigned long orig_a0;
> +
> +	/*
> +	 * This frame record is entirely zeroed on exception entry, allowing the
> +	 * unwinder to identify exception boundaries. The type field encodes
> +	 * whether the exception was taken from user (FINAL) or kernel (PT_REGS)
> +	 * mode.
> +	 */
> +	struct frame_record_meta stackframe;
>   };
>   
>   #define PTRACE_SYSEMU			0x1f
> diff --git a/arch/riscv/include/asm/stacktrace/frame.h b/arch/riscv/include/asm/stacktrace/frame.h
> new file mode 100644
> index 000000000000..5720a6c65fe8
> --- /dev/null
> +++ b/arch/riscv/include/asm/stacktrace/frame.h
> @@ -0,0 +1,53 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +#ifndef __ASM_RISCV_STACKTRACE_FRAME_H
> +#define __ASM_RISCV_STACKTRACE_FRAME_H
> +
> +/*
> + * See: arch/arm64/include/asm/stacktrace/frame.h for the reference
> + * implementation.
> + */
> +
> +/*
> + * - FRAME_META_TYPE_NONE
> + *
> + *   This value is reserved.
> + *
> + * - FRAME_META_TYPE_FINAL
> + *
> + *   The record is the last entry on the stack.
> + *   Unwinding should terminate successfully.
> + *
> + * - FRAME_META_TYPE_PT_REGS
> + *
> + *   The record is embedded within a struct pt_regs, recording the registers at
> + *   an arbitrary point in time.
> + *   Unwinding should consume pt_regs::epc, followed by pt_regs::ra.
> + *
> + * Note: all other values are reserved and should result in unwinding
> + * terminating with an error.
> + */
> +#define FRAME_META_TYPE_NONE		0
> +#define FRAME_META_TYPE_FINAL		1
> +#define FRAME_META_TYPE_PT_REGS		2
> +
> +#ifndef __ASSEMBLER__
> +/*
> + * A standard RISC-V frame record.
> + */
> +struct frame_record {
> +	unsigned long fp;
> +	unsigned long ra;
> +};
> +
> +/*
> + * A metadata frame record indicating a special unwind.
> + * The record::{fp,ra} fields must be zero to indicate the presence of
> + * metadata.
> + */
> +struct frame_record_meta {
> +	struct frame_record record;
> +	unsigned long type;
> +};
> +#endif /* __ASSEMBLER__ */
> +
> +#endif /* __ASM_RISCV_STACKTRACE_FRAME_H */
> diff --git a/arch/riscv/kernel/asm-offsets.c b/arch/riscv/kernel/asm-offsets.c
> index a75f0cfea1e9..bc8e8cd7130a 100644
> --- a/arch/riscv/kernel/asm-offsets.c
> +++ b/arch/riscv/kernel/asm-offsets.c
> @@ -131,6 +131,9 @@ void asm_offsets(void)
>   	OFFSET(PT_BADADDR, pt_regs, badaddr);
>   	OFFSET(PT_CAUSE, pt_regs, cause);
>   
> +	DEFINE(S_STACKFRAME,		offsetof(struct pt_regs, stackframe));
> +	DEFINE(S_STACKFRAME_TYPE,	offsetof(struct pt_regs, stackframe.type));
> +
>   	OFFSET(SUSPEND_CONTEXT_REGS, suspend_context, regs);
>   
>   	OFFSET(HIBERN_PBE_ADDR, pbe, address);
> @@ -503,6 +506,9 @@ void asm_offsets(void)
>   	DEFINE(STACKFRAME_SIZE_ON_STACK, ALIGN(sizeof(struct stackframe), STACK_ALIGN));
>   	DEFINE(STACKFRAME_FP, offsetof(struct stackframe, fp) - sizeof(struct stackframe));
>   	DEFINE(STACKFRAME_RA, offsetof(struct stackframe, ra) - sizeof(struct stackframe));
> +	DEFINE(STACKFRAME_RECORD_SIZE, sizeof(struct stackframe));

This should be sizeof(struct frame_record) rather than
sizeof(struct stackframe). STACKFRAME_RECORD_SIZE is used to skip past
the embedded frame_record_meta.record field:

     addi s0, sp, S_STACKFRAME + STACKFRAME_RECORD_SIZE

The two structs happen to be identical today, but they are independent
types serving different purposes — struct stackframe is the existing
unwinder frame record, while struct frame_record is the one embedded
in struct frame_record_meta introduced by this patch. If struct
stackframe ever gains an extra field, this offset would silently break.

With that fixed:

Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>

Thanks.
Shuai

^ permalink raw reply

* [PATCH v2 4/4] KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp
From: Vincent Donnefort @ 2026-07-08  7:54 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, rostedt
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	linux-trace-kernel, Vincent Donnefort
In-Reply-To: <20260708075435.47419-1-vdonnefort@google.com>

Create an event to allow developers to log pretty much anything into the
hypervisor tracing buffer with trace_hyp_printk(), just like the kernel
tracing has the function trace_printk().

  trace_hyp_printk("foobar");
  trace_hyp_printk("foo=%d", foo);
  trace_hyp_printk("foo=%d bar=0x%016llx", foo, bar);

To ensure writing into the tracing buffer is fast, store the string
format into a kernel-accessible ELF section. The hypervisor only has to
write into the event the string ID, which is the delta between the
hyp_string_fmt and the start of the ELF section.

The string format is parsed by the kernel. It is therefore not possible
to dereference hypervisor pointers and the format specifier %s is not
supported. Also the %p specifiers will fail to find the hypervisor
function.

To not waste tracing buffer data, use a dynamic size. Each
argument is 8 bytes and the in-kernel printing function can simply know
how many of them there are by looking at the event length.

Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>

diff --git a/arch/arm64/include/asm/kvm_hypevents.h b/arch/arm64/include/asm/kvm_hypevents.h
index 743c49bd878f..8465b523cb1d 100644
--- a/arch/arm64/include/asm/kvm_hypevents.h
+++ b/arch/arm64/include/asm/kvm_hypevents.h
@@ -57,4 +57,18 @@ HYP_EVENT(selftest,
 	),
 	RE_PRINTK("id=%llu", __entry->id)
 );
+
+/*
+ * trace_hyp_printk() has too many specificities to be declared with HYP_EVENT().
+ * However, we can use a REMOTE_EVENT macro to automatically do the declaration
+ * for the kernel side.
+ */
+REMOTE_EVENT_CUSTOM_PRINTK(hyp_printk,
+	0, /* id will be overwritten during hyp event init */
+	RE_STRUCT(
+		re_field(u16, fmt_id)
+		re_field(u64, args[])
+	),
+	__hyp_trace_printk(evt, seq)
+);
 #endif
diff --git a/arch/arm64/include/asm/kvm_hyptrace.h b/arch/arm64/include/asm/kvm_hyptrace.h
index de133b735f72..46097105fdd8 100644
--- a/arch/arm64/include/asm/kvm_hyptrace.h
+++ b/arch/arm64/include/asm/kvm_hyptrace.h
@@ -23,4 +23,12 @@ extern struct remote_event __hyp_events_end[];
 extern struct hyp_event_id __hyp_event_ids_start[];
 extern struct hyp_event_id __hyp_event_ids_end[];
 
+#define HYP_STRING_FMT_MAX_SIZE 128
+
+struct hyp_string_fmt {
+	const char	fmt[HYP_STRING_FMT_MAX_SIZE];
+};
+
+extern struct hyp_string_fmt __hyp_string_fmts_start[];
+extern struct hyp_string_fmt __hyp_string_fmts_end[];
 #endif
diff --git a/arch/arm64/kernel/image-vars.h b/arch/arm64/kernel/image-vars.h
index d4c7d45ae6bc..ec03621d7a81 100644
--- a/arch/arm64/kernel/image-vars.h
+++ b/arch/arm64/kernel/image-vars.h
@@ -141,6 +141,7 @@ KVM_NVHE_ALIAS(__hyp_rodata_end);
 #ifdef CONFIG_NVHE_EL2_TRACING
 KVM_NVHE_ALIAS(__hyp_event_ids_start);
 KVM_NVHE_ALIAS(__hyp_event_ids_end);
+KVM_NVHE_ALIAS(__hyp_string_fmts_start);
 #endif
 
 /* pKVM static key */
diff --git a/arch/arm64/kernel/vmlinux.lds.S b/arch/arm64/kernel/vmlinux.lds.S
index af1d72020976..7f9b6c7dfe70 100644
--- a/arch/arm64/kernel/vmlinux.lds.S
+++ b/arch/arm64/kernel/vmlinux.lds.S
@@ -324,6 +324,10 @@ SECTIONS
 		__hyp_events_start = .;
 		*(SORT(_hyp_events.*))
 		__hyp_events_end = .;
+
+		__hyp_string_fmts_start = .;
+		*(_hyp_string_fmts)
+		__hyp_string_fmts_end = .;
 	}
 #endif
 	/*
diff --git a/arch/arm64/kvm/hyp/include/nvhe/define_events.h b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
index 776d4c6cb702..370e8c2d39fe 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/define_events.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/define_events.h
@@ -10,5 +10,3 @@
 #define HYP_EVENT_MULTI_READ
 #include <asm/kvm_hypevents.h>
 #undef HYP_EVENT_MULTI_READ
-
-#undef HYP_EVENT
diff --git a/arch/arm64/kvm/hyp/include/nvhe/trace.h b/arch/arm64/kvm/hyp/include/nvhe/trace.h
index 8813ff250f8e..3d0b5c634bb3 100644
--- a/arch/arm64/kvm/hyp/include/nvhe/trace.h
+++ b/arch/arm64/kvm/hyp/include/nvhe/trace.h
@@ -46,6 +46,69 @@ static inline pid_t __tracing_get_vcpu_pid(struct kvm_cpu_context *host_ctxt)
 void *tracing_reserve_entry(unsigned long length);
 void tracing_commit_entry(void);
 
+/*
+ * The trace_hyp_printk boilerplate is too fiddly to be declared with
+ * HYP_EVENT():
+ *
+ * The string format is stored into a kernel-accessible ELF section. The
+ * hypervisor only writes the format ID.
+ *
+ * The function has a variadic prototype. We have no easy way to know each
+ * argument width so they must all cast to u64.
+ */
+#define REMOTE_EVENT_CUSTOM_PRINTK(...)
+
+#define __TO_U64_0()
+#define __TO_U64_1(x)			, (u64)(x)
+#define __TO_U64_2(x, ...)		, (u64)(x) __TO_U64_1(__VA_ARGS__)
+#define __TO_U64_3(x, ...)		, (u64)(x) __TO_U64_2(__VA_ARGS__)
+#define __TO_U64_4(x, ...)		, (u64)(x) __TO_U64_3(__VA_ARGS__)
+#define __TO_U64_5(x, ...)		, (u64)(x) __TO_U64_4(__VA_ARGS__)
+#define __TO_U64_6(x, ...)		, (u64)(x) __TO_U64_5(__VA_ARGS__)
+#define __TO_U64_7(x, ...)		, (u64)(x) __TO_U64_6(__VA_ARGS__)
+#define __TO_U64_8(x, ...)		, (u64)(x) __TO_U64_7(__VA_ARGS__)
+
+#define __TO_U64_X(N, ...)		CONCATENATE(__TO_U64_, N)(__VA_ARGS__)
+#define __TO_U64(...)			__TO_U64_X(COUNT_ARGS(__VA_ARGS__), ##__VA_ARGS__)
+
+REMOTE_EVENT_FORMAT(hyp_printk, HE_STRUCT(he_field(u16, fmt_id) he_field(u64, args[])));
+extern struct hyp_event_id hyp_event_id_hyp_printk;
+
+static __always_inline void __trace_hyp_printk(struct hyp_string_fmt *fmt, int nr_args, ...)
+{
+	struct remote_event_format_hyp_printk *entry;
+	va_list va;
+	int i;
+
+	if (!atomic_read(&hyp_event_id_hyp_printk.enabled))
+		return;
+
+	entry = tracing_reserve_entry(struct_size(entry, args, nr_args));
+	if (!entry)
+		return;
+
+	entry->hdr.id = hyp_event_id_hyp_printk.id;
+	entry->fmt_id = fmt - __hyp_string_fmts_start;
+
+	va_start(va, nr_args);
+	for (i = 0; i < nr_args; i++)
+		entry->args[i] = va_arg(va, u64);
+	va_end(va);
+
+	tracing_commit_entry();
+}
+
+
+#define trace_hyp_printk(__fmt, __args...)						\
+do {											\
+	static struct hyp_string_fmt __used __section("_hyp_string_fmts") fmt = {	\
+		.fmt = __fmt								\
+	};										\
+	BUILD_BUG_ON(sizeof(__fmt) > HYP_STRING_FMT_MAX_SIZE);				\
+	/* __TO_U64 prepends a comma if there are arguments */				\
+	__trace_hyp_printk(&fmt, COUNT_ARGS(__args) __TO_U64(__args));			\
+} while (0)
+
 int __tracing_load(unsigned long desc_va, size_t desc_size);
 void __tracing_unload(void);
 int __tracing_enable(bool enable);
@@ -58,6 +121,8 @@ static inline void *tracing_reserve_entry(unsigned long length) { return NULL; }
 static inline void tracing_commit_entry(void) { }
 #define HYP_EVENT(__name, __proto, __struct, __assign, __printk)      \
 	static inline void trace_##__name(__proto) {}
+#define REMOTE_EVENT_CUSTOM_PRINTK(...)
+#define trace_hyp_printk(fmt, args...) do { } while (0)
 
 static inline int __tracing_load(unsigned long desc_va, size_t desc_size) { return -ENODEV; }
 static inline void __tracing_unload(void) { }
diff --git a/arch/arm64/kvm/hyp/nvhe/events.c b/arch/arm64/kvm/hyp/nvhe/events.c
index add9383aadb5..12223d2e3618 100644
--- a/arch/arm64/kvm/hyp/nvhe/events.c
+++ b/arch/arm64/kvm/hyp/nvhe/events.c
@@ -9,6 +9,12 @@
 
 #include <nvhe/define_events.h>
 
+/*
+ * The hyp_printk event is not declared with HYP_EVENT in kvm_hypevents.h,
+ * so we manually add the boilerplate here.
+ */
+HYP_EVENT(hyp_printk, 0, 0, 0, 0);
+
 int __tracing_enable_event(unsigned short id, bool enable)
 {
 	struct hyp_event_id *event_id = &__hyp_event_ids_start[id];
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index 0c7349fe006a..f39a2451c1bc 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -391,6 +391,9 @@ static struct trace_remote_callbacks trace_remote_callbacks = {
 
 static const char *__hyp_enter_exit_reason_str(u8 reason);
 
+struct remote_event_format_hyp_printk;
+static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq);
+
 #include "define_hypevents.h"
 
 static const char *__hyp_enter_exit_reason_str(u8 reason)
@@ -409,6 +412,61 @@ static const char *__hyp_enter_exit_reason_str(u8 reason)
 	return strs[min(reason, HYP_REASON_UNKNOWN)];
 }
 
+static void __hyp_trace_printk(struct remote_event_format_hyp_printk *entry, struct trace_seq *seq)
+{
+	const char *fmt = (const char *)(&__hyp_string_fmts_start[entry->fmt_id]);
+	struct ring_buffer_event *evt = (void *)entry - RB_EVNT_HDR_SIZE;
+	int nr_args;
+
+	trace_seq_putc(seq, ' ');
+
+	if ((void *)fmt >= (void *)__hyp_string_fmts_end) {
+		trace_seq_printf(seq, "Unknown hyp_string_fmt ID %d\n", entry->fmt_id);
+		return;
+	}
+
+	nr_args = (ring_buffer_event_length(evt) -
+		   offsetof(struct remote_event_format_hyp_printk, args)) / sizeof(entry->args[0]);
+	switch (nr_args) {
+	case 0:
+		trace_seq_printf(seq, fmt);
+		break;
+	case 1:
+		trace_seq_printf(seq, fmt, entry->args[0]);
+		break;
+	case 2:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1]);
+		break;
+	case 3:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2]);
+		break;
+	case 4:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+				 entry->args[3]);
+		break;
+	case 5:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+				 entry->args[3], entry->args[4]);
+		break;
+	case 6:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+				 entry->args[3], entry->args[4], entry->args[5]);
+		break;
+	case 7:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1], entry->args[2],
+				 entry->args[3], entry->args[4], entry->args[5], entry->args[6]);
+		break;
+	default:
+		trace_seq_printf(seq, fmt, entry->args[0], entry->args[1],
+				 entry->args[2], entry->args[3], entry->args[4], entry->args[5],
+				 entry->args[6], entry->args[7]);
+		break;
+	}
+
+	if (seq->buffer[trace_seq_used(seq) - 1] != '\n')
+		trace_seq_putc(seq, '\n');
+}
+
 static void __init hyp_trace_init_events(void)
 {
 	struct hyp_event_id *hyp_event_id = __hyp_event_ids_start;
@@ -418,6 +476,9 @@ static void __init hyp_trace_init_events(void)
 	/* Events on both sides hypervisor are sorted */
 	for (; event < __hyp_events_end; event++, hyp_event_id++, id++)
 		event->id = hyp_event_id->id = id;
+
+	WARN(__hyp_string_fmts_end - __hyp_string_fmts_start > U16_MAX + 1,
+	     "Too many trace_hyp_printk() callsites\n");
 }
 
 int __init kvm_hyp_trace_init(void)
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply related

* [PATCH v2 3/4] tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
From: Vincent Donnefort @ 2026-07-08  7:54 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, rostedt
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	linux-trace-kernel, Vincent Donnefort
In-Reply-To: <20260708075435.47419-1-vdonnefort@google.com>

The current REMOTE_EVENT() takes as a __printk argument a string format
and a list of arguments, such as RE_STRUCT("foo=%d bar=%d", foo, bar).
Add a REMOTE_EVENT_CUSTOM_PRINTK() where the __printk argument can be a
function. This intends to support the creation of a "printk" event for
the arm64 nVHE/pKVM hypervisor with a dynamic prototype and by extension
a dynamic print format.

Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>

diff --git a/include/trace/define_remote_events.h b/include/trace/define_remote_events.h
index 676e803dc144..4f4d58e37b84 100644
--- a/include/trace/define_remote_events.h
+++ b/include/trace/define_remote_events.h
@@ -35,17 +35,26 @@ do {											\
 
 #define RE_PRINTK(__args...) __args
 
-#define REMOTE_EVENT(__name, __id, __struct, __printk)					\
-	REMOTE_EVENT_FORMAT(__name, __struct);						\
+#define REMOTE_EVENT_PRINT_FUNC(__name, __printk)					\
 	static void remote_event_print_##__name(void *evt, struct trace_seq *seq)	\
 	{										\
 		struct remote_event_format_##__name __maybe_unused *__entry = evt;	\
 		trace_seq_puts(seq, #__name);						\
-		remote_printk(__printk);						\
+		__printk;								\
 	}
+
+#define REMOTE_EVENT(__name, __id, __struct, __printk)					\
+	REMOTE_EVENT_FORMAT(__name, __struct);						\
+	REMOTE_EVENT_PRINT_FUNC(__name, remote_printk(__printk))
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk)			\
+	REMOTE_EVENT_FORMAT(__name, __struct);						\
+	REMOTE_EVENT_PRINT_FUNC(__name, __printk)
+
 #include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
 
 #undef REMOTE_EVENT
+#undef REMOTE_EVENT_CUSTOM_PRINTK
 #undef RE_PRINTK
 #undef re_field
 #define re_field(__type, __field)							\
@@ -70,4 +79,8 @@ do {											\
 		.print_fmt	= remote_event_print_fmt_##__name,			\
 		.print		= remote_event_print_##__name,				\
 	}
+
+#define REMOTE_EVENT_CUSTOM_PRINTK(__name, __id, __struct, __printk)			\
+	REMOTE_EVENT(__name, __id, RE_STRUCT(__struct), "Unknown")
+
 #include REMOTE_EVENT_INCLUDE(REMOTE_EVENT_INCLUDE_FILE)
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply related

* [PATCH v2 2/4] KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
From: Vincent Donnefort @ 2026-07-08  7:54 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, rostedt
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	linux-trace-kernel, Vincent Donnefort
In-Reply-To: <20260708075435.47419-1-vdonnefort@google.com>

kvm_define_hypevents.h is used to define the kernel-side structures for
hypervisor events. It doesn't need to be used anywhere else than in
hyp_trace.c.

Rename and move it to arch/arm64/kvm/

Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>

diff --git a/arch/arm64/include/asm/kvm_define_hypevents.h b/arch/arm64/kvm/define_hypevents.h
similarity index 100%
rename from arch/arm64/include/asm/kvm_define_hypevents.h
rename to arch/arm64/kvm/define_hypevents.h
diff --git a/arch/arm64/kvm/hyp_trace.c b/arch/arm64/kvm/hyp_trace.c
index 2411b4c32932..0c7349fe006a 100644
--- a/arch/arm64/kvm/hyp_trace.c
+++ b/arch/arm64/kvm/hyp_trace.c
@@ -391,7 +391,7 @@ static struct trace_remote_callbacks trace_remote_callbacks = {
 
 static const char *__hyp_enter_exit_reason_str(u8 reason);
 
-#include <asm/kvm_define_hypevents.h>
+#include "define_hypevents.h"
 
 static const char *__hyp_enter_exit_reason_str(u8 reason)
 {
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply related

* [PATCH v2 0/4] trace_hyp_printk() for pKVM/nVHE hypervisor
From: Vincent Donnefort @ 2026-07-08  7:54 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, rostedt
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	linux-trace-kernel, Vincent Donnefort

Hi all,

This series adds a hypervisor event "hyp_printk" which enables
developers to log pretty much anything into the hypervisor tracing
buffer, just like the kernel function trace_printk().

This enables rich logging from the hypervisor, while leaving all the
string parsing burden to the kernel. This has been the main way of
debugging pKVM in Android.

Even though not strictly related to trace_hyp_printk, I have added the
following two patches:

  * KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp

    This one mainly intends to support one of the new features I have
    posted here [1], which allows to enable tracing as early as
    possible. I have added it here to limit cross-posting.

  * KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/

    This one is just a cleanup.

[1] https://lore.kernel.org/all/20260605163825.1762953-1-vdonnefort@google.com/

Changelog:

v2:
  - Collect Fuad's tags
  - Rebase on 7.2-rc2
  - Warn when trace_hyp_printk callsites are exhausted (Fuad)

v1 (https://lore.kernel.org/all/20260612142245.1015744-1-vdonnefort@google.com/)

Vincent Donnefort (4):
  KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
  KVM: arm64: Move kvm_define_hypevents.h to arch/arm64/kvm/
  tracing/remotes: Add REMOTE_EVENT_CUSTOM_PRINTK() helper
  KVM: arm64: Add hyp_printk event to nVHE/pKVM hyp

 arch/arm64/include/asm/kvm_asm.h              |  4 +-
 arch/arm64/include/asm/kvm_hypevents.h        | 14 ++++
 arch/arm64/include/asm/kvm_hyptrace.h         |  8 +++
 arch/arm64/kernel/image-vars.h                |  1 +
 arch/arm64/kernel/vmlinux.lds.S               |  4 ++
 .../define_hypevents.h}                       |  0
 .../kvm/hyp/include/nvhe/define_events.h      |  2 -
 arch/arm64/kvm/hyp/include/nvhe/trace.h       | 65 +++++++++++++++++++
 arch/arm64/kvm/hyp/nvhe/events.c              |  6 ++
 arch/arm64/kvm/hyp/nvhe/hyp-main.c            |  2 +-
 arch/arm64/kvm/hyp_trace.c                    | 63 +++++++++++++++++-
 include/trace/define_remote_events.h          | 19 +++++-
 12 files changed, 179 insertions(+), 9 deletions(-)
 rename arch/arm64/{include/asm/kvm_define_hypevents.h => kvm/define_hypevents.h} (100%)


base-commit: 8cdeaa50eae8dad34885515f62559ee83e7e8dda
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply

* [PATCH v2 1/4] KVM: arm64: Allow early calls to pKVM host_share/unshare_hyp
From: Vincent Donnefort @ 2026-07-08  7:54 UTC (permalink / raw)
  To: maz, oliver.upton, joey.gouly, suzuki.poulose, yuzenghui,
	catalin.marinas, will, rostedt
  Cc: linux-arm-kernel, kvmarm, kernel-team, qperret, tabba,
	linux-trace-kernel, Vincent Donnefort
In-Reply-To: <20260708075435.47419-1-vdonnefort@google.com>

The hypervisor tracing for pKVM relies on the __pkvm_host_share_hyp and
__pkvm_host_unshare_hyp HVCs. In order to start tracing as early as
possible, allow those two HVCs before the host is deprivileged.

Reviewed-by: Fuad Tabba <tabba@google.com>
Tested-by: Fuad Tabba <tabba@google.com>
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>

diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h
index 043495f7fc78..fb049c40d04f 100644
--- a/arch/arm64/include/asm/kvm_asm.h
+++ b/arch/arm64/include/asm/kvm_asm.h
@@ -89,12 +89,12 @@ enum __kvm_host_smccc_func {
 	__KVM_HOST_SMCCC_FUNC___vgic_v3_restore_vmcr_aprs,
 	__KVM_HOST_SMCCC_FUNC___vgic_v5_save_apr,
 	__KVM_HOST_SMCCC_FUNC___vgic_v5_restore_vmcr_apr,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
+	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 
 	MARKER(__KVM_HOST_SMCCC_FUNC_PKVM_ONLY),
 
 	/* Hypercalls that are available only when pKVM has finalised. */
-	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_hyp,
-	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_hyp,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_donate_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_share_guest,
 	__KVM_HOST_SMCCC_FUNC___pkvm_host_unshare_guest,
diff --git a/arch/arm64/kvm/hyp/nvhe/hyp-main.c b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
index d3c69de698f4..361dbfe2e832 100644
--- a/arch/arm64/kvm/hyp/nvhe/hyp-main.c
+++ b/arch/arm64/kvm/hyp/nvhe/hyp-main.c
@@ -740,9 +740,9 @@ static const hcall_t host_hcall[] = {
 	HANDLE_FUNC(__vgic_v3_restore_vmcr_aprs),
 	HANDLE_FUNC(__vgic_v5_save_apr),
 	HANDLE_FUNC(__vgic_v5_restore_vmcr_apr),
-
 	HANDLE_FUNC(__pkvm_host_share_hyp),
 	HANDLE_FUNC(__pkvm_host_unshare_hyp),
+
 	HANDLE_FUNC(__pkvm_host_donate_guest),
 	HANDLE_FUNC(__pkvm_host_share_guest),
 	HANDLE_FUNC(__pkvm_host_unshare_guest),
-- 
2.55.0.795.g602f6c329a-goog


^ permalink raw reply related

* Re: [RFC 1/3] arm64: kprobes: Do not handle non-XOL faults as kprobe faults
From: Masami Hiramatsu @ 2026-07-08  7:42 UTC (permalink / raw)
  To: Hongyan Xia
  Cc: Pu Hu, ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <8cc07468-804e-4ee1-acad-77bc99af74c6@transsion.com>

On Wed, 8 Jul 2026 05:57:24 +0000
Hongyan Xia <hongyan.xia@transsion.com> wrote:

> Hi Masami,
> 
> On 7/8/2026 8:46 AM, Masami Hiramatsu wrote:
> > On Mon, 6 Jul 2026 08:36:48 +0000
> > Pu Hu <hupu@transsion.com> wrote:
> >
> >> From: Pu Hu <hupu@transsion.com>
> >>
> >> kprobe_fault_handler() handles faults taken while kprobes is in
> >> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the
> >> single-stepped instruction.
> >>
> >> That assumption is not always true. While a kprobe is preparing or
> >> executing the out-of-line single-step instruction, other code may run
> >> in that window. For example, perf or trace code can be invoked from the
> >> debug exception path and may take a fault of its own. In that case the
> >> fault did not happen on the kprobe XOL instruction, but the kprobe fault
> >> handler may still try to recover it as a kprobe single-step fault.
> >>
> >> This can corrupt the exception recovery flow and leave the real fault to
> >> be handled with a wrong PC. A typical reproducer is running simpleperf
> >> with preemptirq tracepoints and dwarf callchains while a kprobe is
> >> installed on a frequently executed kernel function.
> >>
> >> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when
> >> the faulting PC points at the current kprobe's XOL instruction. Faults
> >> from any other PC are left to the normal fault handling path.
> >>
> >> This follows the same idea as the x86 fix in commit 6381c24cd6d5
> >> ("kprobes/x86: Fix page-fault handling logic").
> >>
> >> Signed-off-by: Pu Hu <hupu@transsion.com>
> >> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
> >> ---
> >>   arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++
> >>   1 file changed, 14 insertions(+)
> >>
> >> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> >> index 43a0361a8bf0..e4d2852ce2fb 100644
> >> --- a/arch/arm64/kernel/probes/kprobes.c
> >> +++ b/arch/arm64/kernel/probes/kprobes.c
> >> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
> >>        switch (kcb->kprobe_status) {
> >>        case KPROBE_HIT_SS:
> >>        case KPROBE_REENTER:
> >> +             /*
> >> +              * A fault taken while a kprobe is single-stepping is not
> >> +              * necessarily caused by the instruction in the XOL slot. For
> >> +              * example, tracing or perf code running in this window may take
> >> +              * an unrelated fault.
> >> +              *
> >> +              * Handle the fault here only when the faulting PC is the XOL
> >> +              * instruction of the current kprobe. Otherwise let the normal
> >> +              * fault handling path deal with it.
> >> +              */
> >> +             if (cur->ainsn.xol_insn &&
> >> +                     instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
> >> +                     break;
> >
> > Can you check Sashiko's comments[1]?
> >
> > [1] https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1
> >
> > It seems that it complains about simulated kprobe's case.
> > In that case, cur->ainsn.xol_insn == NULL. The simulation should be done
> > in the kprobe context (which is a debug trap). I'm not sure the arm64
> > can cause NMI in that context, but if it happens and causes a fault,
> > it may cause a problem.
> >
> > So I think we can just ignore the fault on the simulated kprobes.
> >
> > To ensure that, you can just add:
> >
> >          if (cur && !cur->ainsn.xol_insn)
> >                  return 0;
> >
> > at the entry of this function. (and remove redundant cur->ainsn.xol_insn check)
> 
> Right, both cases:
> 
> 1. single-step XOL
> 2. simulated
> 
> have this problem and this patch fixed 1. 2 remains unchanged.
> 
> Ideally we should fix both, but the simulated case seems more
> complicated, and at least we didn't make things worse for 2. So I wonder
> if we can analyze 2 more thoroughly and fix it in a separate patch.

OK, but basically this fault handler is only for the SS XOL,
not for simulated one (as same as x86). So just skip the
simulated case is enough in this patch.
(Note that x86 also have simulated path, and that is not handled
by the fault handler)

Thank you,


> 
> > Thank you,
> >
> >> +
> >>                /*
> >>                 * We are here because the instruction being single
> >>                 * stepped caused a page fault. We reset the current
> >> --
> >> 2.43.0
> >>
> > --
> > Masami Hiramatsu (Google) <mhiramat@kernel.org>
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [RFC 2/3] arm64: kprobes: Allow reentering kprobes while single-stepping
From: Hongyan Xia @ 2026-07-08  7:12 UTC (permalink / raw)
  To: Masami Hiramatsu (Google), Pu Hu
  Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260708095400.7582bc9589fd9da925aa9c1d@kernel.org>

On 7/8/2026 8:54 AM, Masami Hiramatsu wrote:
> On Mon, 6 Jul 2026 08:36:49 +0000
> Pu Hu <hupu@transsion.com> wrote:
>
>> From: Pu Hu <hupu@transsion.com>
>>
>> A kprobe can be hit while another kprobe is in KPROBE_HIT_SS state. This
>> can happen when tracing or perf code runs from the debug exception path
>> while the first kprobe is preparing or executing its out-of-line
>> single-step instruction.
>>
>> Currently arm64 treats a kprobe hit in KPROBE_HIT_SS as unrecoverable,
>> the same as a hit in KPROBE_REENTER. This is too strict. A hit in
>> KPROBE_HIT_SS is still a one-level reentry and can be handled by saving
>> the current kprobe state and setting up single-step for the new probe,
>> just like reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
>>
>> The truly unrecoverable case is hitting another kprobe while already in
>> KPROBE_REENTER, because the reentry save area has already been consumed.
>>
>> Move KPROBE_HIT_SS to the recoverable reentry cases and leave
>> KPROBE_REENTER as the unrecoverable nested reentry case.
>>
>> This mirrors the x86 fix in commit 6a5022a56ac3
>> ("kprobes/x86: Allow to handle reentered kprobe on single-stepping").
>
> Can you also check the Sashiko comment?
>
> https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=2
>
> This seems indicating potentially brakage of reenter kprobes on arm64.
> But is it possible to hit another kprobe while SS on arm64? It is
> the same question about the previous one, can NMI happens during
> the single stepping? (maybe yes, because it is non-maskable)

It is possible as this is what we hit. There are
preempt_enable/disable() calls during SS which can trigger perf events
sampling the user stack, which may then trigger page faults and send the
CPU into one more level of exception context. I believe this is what you
saw in 6a5022a56ac3?
> Anyway, for making it safer, we need to add saved_irqflags to prev_kprobe.

Yes, this seems to be a legit bug that needs to be fixed. Thank you.

> Thank you,
>
>>
>> Signed-off-by: Pu Hu <hupu@transsion.com>
>> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
>> ---
>>   arch/arm64/kernel/probes/kprobes.c | 8 +++++++-
>>   1 file changed, 7 insertions(+), 1 deletion(-)
>>
>> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
>> index e4d2852ce2fb..764b2228cca0 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -240,10 +240,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
>>        switch (kcb->kprobe_status) {
>>        case KPROBE_HIT_SSDONE:
>>        case KPROBE_HIT_ACTIVE:
>> +     case KPROBE_HIT_SS:
>> +             /*
>> +              * A probe can be hit while another kprobe is preparing or
>> +              * executing its XOL single-step instruction. This is still a
>> +              * recoverable one-level reentry, so handle it in the same way as
>> +              * reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
>> +              */
>>                kprobes_inc_nmissed_count(p);
>>                setup_singlestep(p, regs, kcb, 1);
>>                break;
>> -     case KPROBE_HIT_SS:
>>        case KPROBE_REENTER:
>>                pr_warn("Failed to recover from reentered kprobes.\n");
>>                dump_kprobe(p);
>> --
>> 2.43.0
>>
>
>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>


^ permalink raw reply

* Re: [PATCH v4 RESEND 4/7] riscv: stacktrace: introduce stack-bound tracking helpers
From: Shuai Xue @ 2026-07-08  6:59 UTC (permalink / raw)
  To: Wang Han, Paul Walmsley, Palmer Dabbelt, Albert Ou
  Cc: Alexandre Ghiti, linux-riscv, Oleg Nesterov, Steven Rostedt,
	Masami Hiramatsu, Mark Rutland, Peter Zijlstra, Ingo Molnar,
	Arnaldo Carvalho de Melo, Namhyung Kim, Alexander Shishkin,
	Jiri Olsa, Ian Rogers, Adrian Hunter, James Clark, Josh Poimboeuf,
	Jiri Kosina, Miroslav Benes, Petr Mladek, Joe Lawrence,
	Shuah Khan, oliver.yang, zhuo.song, jkchen, Marcos Paulo de Souza,
	linux-kernel, linux-trace-kernel, linux-perf-users, live-patching,
	linux-kselftest
In-Reply-To: <20260629072713.3273743-5-wanghan@linux.alibaba.com>



On 6/29/26 3:27 PM, Wang Han wrote:
> A reliable unwinder needs to validate that every frame record it reads
> is fully contained in a known kernel stack, and it needs to refuse to
> walk back into a stack it has already left. Add the building blocks
> for that:
> 
>    * struct stack_info / struct unwind_state in a new
>      asm/stacktrace/common.h, modelled on the arm64 reference
>      implementation.
>    * stackinfo_get_irq() / stackinfo_get_task() / stackinfo_get_overflow()
>      plus the corresponding on_*_stack() predicates in asm/stacktrace.h,
>      so callers can ask "is this object on stack X?" by stack kind
>      rather than open-coded address arithmetic.
>    * unwind_init_common(), unwind_find_stack() and
>      unwind_consume_stack() helpers that enforce the
>      forward-progress-only invariant required for reliability.
> 
> No existing user is wired up to these helpers in this commit; the
> unwinder switch comes in a follow-up. The header changes leave
> on_thread_stack() with the same semantics as before, just expressed in
> terms of the new helpers.
> 
> Reviewed-by: Shuai Xue <xueshuai@linux.alibaba.com>
> Signed-off-by: Wang Han <wanghan@linux.alibaba.com>
> ---
>   arch/riscv/include/asm/stacktrace.h        |  65 ++++++++-
>   arch/riscv/include/asm/stacktrace/common.h | 159 +++++++++++++++++++++
>   2 files changed, 222 insertions(+), 2 deletions(-)
>   create mode 100644 arch/riscv/include/asm/stacktrace/common.h
> 
> diff --git a/arch/riscv/include/asm/stacktrace.h b/arch/riscv/include/asm/stacktrace.h
> index b1495a7e06ce..bc87c4940379 100644
> --- a/arch/riscv/include/asm/stacktrace.h
> +++ b/arch/riscv/include/asm/stacktrace.h
> @@ -3,8 +3,13 @@
>   #ifndef _ASM_RISCV_STACKTRACE_H
>   #define _ASM_RISCV_STACKTRACE_H
>   
> +#include <linux/percpu.h>
>   #include <linux/sched.h>
> +#include <linux/sched/task_stack.h>
> +
> +#include <asm/irq_stack.h>
>   #include <asm/ptrace.h>
> +#include <asm/stacktrace/common.h>
>   
>   struct stackframe {
>   	unsigned long fp;
> @@ -16,14 +21,70 @@ extern void notrace walk_stackframe(struct task_struct *task, struct pt_regs *re
>   extern void dump_backtrace(struct pt_regs *regs, struct task_struct *task,
>   			   const char *loglvl);
>   
> -static inline bool on_thread_stack(void)
> +/*
> + * IRQ stack accessors
> + */
> +static inline struct stack_info stackinfo_get_irq(void)
> +{
> +	unsigned long low = (unsigned long)raw_cpu_read(irq_stack_ptr);

 From https://sashiko.dev/#/patchset/20260629072713.3273743-1-wanghan%40linux.alibaba.com

Will this cause a link error when CONFIG_IRQ_STACKS is disabled?
Looking at arch/riscv/kernel/irq.c, irq_stack_ptr is defined inside an
#ifdef CONFIG_IRQ_STACKS block. Since stackinfo_get_irq() unconditionally
references it here, it seems this might result in an undefined reference
to irq_stack_ptr during linking.

Should this accessor be conditionally compiled, or should it provide a
fallback when CONFIG_IRQ_STACKS is not set?

Thanks.
Shuai

^ permalink raw reply

* Reserving memory on ACPI systems (was: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal())
From: Mike Rapoport @ 2026-07-08  6:36 UTC (permalink / raw)
  To: Will Deacon
  Cc: Thierry Reding, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Hunter, David Airlie, Simona Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Sowjanya Komatineni,
	Luca Ceresoli, Mikko Perttunen, Yury Norov, Rasmus Villemoes,
	Russell King, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
	Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Marek Szyprowski, Robin Murphy, Sumit Semwal,
	Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
	Christian König, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, Catalin Marinas, Thierry Reding, devicetree,
	linux-tegra, linux-kernel, dri-devel, linux-media,
	linux-arm-kernel, linux-s390, linux-mm, iommu, linaro-mm-sig,
	linux-trace-kernel, Thierry Reding, Chun Ng, Shyam Saini
In-Reply-To: <akftuw9NyRy36fXA@willie-the-truck>

On Fri, Jul 03, 2026 at 06:13:31PM +0100, Will Deacon wrote:
> On Thu, Jul 02, 2026 at 06:41:23PM +0200, Thierry Reding wrote:
> > On Thu, Jul 02, 2026 at 03:46:44PM +0200, Thierry Reding wrote:
> > > On Thu, Jul 02, 2026 at 10:18:47AM +0100, Will Deacon wrote:
> > > > On Wed, Jul 01, 2026 at 06:08:15PM +0200, Thierry Reding wrote:
> > > > > From: Chun Ng <chunn@nvidia.com>
> > > > > 
> > > > > Add helpers to swap PROT_NORMAL and PROT_DEVICE_nGnRnE protection bits
> > > > > on a kernel-linear-map range.
> > > > 
> > > > That sounds like a really terrible idea. Why is this necessary and how
> > > > does it interact with things like load_unaligned_zeropad()?
> > > 
> > > This is necessary because once the memory controller has walled off the
> > > new memory region the CPU must not access it under any circumstances or
> > > it'll cause the CPU to lock up (I think technically it'll hit an SError
> > > but in practice that just means it'll freeze, as far as I can tell).
> > > 
> > > Probably doesn't interact well at all with load_unaligned_zeropad().
> > > 
> > > > I think you should unmap the memory from the linear map and memremap()
> > > > it instead.
> > > 
> > > Given that the memory can never be accessed by the CPU after the memory
> > > controller locks it down, I don't think we'll even need memremap(). The
> > > only thing we really need is the sg_table we hand out via the DMA BUFs
> > > so that they can be used by device drivers to program their DMA engines
> > > internally.
> > > 
> > > Looking through some of the architecture code around this, shouldn't we
> > > simply be using set_memory_encrypted() and set_memory_decrypted() for
> > > this? While they might've been created for slightly other use-cases,
> > > they seem to be doing exactly what we want (i.e. remove the page range
> > > from the linear mapping and flushing it, or restoring the valid bit and
> > > standard permissions, respectively).
> > 
> > Ah... I guess we can't do it because we're not in a realm world and so
> > the early checks in __set_memory_enc_dec() would return early and turn
> > it into a no-op.
> > 
> > How about if I extract a common helper and provide set_memory_p() and
> > set_memory_np() in terms of those. Those are available on x86 and
> > PowerPC as well, so fairly standard. I suppose at that point we're
> > closer to set_memory_valid().
> 
> Why not just call set_direct_map_invalid_noflush() +
> flush_tlb_kernel_range() for each page? We already have APIs for this.
> 
> The big challenge I see with any linear map manipulation, however, is
> that it will rely on can_set_direct_map() which likely means you need to
> give up some performance and/or security to make this work. Does memory
> become inaccesible dynamically at runtime? If not, the best bet would
> be to describe it as a carveout in the DT and mark it as "no-map" so
> we avoid mapping it in the first place.

While I got your attention a bit off-topic but still related question.

AFAIK a lot in arm64 drivers ecosystem relies on that ranges defined as
"/reserved-memory" in DT are linked to devices that use that memory.

EFI/ACPI does not have a similar concept.

Given that more and more systems are using EFI/ACPI rather than DT as their
boot protocol we probably need some way to define such memory carveouts in
the ACPI world.
 
> Will

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* Re: [RFC PATCH 0/3] mm/compaction: honour compact_unevictable_allowed in mlock race and alloc_contig path
From: Lorenzo Stoakes @ 2026-07-08  6:35 UTC (permalink / raw)
  To: Wandun Chen
  Cc: linux-mm, linux-kernel, linux-trace-kernel, linux-rt-devel, akpm,
	vbabka, surenb, mhocko, jackmanb, hannes, ziy, rostedt, mhiramat,
	mathieu.desnoyers, david, liam, rppt, bigeasy, clrkwllms,
	Alexander.Krabler
In-Reply-To: <ak3uV7L5EEi3aKyD@lucifer>

On Wed, Jul 08, 2026 at 07:31:26AM +0100, Lorenzo Stoakes wrote:
> Errr... how does this relate to your other, non-RFC patch series [0] "mm: honour
> compact_unevictable_allowed in mlock and CMA paths"?
>
> Why did you send this separately and why do you not mention the other series
> here or there?
>
> And why is one RFC and the other not?
>
> You really need to add more context like this, I spent quite a bit of time
> reviewing [0] and don't want to find out that actually you are abandoning that
> for this or something?...

Oh hang on... this is old, and [0] is new, my bad.

It just got pinged up my mail client because of recent replies :>)

Thanks, Lorenzo

>
> On Thu, Jun 04, 2026 at 10:38:09AM +0800, Wandun Chen wrote:
> > From: Wandun Chen <chenwandun@lixiang.com>
> >
> > vm.compact_unevictable_allowed=0 is meant to keep compaction from
> > touching unevictable folios. In practice there are still two paths
> > where it does not take effect. This series fixes them and adds a
> > tracepoint to make such issues easier to diagnose in the future.
> >
> > Wandun Chen (3):
> >   mm/compaction: skip isolate mlocked folios when
> >     compact_unevictable_allowed=0
> >   mm/compaction: add per-folio isolation tracepoint
> >   mm/compaction: respect compact_unevictable_allowed in alloc_contig
> >     path
> >
> >  include/linux/compaction.h        |  6 ++++++
> >  include/trace/events/compaction.h | 26 ++++++++++++++++++++++++++
> >  mm/compaction.c                   | 14 +++++++++++---
> >  mm/internal.h                     |  1 +
> >  mm/page_alloc.c                   |  2 ++
> >  5 files changed, 46 insertions(+), 3 deletions(-)
> >
> > --
> > 2.43.0
> >
>
> Thanks, Lorenzo
>
> [0]:https://lore.kernel.org/all/20260707125925.3725177-1-chenwandun1@gmail.com/

^ permalink raw reply

* Re: [RFC PATCH 0/3] mm/compaction: honour compact_unevictable_allowed in mlock race and alloc_contig path
From: Lorenzo Stoakes @ 2026-07-08  6:31 UTC (permalink / raw)
  To: Wandun Chen
  Cc: linux-mm, linux-kernel, linux-trace-kernel, linux-rt-devel, akpm,
	vbabka, surenb, mhocko, jackmanb, hannes, ziy, rostedt, mhiramat,
	mathieu.desnoyers, david, liam, rppt, bigeasy, clrkwllms,
	Alexander.Krabler
In-Reply-To: <20260604023812.3700316-1-chenwandun1@gmail.com>

Errr... how does this relate to your other, non-RFC patch series [0] "mm: honour
compact_unevictable_allowed in mlock and CMA paths"?

Why did you send this separately and why do you not mention the other series
here or there?

And why is one RFC and the other not?

You really need to add more context like this, I spent quite a bit of time
reviewing [0] and don't want to find out that actually you are abandoning that
for this or something?...

On Thu, Jun 04, 2026 at 10:38:09AM +0800, Wandun Chen wrote:
> From: Wandun Chen <chenwandun@lixiang.com>
>
> vm.compact_unevictable_allowed=0 is meant to keep compaction from
> touching unevictable folios. In practice there are still two paths
> where it does not take effect. This series fixes them and adds a
> tracepoint to make such issues easier to diagnose in the future.
>
> Wandun Chen (3):
>   mm/compaction: skip isolate mlocked folios when
>     compact_unevictable_allowed=0
>   mm/compaction: add per-folio isolation tracepoint
>   mm/compaction: respect compact_unevictable_allowed in alloc_contig
>     path
>
>  include/linux/compaction.h        |  6 ++++++
>  include/trace/events/compaction.h | 26 ++++++++++++++++++++++++++
>  mm/compaction.c                   | 14 +++++++++++---
>  mm/internal.h                     |  1 +
>  mm/page_alloc.c                   |  2 ++
>  5 files changed, 46 insertions(+), 3 deletions(-)
>
> --
> 2.43.0
>

Thanks, Lorenzo

[0]:https://lore.kernel.org/all/20260707125925.3725177-1-chenwandun1@gmail.com/

^ permalink raw reply

* Re: [RFC PATCH 1/3] mm/compaction: skip isolate mlocked folios when compact_unevictable_allowed=0
From: Alexander Krabler @ 2026-07-08  6:24 UTC (permalink / raw)
  To: Wandun, Vlastimil Babka (SUSE), linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	linux-rt-devel@lists.linux.dev
  Cc: akpm@linux-foundation.org, surenb@google.com, mhocko@suse.com,
	jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com,
	rostedt@goodmis.org, mhiramat@kernel.org,
	mathieu.desnoyers@efficios.com, david@kernel.org, ljs@kernel.org,
	liam@infradead.org, rppt@kernel.org, bigeasy@linutronix.de,
	clrkwllms@kernel.org, Hugh Dickins
In-Reply-To: <e4761ca0-21d2-41d5-8d0f-ec14d0a5d3b9@gmail.com>

On 7/08/26 03:31, Wandun wrote:
> I found there are false positives in this reproducer.
> I modified the program a little,  the diff is as follows,
> the problem can still be reproduced
>
>
> diff --git a/repro.c b/repro.c
> index b1b34d5..59cb417 100644
> --- a/repro.c
> +++ b/repro.c
> @@ -15,6 +15,7 @@ static void *worker_fn(void *arg)
>         int fd = (long)arg;
>         size_t len = NR_PAGES * PAGE_SIZE;
>
> +       mlockall(MCL_ONFAULT |  MCL_FUTURE | MCL_CURRENT);
>         while (1) {
>                 if (ftruncate(fd, 0) < 0) {}
>                 if (ftruncate(fd, len) < 0) {}
> @@ -24,8 +25,6 @@ static void *worker_fn(void *arg)
>                 if (p == MAP_FAILED)
>                         continue;
>
> -               mlockall(MCL_ONFAULT |  MCL_FUTURE);
> -
>                 for (int i = 0; i < NR_PAGES; i++) {
>                         for (int j = 0; j < PAGE_SIZE; j++) {

No worries, I can reproduce with that program,
but I still think this is different.
The reproducer passes the MCL_ONFAULT flag to mlockall(),
delaying the actual memory allocation.

However, this is not what I would do in realtime programs and if I do,
these faults are basically memory allocations, where I can
not expect realtime performance guarantees.

If I remove MCL_ONFAULT, I did not manage to hit the migration_entry_wait
with the reproducer.

My guess is, that it only triggers when using CMA,
but I'm not deep enough into that topic to proof that.

--

KUKA Deutschland GmbH   Board of Directors: Michael Jürgens (Chairman), Johan Naten, Hui Zhang   Registered Office: Augsburg HRB 14914

This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of contents of this e-mail is strictly forbidden.

Please consider the environment before printing this e-mail.

^ permalink raw reply

* Re: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal()
From: Mike Rapoport @ 2026-07-08  6:22 UTC (permalink / raw)
  To: Robin Murphy
  Cc: Will Deacon, Thierry Reding, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Jonathan Hunter, David Airlie, Simona Vetter,
	Maarten Lankhorst, Maxime Ripard, Thomas Zimmermann,
	Sowjanya Komatineni, Luca Ceresoli, Mikko Perttunen, Yury Norov,
	Rasmus Villemoes, Russell King, Alexander Gordeev,
	Gerald Schaefer, Heiko Carstens, Vasily Gorbik,
	Christian Borntraeger, Sven Schnelle, Andrew Morton,
	David Hildenbrand, Lorenzo Stoakes, Liam R. Howlett,
	Vlastimil Babka, Suren Baghdasaryan, Michal Hocko,
	Marek Szyprowski, Sumit Semwal, Benjamin Gaignard, Brian Starkey,
	John Stultz, T.J. Mercier, Christian König, Steven Rostedt,
	Masami Hiramatsu, Mathieu Desnoyers, Catalin Marinas,
	Thierry Reding, devicetree, linux-tegra, linux-kernel, dri-devel,
	linux-media, linux-arm-kernel, linux-s390, linux-mm, iommu,
	linaro-mm-sig, linux-trace-kernel, Thierry Reding, Chun Ng
In-Reply-To: <f6e8b4d4-8b50-4cc7-b264-ae39929c619a@arm.com>

On Tue, Jul 07, 2026 at 03:15:24PM +0100, Robin Murphy wrote:
> On 07/07/2026 2:36 pm, Mike Rapoport wrote:
> > On Tue, Jul 07, 2026 at 02:17:29PM +0100, Robin Murphy wrote:
> > > 
> > > Given the precedent of memblock_mark_nomap(), as long as the reusable
> > > reserved-memory regions also get split into distinct memblocks, then it
> > > seems like in principle we ought to be able to give them a new
> > > MEMBLOCK_PTEMAP (or whatever) flag which could then be picked up in
> > > map_mem() without needing to override force_pte_mapping() globally?
> > 
> > Please don't. _nomap() caused enough pain.
> 
> Indeed I was there for pretty much the whole pfn_valid() saga :)
> 
> Bad example maybe - in this case the only actual similarity to nomap would
> be the fact that it would also be set by the of_reserved_mem code based on
> what it finds in DT; in all other aspects it should be functionally closer
> to something like MEMBLOCK_RSRV_NOINIT, i.e. just carrying information
> through the mm init phase, then ceasing to matter at all once the linear
> mapping is done.

Sounds simpler than nomap indeed :)

Although I'm not sure it won't be required after mm init in some way. There
is already a suggestion to allow collapsing PTE mappings into PMD in the
linear map [1] and it already adds a use-case for runtime check for
MEMBLOCK_PTEMAP.

That said, I don't hate the idea. The only thing is that such flag would be
very much arm64 specific. 
I've been thinking for a while about splitting memblock flags to generic
and arch-specific parts and if you decide to take a memblock flag route it
seems like a good use case for memblock_{set,clear}_arch_flags().

[1] https://lore.kernel.org/linux-mm/20260611130144.1385343-7-abarnas@google.com/
 
> Cheers,
> Robin.

-- 
Sincerely yours,
Mike.

^ permalink raw reply

* Re: [PATCH v3 04/11] arm64/mm: Add set_memory_device() and set_memory_normal()
From: Mike Rapoport @ 2026-07-08  6:08 UTC (permalink / raw)
  To: Thierry Reding
  Cc: Will Deacon, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
	Jonathan Hunter, David Airlie, Simona Vetter, Maarten Lankhorst,
	Maxime Ripard, Thomas Zimmermann, Sowjanya Komatineni,
	Luca Ceresoli, Mikko Perttunen, Yury Norov, Rasmus Villemoes,
	Russell King, Alexander Gordeev, Gerald Schaefer, Heiko Carstens,
	Vasily Gorbik, Christian Borntraeger, Sven Schnelle,
	Andrew Morton, David Hildenbrand, Lorenzo Stoakes,
	Liam R. Howlett, Vlastimil Babka, Suren Baghdasaryan,
	Michal Hocko, Marek Szyprowski, Robin Murphy, Sumit Semwal,
	Benjamin Gaignard, Brian Starkey, John Stultz, T.J. Mercier,
	Christian König, Steven Rostedt, Masami Hiramatsu,
	Mathieu Desnoyers, Catalin Marinas, Thierry Reding, devicetree,
	linux-tegra, linux-kernel, dri-devel, linux-media,
	linux-arm-kernel, linux-s390, linux-mm, iommu, linaro-mm-sig,
	linux-trace-kernel, Thierry Reding, Chun Ng
In-Reply-To: <akuvyu1Pq0ZVMZV0@orome>

On Mon, Jul 06, 2026 at 03:49:24PM +0200, Thierry Reding wrote:
> On Fri, Jul 03, 2026 at 06:13:31PM +0100, Will Deacon wrote:
> > >
> > > How about if I extract a common helper and provide set_memory_p() and
> > > set_memory_np() in terms of those. Those are available on x86 and
> > > PowerPC as well, so fairly standard. I suppose at that point we're
> > > closer to set_memory_valid().
> > 
> > Why not just call set_direct_map_invalid_noflush() +
> > flush_tlb_kernel_range() for each page? We already have APIs for this.
> 
> Having a "standard" helper with a fixed and documented purposed seemed
> like a preferable approach for this particular case. We also may want to
> make the driver that uses this buildable as a module, in which case we'd
> need to export these rather low-level APIs. And then there's also the
> fact that we typically call this on a rather large region of memory
> (usually something like 512 MiB), so doing it page-by-page is rather
> suboptimal.

There are discussions about adding numpages to set_direct_map, e.g.

https://lore.kernel.org/linux-mm/20260410151746.61150-2-kalyazin@amazon.com/
 
-- 
Sincerely yours,
Mike.

^ permalink raw reply

* Re: [RFC 1/3] arm64: kprobes: Do not handle non-XOL faults as kprobe faults
From: Hongyan Xia @ 2026-07-08  5:57 UTC (permalink / raw)
  To: Masami Hiramatsu (Google), Pu Hu
  Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260708094623.9a1d40bed37bce3c7969ad20@kernel.org>

Hi Masami,

On 7/8/2026 8:46 AM, Masami Hiramatsu wrote:
> On Mon, 6 Jul 2026 08:36:48 +0000
> Pu Hu <hupu@transsion.com> wrote:
>
>> From: Pu Hu <hupu@transsion.com>
>>
>> kprobe_fault_handler() handles faults taken while kprobes is in
>> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the
>> single-stepped instruction.
>>
>> That assumption is not always true. While a kprobe is preparing or
>> executing the out-of-line single-step instruction, other code may run
>> in that window. For example, perf or trace code can be invoked from the
>> debug exception path and may take a fault of its own. In that case the
>> fault did not happen on the kprobe XOL instruction, but the kprobe fault
>> handler may still try to recover it as a kprobe single-step fault.
>>
>> This can corrupt the exception recovery flow and leave the real fault to
>> be handled with a wrong PC. A typical reproducer is running simpleperf
>> with preemptirq tracepoints and dwarf callchains while a kprobe is
>> installed on a frequently executed kernel function.
>>
>> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when
>> the faulting PC points at the current kprobe's XOL instruction. Faults
>> from any other PC are left to the normal fault handling path.
>>
>> This follows the same idea as the x86 fix in commit 6381c24cd6d5
>> ("kprobes/x86: Fix page-fault handling logic").
>>
>> Signed-off-by: Pu Hu <hupu@transsion.com>
>> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
>> ---
>>   arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++
>>   1 file changed, 14 insertions(+)
>>
>> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
>> index 43a0361a8bf0..e4d2852ce2fb 100644
>> --- a/arch/arm64/kernel/probes/kprobes.c
>> +++ b/arch/arm64/kernel/probes/kprobes.c
>> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
>>        switch (kcb->kprobe_status) {
>>        case KPROBE_HIT_SS:
>>        case KPROBE_REENTER:
>> +             /*
>> +              * A fault taken while a kprobe is single-stepping is not
>> +              * necessarily caused by the instruction in the XOL slot. For
>> +              * example, tracing or perf code running in this window may take
>> +              * an unrelated fault.
>> +              *
>> +              * Handle the fault here only when the faulting PC is the XOL
>> +              * instruction of the current kprobe. Otherwise let the normal
>> +              * fault handling path deal with it.
>> +              */
>> +             if (cur->ainsn.xol_insn &&
>> +                     instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
>> +                     break;
>
> Can you check Sashiko's comments[1]?
>
> [1] https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1
>
> It seems that it complains about simulated kprobe's case.
> In that case, cur->ainsn.xol_insn == NULL. The simulation should be done
> in the kprobe context (which is a debug trap). I'm not sure the arm64
> can cause NMI in that context, but if it happens and causes a fault,
> it may cause a problem.
>
> So I think we can just ignore the fault on the simulated kprobes.
>
> To ensure that, you can just add:
>
>          if (cur && !cur->ainsn.xol_insn)
>                  return 0;
>
> at the entry of this function. (and remove redundant cur->ainsn.xol_insn check)

Right, both cases:

1. single-step XOL
2. simulated

have this problem and this patch fixed 1. 2 remains unchanged.

Ideally we should fix both, but the simulated case seems more
complicated, and at least we didn't make things worse for 2. So I wonder
if we can analyze 2 more thoroughly and fix it in a separate patch.

> Thank you,
>
>> +
>>                /*
>>                 * We are here because the instruction being single
>>                 * stepped caused a page fault. We reset the current
>> --
>> 2.43.0
>>
> --
> Masami Hiramatsu (Google) <mhiramat@kernel.org>


^ permalink raw reply

* Re: [RFC PATCH 1/3] mm/compaction: skip isolate mlocked folios when compact_unevictable_allowed=0
From: Wandun @ 2026-07-08  1:31 UTC (permalink / raw)
  To: Alexander Krabler, Vlastimil Babka (SUSE), linux-mm@kvack.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	linux-rt-devel@lists.linux.dev
  Cc: akpm@linux-foundation.org, surenb@google.com, mhocko@suse.com,
	jackmanb@google.com, hannes@cmpxchg.org, ziy@nvidia.com,
	rostedt@goodmis.org, mhiramat@kernel.org,
	mathieu.desnoyers@efficios.com, david@kernel.org, ljs@kernel.org,
	liam@infradead.org, rppt@kernel.org, bigeasy@linutronix.de,
	clrkwllms@kernel.org, Hugh Dickins
In-Reply-To: <05d7369e-341c-49f4-ae13-df3d0ad930d7@gmail.com>



On 6/29/26 17:07, Wandun wrote:
> 
> 
> On 6/26/26 21:42, Alexander Krabler wrote:
>> On 6/26/26 11:38, Wandun wrote:
>>> On 6/26/26 16:45, Alexander Krabler wrote:
>>>> However, we were not able to reproduce the actual race
>>>> (mlockall() process waiting on a migration PTE),
>>>> not in the past, not now. Might be hard to trigger that race.
>>>
>>> Not hard to trigger that case, I added a debug message, such as below,
>>> lots of messages occur in a few second.
>>>
>>> diff --cc mm/memory.c
>>> index ff338c2abe92,ff338c2abe92..6552b3b14f78
>>> --- a/mm/memory.c
>>> +++ b/mm/memory.c
>>> @@@ -4768,6 -4768,6 +4768,8 @@@ vm_fault_t do_swap_page(struct vm_faul
>>>                 if (softleaf_is_migration(entry)) {
>>>                         migration_entry_wait(vma->vm_mm, vmf->pmd,
>>>                                              vmf->address);
>>> +                       if (!strcmp(current->comm, "repro"))
>>> +                               pr_err("============== hit ================\n");
>>>                 } else if (softleaf_is_device_exclusive(entry)) {
>>>                         vmf->page = softleaf_to_page(entry);
>>>                         ret = remove_device_exclusive_entry(vmf);
>>
>> I have a kprobe on migration_entry_wait set and logged into a ftrace buffer
>> (including kernel stacktrace).
>> Yes, this function is hit, but only inside the mmap-syscall, which is okay,
>> memory allocation is not realtime-safe.
>>
>>            repro-2090    [002] d....   811.129549: frt_migration_entry_wait: (migration_entry_wait+0x0/0x100)
>>            repro-2090    [002] d....   811.129553: <stack trace>
>>  => migration_entry_wait
>>  => __handle_mm_fault
>>  => handle_mm_fault
>>  => __get_user_pages
>>  => populate_vma_page_range
>>  => __mm_populate
>>  => vm_mmap_pgoff
>>  => ksys_mmap_pgoff
>>  => __arm64_sys_mmap
>>  => el0_svc_common.constprop.0
>>  => do_el0_svc
>>  => el0_svc
>>  => el0t_64_sync_handler
>>  => el0t_64_sync
>>
>> The original race was an instruction abort interrupt out of nothing due
>> to the migration PTE set by kcompactd.
>> And these kind of races I see quite often on non mlockall()-processes,
>> but can't reproduce on memory locked processes.
>>
>> Example:
>>           podman-832     [000] d....   812.447820: frt_migration_entry_wait: (migration_entry_wait+0x0/0x100)
>>           podman-832     [000] d....   812.447823: <stack trace>
>>  => migration_entry_wait
>>  => __handle_mm_fault
>>  => handle_mm_fault
>>  => do_page_fault
>>  => do_translation_fault
>>  => do_mem_abort
>>  => el0_da
>>  => el0t_64_sync_handler
>>  => el0t_64_sync
> 
> Hi, Alexander
> 
> From the perspective of the root cause, there is no fundamental difference
> between these two call stacks. I modified the reproduction program, and it
> can still reproduce the situation of the second call stack
> (although it doesn't occur as frequently). The complete reproduction program
> is as follows:
> 
> 
> #define _GNU_SOURCE
> #include <fcntl.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <sys/mman.h>
> #include <sys/sysinfo.h>
> #include <unistd.h>
> 
> #define PAGE_SIZE       4096
> #define NR_PAGES        10000
> 
> static void *worker_fn(void *arg)
> {
> 	int fd = (long)arg;
> 	size_t len = NR_PAGES * PAGE_SIZE;
> 
> 	while (1) {
> 		if (ftruncate(fd, 0) < 0) {}
> 		if (ftruncate(fd, len) < 0) {}
> 
> 		char *p = mmap(NULL, len, PROT_READ | PROT_WRITE,
> 			       MAP_SHARED, fd, 0);
> 		if (p == MAP_FAILED)
> 			continue;
> 
> 		mlockall(MCL_ONFAULT |  MCL_FUTURE);
> 
> 		for (int i = 0; i < NR_PAGES; i++) {
> 			for (int j = 0; j < PAGE_SIZE; j++) {
> 				p[i * PAGE_SIZE + j] = 1;
> 			}
> 		}
> 
> 		usleep(200);
> 		munmap(p, len);
> 	}
> 	return NULL;
> }
> 
> static void *compact_fn(void *arg)
> {
> 	(void)arg;
> 	int fd = open("/proc/sys/vm/compact_memory", O_WRONLY);
> 	if (fd < 0)
> 		return NULL;
> 
> 	while (1) {
> 		if (write(fd, "1", 1) < 0) {}
> 		usleep(5000);
> 	}
> }
> 
> int main(void)
> {
> 	int nproc = sysconf(_SC_NPROCESSORS_ONLN);
> 	if (nproc < 1)
> 		nproc = 1;
> 
> 	int *fds = calloc((size_t)nproc, sizeof(int));
> 	if (!fds)
> 		return 1;
> 
> 	size_t len = NR_PAGES * PAGE_SIZE;
> 	for (int i = 0; i < nproc; i++) {
> 		char path[64];
> 		snprintf(path, sizeof(path), "./repro_%d.dat", i);
> 		unlink(path);
> 		fds[i] = open(path, O_RDWR | O_CREAT, 0600);
> 		if (fds[i] < 0)
> 			return 1;
> 		if (ftruncate(fds[i], len) < 0)
> 			return 1;
> 	}
> 
> 	printf("repro: %d workers, %d pages, Ctrl-C to stop\n",
> 	       nproc, NR_PAGES);
> 
> 	pthread_t compact;
> 	pthread_create(&compact, NULL, compact_fn, NULL);
> 
> 	pthread_t *threads = calloc((size_t)nproc, sizeof(pthread_t));
> 	for (int i = 0; i < nproc; i++)
> 		pthread_create(&threads[i], NULL, worker_fn, (void *)(long)fds[i]);
> 
> 	pthread_join(compact, NULL);
> 	return 0;
> }

I found there are false positives in this reproducer.
I modified the program a little,  the diff is as follows,
the problem can still be reproduced


diff --git a/repro.c b/repro.c
index b1b34d5..59cb417 100644
--- a/repro.c
+++ b/repro.c
@@ -15,6 +15,7 @@ static void *worker_fn(void *arg)
        int fd = (long)arg;
        size_t len = NR_PAGES * PAGE_SIZE;

+       mlockall(MCL_ONFAULT |  MCL_FUTURE | MCL_CURRENT);
        while (1) {
                if (ftruncate(fd, 0) < 0) {}
                if (ftruncate(fd, len) < 0) {}
@@ -24,8 +25,6 @@ static void *worker_fn(void *arg)
                if (p == MAP_FAILED)
                        continue;

-               mlockall(MCL_ONFAULT |  MCL_FUTURE);
-
                for (int i = 0; i < NR_PAGES; i++) {
                        for (int j = 0; j < PAGE_SIZE; j++) {
                                p[i * PAGE_SIZE + j] = 1;


> 
> 
> 
> 
>>
>> Thanks,
>> Alexander
>>
>> --
>>
>> KUKA Deutschland GmbH   Board of Directors: Michael Jürgens (Chairman), Johan Naten, Hui Zhang   Registered Office: Augsburg HRB 14914
>>
>> This e-mail may contain confidential and/or privileged information. If you are not the intended recipient (or have received this e-mail in error) please notify the sender immediately and destroy this e-mail. Any unauthorized copying, disclosure or distribution of contents of this e-mail is strictly forbidden.
>>
>> Please consider the environment before printing this e-mail.
> 


^ permalink raw reply related

* Re: [RFC 0/3] arm64: kprobes: Fix single-step fault and reentry handling
From: Masami Hiramatsu @ 2026-07-08  0:55 UTC (permalink / raw)
  To: Pu Hu
  Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Hongyan Xia, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-1-hupu@transsion.com>

Hi, Pu,

Thanks for updating the series. But even if it just update
the signed-off-by, please update the version.

Also, can you check the Sashiko's comments?

https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com

Thank you,

On Mon, 6 Jul 2026 08:36:46 +0000
Pu Hu <hupu@transsion.com> wrote:

> From: Pu Hu <hupu@transsion.com>
> 
> This series fixes two arm64 kprobes issues observed when running
> simpleperf with preemptirq tracepoints and dwarf callchains while a
> kprobe is active on a frequently executed kernel function.
> 
> The crash happens in the kprobe debug exception path. While a kprobe is
> preparing or executing its XOL single-step instruction, perf/trace code
> can run in the same window. That code may either take a fault of its own
> or hit another kprobe.
> 
> Patch 1 makes kprobe_fault_handler() handle a fault in
> KPROBE_HIT_SS/KPROBE_REENTER only when the faulting PC points at the
> current kprobe's XOL instruction. Otherwise the fault is left to the
> normal fault handling path.
> 
> Patch 2 allows a kprobe hit in KPROBE_HIT_SS to be handled as a
> recoverable one-level reentry. Only a hit while already in
> KPROBE_REENTER remains unrecoverable.
> 
> Patch 3 adds a kprobes selftest which registers a kprobe on a frequently
> executed filemap fault path and drives repeated file-backed page faults
> from userspace. This provides a smaller reproducer for validating the
> fault handling fix.
> 
> This follows the same logic as the existing x86 fixes:
>   6381c24cd6d5 ("kprobes/x86: Fix page-fault handling logic")
>   6a5022a56ac3 ("kprobes/x86: Allow to handle reentered kprobe on single-stepping")
> 
> Reproducer:
> 
>   simpleperf record -p <pid> -f 10000 \
>     -e preemptirq:preempt_disable \
>     -e preemptirq:preempt_enable \
>     --duration 9 --call-graph dwarf \
>     -o /data/local/tmp/perf.data
> 
> The new selftest can be built from tools/testing/selftests/kprobe/ and
> used to exercise the page fault handling path with the test kprobe
> module loaded.
> 
> Before this series, the crash reproduced frequently. With both patches
> applied, it was no longer reproduced in our testing.
> 
> 
> Pu Hu (3):
>   arm64: kprobes: Do not handle non-XOL faults as kprobe faults
>   arm64: kprobes: Allow reentering kprobes while single-stepping
>   selftests/kprobes: Add kprobe stress test for page fault handling
> 
>  arch/arm64/kernel/probes/kprobes.c            |  22 +++-
>  tools/testing/selftests/kprobe/.gitignore     |   2 +
>  tools/testing/selftests/kprobe/Makefile       |  75 +++++++++++++
>  tools/testing/selftests/kprobe/fault_stress.c | 105 ++++++++++++++++++
>  .../selftests/kprobe/kprobe_folio_stress.c    |  70 ++++++++++++
>  5 files changed, 273 insertions(+), 1 deletion(-)
>  create mode 100644 tools/testing/selftests/kprobe/.gitignore
>  create mode 100644 tools/testing/selftests/kprobe/Makefile
>  create mode 100644 tools/testing/selftests/kprobe/fault_stress.c
>  create mode 100644 tools/testing/selftests/kprobe/kprobe_folio_stress.c
> 
> -- 
> 2.43.0
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [RFC 2/3] arm64: kprobes: Allow reentering kprobes while single-stepping
From: Masami Hiramatsu @ 2026-07-08  0:54 UTC (permalink / raw)
  To: Pu Hu
  Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Hongyan Xia, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-3-hupu@transsion.com>

On Mon, 6 Jul 2026 08:36:49 +0000
Pu Hu <hupu@transsion.com> wrote:

> From: Pu Hu <hupu@transsion.com>
> 
> A kprobe can be hit while another kprobe is in KPROBE_HIT_SS state. This
> can happen when tracing or perf code runs from the debug exception path
> while the first kprobe is preparing or executing its out-of-line
> single-step instruction.
> 
> Currently arm64 treats a kprobe hit in KPROBE_HIT_SS as unrecoverable,
> the same as a hit in KPROBE_REENTER. This is too strict. A hit in
> KPROBE_HIT_SS is still a one-level reentry and can be handled by saving
> the current kprobe state and setting up single-step for the new probe,
> just like reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
> 
> The truly unrecoverable case is hitting another kprobe while already in
> KPROBE_REENTER, because the reentry save area has already been consumed.
> 
> Move KPROBE_HIT_SS to the recoverable reentry cases and leave
> KPROBE_REENTER as the unrecoverable nested reentry case.
> 
> This mirrors the x86 fix in commit 6a5022a56ac3
> ("kprobes/x86: Allow to handle reentered kprobe on single-stepping").

Can you also check the Sashiko comment?

https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=2

This seems indicating potentially brakage of reenter kprobes on arm64.
But is it possible to hit another kprobe while SS on arm64? It is
the same question about the previous one, can NMI happens during
the single stepping? (maybe yes, because it is non-maskable)

Anyway, for making it safer, we need to add saved_irqflags to prev_kprobe.

Thank you,

> 
> Signed-off-by: Pu Hu <hupu@transsion.com>
> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
> ---
>  arch/arm64/kernel/probes/kprobes.c | 8 +++++++-
>  1 file changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index e4d2852ce2fb..764b2228cca0 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -240,10 +240,16 @@ static int __kprobes reenter_kprobe(struct kprobe *p,
>  	switch (kcb->kprobe_status) {
>  	case KPROBE_HIT_SSDONE:
>  	case KPROBE_HIT_ACTIVE:
> +	case KPROBE_HIT_SS:
> +		/*
> +		 * A probe can be hit while another kprobe is preparing or
> +		 * executing its XOL single-step instruction. This is still a
> +		 * recoverable one-level reentry, so handle it in the same way as
> +		 * reentry from KPROBE_HIT_ACTIVE or KPROBE_HIT_SSDONE.
> +		 */
>  		kprobes_inc_nmissed_count(p);
>  		setup_singlestep(p, regs, kcb, 1);
>  		break;
> -	case KPROBE_HIT_SS:
>  	case KPROBE_REENTER:
>  		pr_warn("Failed to recover from reentered kprobes.\n");
>  		dump_kprobe(p);
> -- 
> 2.43.0
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* Re: [RFC 1/3] arm64: kprobes: Do not handle non-XOL faults as kprobe faults
From: Masami Hiramatsu @ 2026-07-08  0:46 UTC (permalink / raw)
  To: Pu Hu
  Cc: ada.coupriediaz@arm.com, catalin.marinas@arm.com,
	davem@davemloft.net, Hongyan Xia, Jiazi Li,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-trace-kernel@vger.kernel.org,
	naveen@kernel.org, will@kernel.org, yang@os.amperecomputing.com
In-Reply-To: <20260706083636.159883-2-hupu@transsion.com>

On Mon, 6 Jul 2026 08:36:48 +0000
Pu Hu <hupu@transsion.com> wrote:

> From: Pu Hu <hupu@transsion.com>
> 
> kprobe_fault_handler() handles faults taken while kprobes is in
> KPROBE_HIT_SS or KPROBE_REENTER state as faults caused by the
> single-stepped instruction.
> 
> That assumption is not always true. While a kprobe is preparing or
> executing the out-of-line single-step instruction, other code may run
> in that window. For example, perf or trace code can be invoked from the
> debug exception path and may take a fault of its own. In that case the
> fault did not happen on the kprobe XOL instruction, but the kprobe fault
> handler may still try to recover it as a kprobe single-step fault.
> 
> This can corrupt the exception recovery flow and leave the real fault to
> be handled with a wrong PC. A typical reproducer is running simpleperf
> with preemptirq tracepoints and dwarf callchains while a kprobe is
> installed on a frequently executed kernel function.
> 
> Fix this by handling faults in KPROBE_HIT_SS/KPROBE_REENTER only when
> the faulting PC points at the current kprobe's XOL instruction. Faults
> from any other PC are left to the normal fault handling path.
> 
> This follows the same idea as the x86 fix in commit 6381c24cd6d5
> ("kprobes/x86: Fix page-fault handling logic").
> 
> Signed-off-by: Pu Hu <hupu@transsion.com>
> Signed-off-by: Hongyan Xia <hongyan.xia@transsion.com>
> ---
>  arch/arm64/kernel/probes/kprobes.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
> 
> diff --git a/arch/arm64/kernel/probes/kprobes.c b/arch/arm64/kernel/probes/kprobes.c
> index 43a0361a8bf0..e4d2852ce2fb 100644
> --- a/arch/arm64/kernel/probes/kprobes.c
> +++ b/arch/arm64/kernel/probes/kprobes.c
> @@ -285,6 +285,20 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr)
>  	switch (kcb->kprobe_status) {
>  	case KPROBE_HIT_SS:
>  	case KPROBE_REENTER:
> +		/*
> +		 * A fault taken while a kprobe is single-stepping is not
> +		 * necessarily caused by the instruction in the XOL slot. For
> +		 * example, tracing or perf code running in this window may take
> +		 * an unrelated fault.
> +		 *
> +		 * Handle the fault here only when the faulting PC is the XOL
> +		 * instruction of the current kprobe. Otherwise let the normal
> +		 * fault handling path deal with it.
> +		 */
> +		if (cur->ainsn.xol_insn &&
> +			instruction_pointer(regs) != (unsigned long)cur->ainsn.xol_insn)
> +			break;

Can you check Sashiko's comments[1]?

[1] https://sashiko.dev/#/patchset/20260706083636.159883-1-hupu%40transsion.com?part=1

It seems that it complains about simulated kprobe's case.
In that case, cur->ainsn.xol_insn == NULL. The simulation should be done
in the kprobe context (which is a debug trap). I'm not sure the arm64
can cause NMI in that context, but if it happens and causes a fault,
it may cause a problem.

So I think we can just ignore the fault on the simulated kprobes.

To ensure that, you can just add:

	if (cur && !cur->ainsn.xol_insn)
		return 0;

at the entry of this function. (and remove redundant cur->ainsn.xol_insn check)

Thank you,

> +
>  		/*
>  		 * We are here because the instruction being single
>  		 * stepped caused a page fault. We reset the current
> -- 
> 2.43.0
> 


-- 
Masami Hiramatsu (Google) <mhiramat@kernel.org>

^ permalink raw reply

* [PATCH v3] selftests/user_events: wait for deferred event teardown after unregister
From: Michael Bommarito @ 2026-07-07 18:02 UTC (permalink / raw)
  To: Steven Rostedt, Masami Hiramatsu, Mathieu Desnoyers
  Cc: Beau Belgrave, XIAO WU, Shuah Khan, linux-trace-kernel,
	linux-kselftest, linux-kernel

Unregistering a user event now defers the drop of the enabler's event
reference (and the freeing of the enabler) past an RCU grace period. As a
result DIAG_IOCSDEL can transiently fail with -EBUSY while that last
reference is still being dropped, where it previously succeeded
immediately.

Two tests assumed the delete takes effect the instant the unregister
returns:

  - abi_test "flags" deletes the event right after disabling it.
  - perf_test's fixture teardown clear() deletes __test_event before the
    next test registers the same name; a stale event makes the following
    registration fail with -EADDRINUSE.

Retry the delete until it succeeds (or the event is already gone) with a
bounded wait, matching the existing wait_for_delete() idiom in the same
suite, so the tests are robust to the deferred teardown.

Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
---
This resends only the selftest patch; the tracing/user_events fix that
was patch 1/2 of the v2 series is unchanged and being applied separately.

v2 -> v3:
  - abi_test wait_for_event_delete(): only retry the delete on -EBUSY,
    treat an already-deleted event (-ENOENT) as success, and return any
    other error immediately instead of spinning for the full 10s timeout.
    perf_test's clear() already discriminated on errno this way; the two
    now match. Reported by Sashiko automated review.

 .../testing/selftests/user_events/abi_test.c  | 29 ++++++++++++++++++-
 .../testing/selftests/user_events/perf_test.c | 26 +++++++++++++++--
 2 files changed, 51 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/user_events/abi_test.c b/tools/testing/selftests/user_events/abi_test.c
index 85892b3b719cc..b71813eaf5c04 100644
--- a/tools/testing/selftests/user_events/abi_test.c
+++ b/tools/testing/selftests/user_events/abi_test.c
@@ -132,6 +132,33 @@ static int event_delete(void)
 	return ret;
 }
 
+/*
+ * Deleting an event drops its last reference, but an unregister may defer
+ * that put (and the freeing of the associated enabler) past an RCU grace
+ * period. The delete can therefore transiently fail with -EBUSY while the
+ * previous reference is still being dropped. Retry only on that transient
+ * failure; treat an already-deleted event (-ENOENT) as success and return
+ * any other error immediately rather than spinning for the full timeout.
+ */
+static int wait_for_event_delete(void)
+{
+	int i, ret;
+
+	for (i = 0; i < 10000; ++i) {
+		ret = event_delete();
+
+		if (ret == 0 || errno == ENOENT)
+			return 0;
+
+		if (errno != EBUSY)
+			return ret;
+
+		usleep(1000);
+	}
+
+	return ret;
+}
+
 static int reg_enable_multi(void *enable, int size, int bit, int flags,
 			    char *args)
 {
@@ -262,7 +289,7 @@ TEST_F(user, flags) {
 	ASSERT_TRUE(event_exists());
 
 	/* Ensure we can delete it */
-	ASSERT_EQ(0, event_delete());
+	ASSERT_EQ(0, wait_for_event_delete());
 
 	/* USER_EVENT_REG_MAX or above is not allowed */
 	ASSERT_EQ(-1, reg_enable_flags(&self->check, sizeof(int), 0,
diff --git a/tools/testing/selftests/user_events/perf_test.c b/tools/testing/selftests/user_events/perf_test.c
index cafec0e52eb31..5727cb5b914cf 100644
--- a/tools/testing/selftests/user_events/perf_test.c
+++ b/tools/testing/selftests/user_events/perf_test.c
@@ -85,6 +85,7 @@ static int get_offset(void)
 static int clear(int *check)
 {
 	struct user_unreg unreg = {0};
+	int i, ret;
 
 	unreg.size = sizeof(unreg);
 	unreg.disable_bit = 31;
@@ -99,13 +100,32 @@ static int clear(int *check)
 		if (errno != ENOENT)
 			return -1;
 
-	if (ioctl(fd, DIAG_IOCSDEL, "__test_event") == -1)
-		if (errno != ENOENT)
+	/*
+	 * Deleting the event drops its last reference, but the unregister
+	 * above defers that put (and the freeing of the enabler) past an RCU
+	 * grace period. The delete can therefore transiently fail with -EBUSY
+	 * until that reference is dropped. Retry for up to ~10 seconds so the
+	 * event is actually gone before the next test registers the same name.
+	 */
+	for (i = 0; i < 10000; ++i) {
+		ret = ioctl(fd, DIAG_IOCSDEL, "__test_event");
+
+		if (ret == 0 || errno == ENOENT) {
+			ret = 0;
+			break;
+		}
+
+		if (errno != EBUSY) {
+			close(fd);
 			return -1;
+		}
+
+		usleep(1000);
+	}
 
 	close(fd);
 
-	return 0;
+	return ret;
 }
 
 FIXTURE(user) {
-- 
2.53.0


^ permalink raw reply related

* Re: [PATCH v2] tracing/synthetic: Free type string on error path
From: Steven Rostedt @ 2026-07-07 17:54 UTC (permalink / raw)
  To: Yu Peng; +Cc: mhiramat, mathieu.desnoyers, linux-trace-kernel, linux-kernel
In-Reply-To: <20260707132417.2193412-1-pengyu@kylinos.cn>

On Tue,  7 Jul 2026 21:24:17 +0800
Yu Peng <pengyu@kylinos.cn> wrote:

> parse_synth_field() builds a "__data_loc ..." type string before
> assigning it to field->type. If the seq_buf check fails, the temporary
> string is not owned by field and is leaked. Free it before leaving.
> 
> Suggested-by: Steven Rostedt <rostedt@goodmis.org>
> Signed-off-by: Yu Peng <pengyu@kylinos.cn>
> ---
> Changes in v2:
> - Use __free(kfree) and no_free_ptr() as suggested by Steven.
> 
>  kernel/trace/trace_events_synth.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
> index e6871230bde96..ad2e70258291b 100644
> --- a/kernel/trace/trace_events_synth.c
> +++ b/kernel/trace/trace_events_synth.c
> @@ -828,7 +828,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
>  	} else if (size == 0) {
>  		if (synth_field_is_string(field->type) ||
>  		    synth_field_is_stack(field->type)) {
> -			char *type;
> +			char *type __free(kfree) = NULL;

Ah, we can't do this here.

(Sashiko pointed this out: https://sashiko.dev/#/patchset/20260707132417.2193412-1-pengyu%40kylinos.cn )

>  
>  			len = sizeof("__data_loc ") + strlen(field->type) + 1;
>  			type = kzalloc(len, GFP_KERNEL);

Because after this code we have:

			type = kzalloc(len, GFP_KERNEL);
			if (!type)
				goto free;

Which jumps out of the if block, and that will break the cleanup.

I'll take you original version for now.

-- Steve


> @@ -844,7 +844,7 @@ static struct synth_field *parse_synth_field(int argc, char **argv,
>  			s.buffer[s.len] = '\0';
>  
>  			kfree(field->type);
> -			field->type = type;
> +			field->type = no_free_ptr(type);
>  
>  			field->is_dynamic = true;
>  			size = sizeof(u64);


^ permalink raw reply

* Re: [PATCH] rtla: Also link in ctype.c
From: Bastian Blank @ 2026-07-07 17:43 UTC (permalink / raw)
  To: Tomas Glozar; +Cc: Steven Rostedt, linux-trace-kernel
In-Reply-To: <CAP4=nvTH5HhUk19w06aH6-xqWGOUQKesGbKCfvgpwmefLom0VQ@mail.gmail.com>

On Tue, Jul 07, 2026 at 12:22:37PM +0200, Tomas Glozar wrote:
> Thank you. It appears that GCC LTO drops the symbol use of "_ctype",
> so I didn't see it earlier. With removed -flto=auto from
> Makefile.rtla, I can reproduce it:

Ah, yes, we override LTO to disabled.

Bastian

-- 
There are certain things men must do to remain men.
		-- Kirk, "The Ultimate Computer", stardate 4929.4

^ permalink raw reply

* Re: [PATCH 2/2] selftests/user_events: wait for deferred event teardown after unregister
From: Steven Rostedt @ 2026-07-07 17:41 UTC (permalink / raw)
  To: Michael Bommarito
  Cc: Masami Hiramatsu, Mathieu Desnoyers, Beau Belgrave, XIAO WU,
	linux-trace-kernel, linux-kernel, stable
In-Reply-To: <20260707165912.2560537-3-michael.bommarito@gmail.com>

On Tue,  7 Jul 2026 12:59:12 -0400
Michael Bommarito <michael.bommarito@gmail.com> wrote:

>  
> +/*
> + * Deleting an event drops its last reference, but an unregister may defer
> + * that put (and the freeing of the associated enabler) past an RCU grace
> + * period. The delete can therefore transiently fail with -EBUSY while the
> + * previous reference is still being dropped. Retry for up to ~10 seconds.
> + */
> +static int wait_for_event_delete(void)
> +{
> +	int i, ret;
> +
> +	for (i = 0; i < 10000; ++i) {
> +		ret = event_delete();
> +
> +		if (ret == 0)
> +			return 0;
> +
> +		usleep(1000);
> +	}
> +
> +	return ret;
> +}
> +

Care to address Sashiko's comment: https://sashiko.dev/#/patchset/20260707165912.2560537-2-michael.bommarito%40gmail.com

I'll pull in patch 1 and start testing it as this one is just the tools
change, it doesn't need my testing (my tests only tests kernel changes)

-- Steve

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox