git: 3e6bc5c3b563 - main - sys/arm: Fix DTrace trap hook

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 03 Sep 2026 15:05:33 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=3e6bc5c3b5632ac9f55633b7d4e2e1a42b96a78b

commit 3e6bc5c3b5632ac9f55633b7d4e2e1a42b96a78b
Author:     Benjamin Jacobs <freebsd@dev.thsi.be>
AuthorDate: 2026-09-03 13:52:19 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-03 15:05:03 +0000

    sys/arm: Fix DTrace trap hook
    
    Move the dtrace_trap hook at the start of the abort handler to exit
    early when a trap is handled by DTrace.
    
    Fix the type argument to be the actual fault type instead of the value
    of the FAR. The latter will need to be added to the trapframe, until
    then DTrace will report unmapped addresses as the null address.
    
    Correct the comment of the PUSHFRAMEINSVC assembler macro to reflect
    that coming from SVC32 mode is expected for DTrace traps.
    
    PR:             298064
    MFC after:      1 month
    Reviewed by:    markj
    Differential Revision:  https://reviews.freebsd.org/D59279
---
 sys/arm/arm/exception.S |  6 +++---
 sys/arm/arm/trap-v6.c   | 15 ++++++++-------
 2 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index 2c25628f77cc..9df8e029385c 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -106,9 +106,9 @@ _C_LABEL(dtrace_invop_jump_addr):
 /*
  * PUSHFRAMEINSVC - macro to push a trap frame on the stack in SVC32 mode
  * This should only be used if the processor is not currently in SVC32
- * mode. The processor mode is switched to SVC mode and the trap frame is
- * stored. The SVC lr field is used to store the previous value of
- * lr in SVC mode.
+ * mode, except for data abort generated and handled by DTrace.
+ * The processor mode is switched to SVC mode and the trap frame is stored.
+ * The SVC lr field is used to store the previous value of lr in SVC mode.
  */
 #define PUSHFRAMEINSVC							   \
 	stmdb	sp, {r0-r3};		/* Save 4 registers */		   \
diff --git a/sys/arm/arm/trap-v6.c b/sys/arm/arm/trap-v6.c
index be7a10bb1f0a..60d716603f3f 100644
--- a/sys/arm/arm/trap-v6.c
+++ b/sys/arm/arm/trap-v6.c
@@ -328,6 +328,14 @@ abort_handler(struct trapframe *tf, int prefetch)
 		return;
 	}
 
+#ifdef KDTRACE_HOOKS
+	if (!usermode) {
+		if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, idx)) {
+			return;
+		}
+	}
+#endif
+
 	/*
 	 * ARM has a set of unprivileged load and store instructions
 	 * (LDRT/LDRBT/STRT/STRBT ...) which are supposed to be used in other
@@ -550,13 +558,6 @@ abort_fatal(struct trapframe *tf, u_int idx, u_int fsr, u_int far,
 #endif
 
 	usermode = TRAPF_USERMODE(tf);
-#ifdef KDTRACE_HOOKS
-	if (!usermode) {
-		if (dtrace_trap_func != NULL && (*dtrace_trap_func)(tf, far))
-			return (0);
-	}
-#endif
-
 	mode = usermode ? "user" : "kernel";
 	rw_mode  = fsr & FSR_WNR ? "write" : "read";
 	disable_interrupts(PSR_I);