git: 5143c53dfb28 - stable/13 - Fix dtrace fbt return probes on arm64

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Wed, 29 Dec 2021 10:39:55 UTC
The branch stable/13 has been updated by andrew:

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

commit 5143c53dfb289d17a796afdd1c3d38d71356533e
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2021-12-14 15:49:07 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2021-12-29 10:06:00 +0000

    Fix dtrace fbt return probes on arm64
    
    As with arm and riscv fix return fbt probes on arm64. arg0 should be
    the offset within the function of the return instruction and arg1
    should be the return value.
    
    Reviewed by:    kp, markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D33440
    
    (cherry picked from commit e3ccf4f9dee9ae39774639407264199a07fa41ff)
---
 sys/cddl/dev/dtrace/aarch64/dtrace_subr.c |  2 +-
 sys/cddl/dev/fbt/aarch64/fbt_isa.c        | 16 +++++++++++-----
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
index 9bf9f0798bb5..ede6353a803f 100644
--- a/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
+++ b/sys/cddl/dev/dtrace/aarch64/dtrace_subr.c
@@ -270,7 +270,7 @@ dtrace_invop_start(struct trapframe *frame)
 	int tmp;
 	int i;
 
-	invop = dtrace_invop(frame->tf_elr, frame, frame->tf_elr);
+	invop = dtrace_invop(frame->tf_elr, frame, frame->tf_x[0]);
 
 	tmp = (invop & LDP_STP_MASK);
 	if (tmp == STP_64 || tmp == LDP_64) {
diff --git a/sys/cddl/dev/fbt/aarch64/fbt_isa.c b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
index 6bc351ad74f6..6a21c7f403de 100644
--- a/sys/cddl/dev/fbt/aarch64/fbt_isa.c
+++ b/sys/cddl/dev/fbt/aarch64/fbt_isa.c
@@ -56,16 +56,21 @@ fbt_invop(uintptr_t addr, struct trapframe *frame, uintptr_t rval)
 	fbt = fbt_probetab[FBT_ADDR2NDX(addr)];
 
 	for (; fbt != NULL; fbt = fbt->fbtp_hashnext) {
-		if ((uintptr_t)fbt->fbtp_patchpoint == addr) {
-			cpu->cpu_dtrace_caller = addr;
+		if ((uintptr_t)fbt->fbtp_patchpoint != addr)
+			continue;
 
+		cpu->cpu_dtrace_caller = addr;
+
+		if (fbt->fbtp_roffset == 0) {
 			dtrace_probe(fbt->fbtp_id, frame->tf_x[0],
 			    frame->tf_x[1], frame->tf_x[2],
 			    frame->tf_x[3], frame->tf_x[4]);
-
-			cpu->cpu_dtrace_caller = 0;
-			return (fbt->fbtp_savedval);
+		} else {
+			dtrace_probe(fbt->fbtp_id, fbt->fbtp_roffset, rval,
+			    0, 0, 0);
 		}
+		cpu->cpu_dtrace_caller = 0;
+		return (fbt->fbtp_savedval);
 	}
 
 	return (0);
@@ -199,6 +204,7 @@ again:
 		fbt->fbtp_rval = DTRACE_INVOP_B;
 	else
 		fbt->fbtp_rval = DTRACE_INVOP_RET;
+	fbt->fbtp_roffset = (uintptr_t)instr - (uintptr_t)symval->value;
 	fbt->fbtp_savedval = *instr;
 	fbt->fbtp_patchval = FBT_PATCHVAL;
 	fbt->fbtp_hashnext = fbt_probetab[FBT_ADDR2NDX(instr)];