git: cf4ff7bd369e - main - amd64 FRED: fix dtrace fbt

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 29 Oct 2026 05:50:01 UTC
The branch main has been updated by kib:

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

commit cf4ff7bd369e42fb0a1c6f5cf2dc4fa7a990158e
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-29 03:34:45 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-29 05:48:50 +0000

    amd64 FRED: fix dtrace fbt
    
    - jump to dtrace_invop_jump_addr on kernel #BP
    - use ERETS instead of IRETQ when done
    
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 sys/amd64/amd64/exception.S            | 12 ++++++++++++
 sys/amd64/amd64/genassym.c             |  4 ++++
 sys/cddl/dev/dtrace/amd64/dtrace_asm.S | 18 ++++++++++++------
 3 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/sys/amd64/amd64/exception.S b/sys/amd64/amd64/exception.S
index b9fc09d7f26f..ba997dd0ab84 100644
--- a/sys/amd64/amd64/exception.S
+++ b/sys/amd64/amd64/exception.S
@@ -1671,6 +1671,18 @@ fred_events_handlers:
 	movq	%r14,TF_R14(%rsp)
 	movq	%r15,TF_R15(%rsp)
 	movq	%rsp, %rdi
+#ifdef KDTRACE_HOOKS
+	movl	TF_FRED_EVINFO2(%rsp),%eax
+	andl	$TF_FRED_EVINFO2_EXCMASK,%eax
+	cmpl	$(TF_FRED_EVINFO2_TYPE_INT3 | IDT_BP),%eax
+	jne	2f
+	cmpq	$0,dtrace_invop_jump_addr
+	je	1f
+	movq	$1f,dtrace_invop_calltrap_addr(%rip)
+	jmpq	*dtrace_invop_jump_addr
+1:	movq	%rsp,%rdi
+2:
+#endif
 	KMSAN_ENTER
 	call	trap_fred_k
 	KMSAN_LEAVE
diff --git a/sys/amd64/amd64/genassym.c b/sys/amd64/amd64/genassym.c
index e9ab1e23c81f..d0331e3bdfd9 100644
--- a/sys/amd64/amd64/genassym.c
+++ b/sys/amd64/amd64/genassym.c
@@ -194,8 +194,11 @@ ASSYM(TF_FRED_EVINFO2_VECMASK, TF_FRED_EVINFO2_VECMASK);
 ASSYM(TF_FRED_EVINFO2_VEC_SYSCALL, TF_FRED_EVINFO2_VEC_SYSCALL);
 ASSYM(TF_FRED_EVINFO2_SYSCALLMASK, TF_FRED_EVINFO2_TYPEMASK |
     TF_FRED_EVINFO2_VECMASK | TF_FRED_EVINFO2_LM);
+ASSYM(TF_FRED_EVINFO2_EXCMASK, TF_FRED_EVINFO2_TYPEMASK |
+    TF_FRED_EVINFO2_VECMASK);
 ASSYM(TF_FRED_EVINFO2_TYPE_EXC, TF_FRED_EVINFO2_TYPE_EXC);
 ASSYM(TF_FRED_EVINFO2_TYPE_SYSCALL, TF_FRED_EVINFO2_TYPE_SYSCALL);
+ASSYM(TF_FRED_EVINFO2_TYPE_INT3, TF_FRED_EVINFO2_TYPE_INT3);
 ASSYM(TF_FRED_EVINFO2_TYPEMASK, TF_FRED_EVINFO2_TYPEMASK);
 ASSYM(TF_FRED_EVINFO2_SYSCALLVAL, TF_FRED_EVINFO2_TYPE_SYSCALL |
     TF_FRED_EVINFO2_VEC_SYSCALL | TF_FRED_EVINFO2_LM);
@@ -292,6 +295,7 @@ ASSYM(SEL_RPL_MASK, SEL_RPL_MASK);
 
 ASSYM(IDT_NP, IDT_NP);
 ASSYM(IDT_GP, IDT_GP);
+ASSYM(IDT_BP, IDT_BP);
 
 ASSYM(__FreeBSD_version, __FreeBSD_version);
 
diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
index 217d8c2936eb..3e78d004024f 100644
--- a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
+++ b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S
@@ -56,7 +56,13 @@
 	swapgs;					\
 1:	addq	$TF_RIP,%rsp;
 
-	ENTRY(dtrace_invop_start)
+doret:	cmpb	$0,fred(%rip)
+	jne	1f
+	iretq
+1:	subq	$8,%rsp		/* fake error code, ignored by ERETS */
+	erets
+
+ENTRY(dtrace_invop_start)
 
 	KMSAN_ENTER
 
@@ -121,7 +127,7 @@ bp_push:
 	movq	32(%rsp), %rax		/* reload calling RSP */
 	movq	%rbp, (%rax)		/* store %rbp there */
 	popq	%rax			/* pop off temp */
-	iretq				/* return from interrupt */
+	jmp	doret
 	/*NOTREACHED*/
 
 bp_call:
@@ -155,7 +161,7 @@ bp_call:
 
 	popq	%rbx			/* pop temp */
 	popq	%rax			/* pop temp */
-	iretq				/* return from interrupt */
+	jmp	doret
 	/*NOTREACHED*/
 
 bp_leave:
@@ -175,13 +181,13 @@ bp_leave:
 	movq	%rbp, 32(%rsp)		/* store new %rsp */
 	movq	%rax, %rbp		/* set new %rbp */
 	popq	%rax			/* pop off temp */
-	iretq				/* return from interrupt */
+	jmp	doret
 	/*NOTREACHED*/
 
 bp_nop:
 	/* We must emulate a "nop". */
 	INTR_POP
-	iretq
+	jmp	doret
 	/*NOTREACHED*/
 
 bp_ret:
@@ -192,7 +198,7 @@ bp_ret:
 	movq	%rax, 8(%rsp)		/* store calling RIP */
 	addq	$8, 32(%rsp)		/* adjust new %rsp */
 	popq	%rax			/* pop off temp */
-	iretq				/* return from interrupt */
+	jmp	doret
 	/*NOTREACHED*/
 
 	END(dtrace_invop_start)