mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Andi Kleen <ak@kernel.org>
To: linux-kernel@vger.kernel.org
Cc: mhiramat@kernel.org, oleg@redhat.com, peterz@infradead.org,
	tglx@kernel.org, x86@kernel.org, jolsa@kernel.org,
	linux-perf-users@vger.kernel.org, adrian.hunter@intel.com,
	Andi Kleen <ak@kernel.org>
Subject: [RFC v1 08/19] ptwrite uprobes / x86: Add a user fault notifier chain
Date: Mon, 31 Aug 2026 08:04:44 -0700	[thread overview]
Message-ID: <20260831150651.1134594-9-ak@kernel.org> (raw)
In-Reply-To: <20260831150651.1134594-1-ak@kernel.org>

The ptwrite uprobes need to catch faults in the user probes, otherwise a
bad probe could crash the program. For classic probes that is handled in
the kernel, but with these new kinds of probes the crash happens in ring 3
code.

The existing die chain cannot be used for this because it only handles
kernel level faults. Add a new user fault notifier chain that is supported
for #GP, #PF, #SS. It is only called before a signal would be delivered, so
it doesn't slow down any hot paths. The fault handler can then handle the
fault and prevent the signal.

Add register code and the hooks for the chain.

Some of the existing fault hardware workarounds could be converted to this
in the future (not done yet)

Assisted-by: omp:gpt-5.6-luna
Signed-off-by: Andi Kleen <ak@kernel.org>
---
 arch/x86/include/asm/traps.h | 17 +++++++++++++++++
 arch/x86/kernel/traps.c      | 32 ++++++++++++++++++++++++++++++++
 arch/x86/mm/fault.c          |  6 ++++++
 3 files changed, 55 insertions(+)

diff --git a/arch/x86/include/asm/traps.h b/arch/x86/include/asm/traps.h
index 3f24cc472ce9..c3cdfde3c7b0 100644
--- a/arch/x86/include/asm/traps.h
+++ b/arch/x86/include/asm/traps.h
@@ -4,6 +4,7 @@
 
 #include <linux/context_tracking_state.h>
 #include <linux/kprobes.h>
+#include <linux/notifier.h>
 
 #include <asm/debugreg.h>
 #include <asm/idtentry.h>
@@ -59,4 +60,20 @@ static inline void cond_local_irq_disable(struct pt_regs *regs)
 		local_irq_disable();
 }
 
+/*
+ * User-mode fault notifier chain, called before a user exception is
+ * about to become a signal. NOTIFY_STOP consumes the fault.
+ */
+struct x86_user_fault_args {
+	struct pt_regs	*regs;
+	unsigned long	error_code;
+	unsigned long	address;	/* #PF: faulting address */
+	unsigned int	trap;
+};
+
+extern int register_x86_user_fault_notifier(struct notifier_block *nb);
+extern void unregister_x86_user_fault_notifier(struct notifier_block *nb);
+extern int notify_x86_user_fault(struct pt_regs *regs, unsigned long error_code,
+				 unsigned long address, unsigned int trap);
+
 #endif /* _ASM_X86_TRAPS_H */
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 30aa8369957e..5259a205b837 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -517,6 +517,11 @@ DEFINE_IDTENTRY_ERRORCODE(exc_segment_not_present)
 
 DEFINE_IDTENTRY_ERRORCODE(exc_stack_segment)
 {
+	if (user_mode(regs) &&
+	    notify_x86_user_fault(regs, error_code, 0, X86_TRAP_SS) ==
+			NOTIFY_STOP)
+		return;
+
 	do_error_trap(regs, error_code, "stack segment", X86_TRAP_SS, SIGBUS,
 		      0, NULL);
 }
@@ -911,6 +916,30 @@ static void gp_user_force_sig_segv(struct pt_regs *regs, int trapnr,
 	force_sig(SIGSEGV);
 }
 
