git: 464b29857ff1 - main - dtrace/arm64: de-pessimize dtrace_copy

From: Mark Johnston <markj_at_FreeBSD.org>
Date: Thu, 10 Sep 2026 09:16:01 UTC
The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=464b29857ff18801aca49d1001643c5cdd1324e8

commit 464b29857ff18801aca49d1001643c5cdd1324e8
Author:     Benjamin Jacobs <freebsd@dev.thsi.be>
AuthorDate: 2026-09-09 09:57:12 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-10 09:14:29 +0000

    dtrace/arm64: de-pessimize dtrace_copy
    
    When DTrace catches a data abort exception it resumes execution on the
    next instruction. If a probe executes copyinto from unmapped memory,
    then dtrace_copy keeps faulting on successive bytes until the loop
    counter is exhausted. Detect the situation by witnessing the absence
    of zero-extension from an aborted unprivileged load.
    
    Reviewed by:    markj
    MFC after:      2 weeks
    Differential Revision:  https://reviews.freebsd.org/D59341
---
 sys/cddl/dev/dtrace/aarch64/dtrace_asm.S | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_asm.S b/sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
index a934733251a3..decca6f79e0c 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_asm.S
@@ -109,8 +109,11 @@ dtrace_copy(uintptr_t uaddr, uintptr_t kaddr, size_t size)
 ENTRY(dtrace_copy)
 	cbz	x2, 2f		/* If len == 0 then skip loop */
 1:
-	ldtrb	w4, [x0]	/* Load from uaddr */
+	mvn	x4, xzr		/* Set all bits */
+	ldtrb	w4, [x0]	/* Load from uaddr or raise data abort */
 	add	x0, x0, #1
+	lsr	x3, x4, #32	/* Extract zero-extended high bits */
+	cbnz	x3, 2f		/* If high bits != 0 then break */
 	strb	w4, [x1], #1	/* Store in kaddr */
 	sub	x2, x2, #1	/* len-- */
 	cbnz	x2, 1b
@@ -120,15 +123,16 @@ END(dtrace_copy)
 
 /*
 void
-dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size,
-    volatile uint16_t *flags)
-XXX: Check for flags?
+dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
 */
 ENTRY(dtrace_copystr)
 	cbz     x2, 2f          /* If len == 0 then skip loop */
 1:
-	ldtrb	w4, [x0]	/* Load from uaddr */
+	mvn	x4, xzr		/* Set all bits */
+	ldtrb	w4, [x0]	/* Load from uaddr or raise data abort */
 	add	x0, x0, #1
+	lsr	x3, x4, #32	/* Extract zero-extended high bits */
+	cbnz	x3, 2f		/* If high bits != 0 then break */
 	strb    w4, [x1], #1    /* Store in kaddr */
 	cbz     w4, 2f          /* If == 0 then break */
 	sub     x2, x2, #1      /* len-- */