git: 52850d1831de - stable/15 - dtrace/arm64: de-pessimize dtrace_copy
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 28 Sep 2026 15:14:33 UTC
The branch stable/15 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=52850d1831de7a3e1ab4aeba3919b26f68f4b7dc
commit 52850d1831de7a3e1ab4aeba3919b26f68f4b7dc
Author: Benjamin Jacobs <freebsd@dev.thsi.be>
AuthorDate: 2026-09-09 09:57:12 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-09-28 13:38:01 +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
(cherry picked from commit 464b29857ff18801aca49d1001643c5cdd1324e8)
---
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-- */