+static ATOMIC_NOTIFIER_HEAD(x86_user_fault_chain);
+
+int register_x86_user_fault_notifier(struct notifier_block *nb)
+{
+	return atomic_notifier_chain_register(&x86_user_fault_chain, nb);
+}
+void unregister_x86_user_fault_notifier(struct notifier_block *nb)
+{
+	atomic_notifier_chain_unregister(&x86_user_fault_chain, nb);
+}
+
+int notify_x86_user_fault(struct pt_regs *regs, unsigned long error_code,
+			  unsigned long address, unsigned int trap)
+{
+	struct x86_user_fault_args args = {
+		.regs = regs,
+		.error_code = error_code,
+		.address = address,
+		.trap = trap,
+	};
+
+	return atomic_notifier_call_chain(&x86_user_fault_chain, 0, &args);
+}
+
 DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 {
 	char desc[sizeof(GPFSTR) + 50 + 2*sizeof(unsigned long) + 1] = GPFSTR;
@@ -942,6 +971,9 @@ DEFINE_IDTENTRY_ERRORCODE(exc_general_protection)
 		if (emulate_vsyscall_gp(regs))
 			goto exit;
 
+		if (notify_x86_user_fault(regs, error_code, 0, X86_TRAP_GP) == NOTIFY_STOP)
+			goto exit;
+
 		gp_user_force_sig_segv(regs, X86_TRAP_GP, error_code, desc);
 		goto exit;
 	}
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index aa88370ce739..897165f960b8 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -821,6 +821,9 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,
 	if (fixup_vdso_exception(regs, X86_TRAP_PF, error_code, address))
 		return;
 
+	if (notify_x86_user_fault(regs, error_code, address, X86_TRAP_PF) == NOTIFY_STOP)
+		return;
+
 	if (likely(show_unhandled_signals))
 		show_signal_msg(regs, error_code, address, tsk);
 
@@ -950,6 +953,9 @@ do_sigbus(struct pt_regs *regs, unsigned long error_code, unsigned long address,
 		return;
 	}
 #endif
+	if (notify_x86_user_fault(regs, error_code, address, X86_TRAP_PF) == NOTIFY_STOP)
+		return;
+
 	force_sig_fault(SIGBUS, BUS_ADRERR, (void __user *)address);
 }
 
-- 
2.54.0


  parent reply	other threads:[~2026-08-31 15:07 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-31 15:04 [RFC] ptwrite uprobes Andi Kleen
2026-08-31 15:04 ` [RFC v1 01/19] uprobes: guard trace cleanup against error pointers Andi Kleen
2026-09-01  0:49   ` Masami Hiramatsu
2026-08-31 15:04 ` [RFC v1 02/19] uprobes: Correctly reject anonymous VMAs for breakpoint installation Andi Kleen
2026-08-31 15:04 ` [RFC v1 03/19] uprobes: Print warning for missing breakpoint install Andi Kleen
2026-08-31 15:04 ` [RFC v1 04/19] ptwrite uprobes: Add infrastructure for ptwrite uprobes Andi Kleen
2026-08-31 15:04 ` [RFC v1 05/19] ptwrite uprobes: Add minimal low level support for x86 Andi Kleen
2026-09-02 16:35   ` Lorenzo Stoakes (ARM)
2026-08-31 15:04 ` [RFC v1 06/19] ptwrite uprobes: Add a sample module to exercise interface Andi Kleen
2026-08-31 15:04 ` [RFC v1 07/19] ptwrite uprobes: Add support to tracing infrastructure Andi Kleen
2026-08-31 15:04 ` Andi Kleen [this message]
2026-08-31 15:04 ` [RFC v1 09/19] ptwrite uprobes: Factor file-backed instruction reads Andi Kleen
2026-08-31 15:04 ` [RFC v1 10/19] ptwrite uprobes: Minimal memory references and fault handling Andi Kleen
2026-08-31 15:04 ` [RFC v1 11/19] ptwrite uprobes: Add multinop support Andi Kleen
2026-08-31 15:04 ` [RFC v1 12/19] ptwrite uprobes: Add pacing to the probes Andi Kleen
2026-08-31 15:04 ` [RFC v1 13/19] ptwrite uprobes: Support instruction puning Andi Kleen
2026-08-31 15:04 ` [RFC v1 14/19] ptwrite uprobes: Use atomic patching for multinop sites Andi Kleen
2026-08-31 15:04 ` [RFC v1 15/19] ptwrite uprobes: Add a tutorial and overview documentation Andi Kleen
2026-08-31 15:04 ` [RFC v1 16/19] ptwrite uprobes / perf tools pt: Improve FUP error handling for ptwrite Andi Kleen
2026-08-31 15:04 ` [RFC v1 17/19] ptwrite uprobes / perf tools probe: Add support of ptwrite probes Andi Kleen
2026-08-31 15:04 ` [RFC v1 18/19] ptwrite uprobes / perf tools script: Add ptwrite uprobes decoder Andi Kleen
2026-08-31 15:04 ` [RFC v1 19/19] ptwrite uprobes: Add self tests Andi Kleen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260831150651.1134594-9-ak@kernel.org \
    --to=ak@kernel.org \
    --cc=adrian.hunter@intel.com \
    --cc=jolsa@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=oleg@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®