From nobody Tue Aug 23 20:46:52 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4MC1Vj0KKVz4ZFBX; Tue, 23 Aug 2022 20:46:53 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4MC1Vh6fRfz3YyV; Tue, 23 Aug 2022 20:46:52 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661287612; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FxARkVgiooEPbzUwTl3JNlCjBt4jXnjZ//KY1dXHMAw=; b=uSCDdWD32w1XJwVTKQONqHOCL2mHSP65Spc+mKGUarAWQWPAZuHpPiBgfm2/GY2hMpWSBq bUOA18OZZmcRO1hWu6UzFnV5l85pmlPGrIeeOCarR0JYvl641froN62GbK/iNFZ5b7bXU6 mZhyBkXzA4M93AbcZmvOFHWhwnIzcIL1CrV59sORMpFozJTpe/hng5Bhx6jr6//HfVGL2p Xpu9XdVosf4+pANPCJ6VPpeICjrPOqjqzjDmUeL7xan7/y2jm/OEo/9bTVNKCcs1UnTFzm YdRYMamFtm8J/VNy3+QwWUeCrGd/4N9nhyoOYo9JkYPTppVCCEJ8zo9QOXrCKw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4MC1Vh5ShJzk9n; Tue, 23 Aug 2022 20:46:52 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 27NKkqfu049241; Tue, 23 Aug 2022 20:46:52 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 27NKkqAi049240; Tue, 23 Aug 2022 20:46:52 GMT (envelope-from git) Date: Tue, 23 Aug 2022 20:46:52 GMT Message-Id: <202208232046.27NKkqAi049240@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Mark Johnston Subject: git: 761d4d350d1a - stable/13 - dtrace/amd64: Implement emulation of call instructions List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 761d4d350d1acd44724ab0bfa1d4940613f5f153 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1661287612; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=FxARkVgiooEPbzUwTl3JNlCjBt4jXnjZ//KY1dXHMAw=; b=c3xw/UwvmslSpwcxbnfv/39negpwxihoWX+J6z96l3tzbjnasQ17m+uWrOOHNFBY7cYmqy WCK4iqyheP/I6lIWv7UuvB9Frgte9Pe7J9PgSAqcsNw1cTGCxGbYl5YFVNuorpWGzGk/fq IP+bYgqQcfgEo7XSpKw6jnhQCb7rlSnUAArj/7bsRz47pLl3FIrBnRyKvXir/2nFSznE1D AukCMkgAer4RcOPjMYJhVCkY6Q1WLq1JCmvTRvQJiOdpLjT9tWNPDqIYXEAAov7eFUHLLi wgIK4DS9ka6CV71GvuVfwDFs3ZMAhYoXaqnNT0jQSEdcFKOYczSSylbB69bTVA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1661287612; a=rsa-sha256; cv=none; b=OPD0DKycPcfh587I3nQz8fGXlqSC+c4GSMHT74HHe3vubnSfFnOhdUqrFeeFWUTltFTmPy m7fnWSgc8jjr6LtWPwXTABdeSZsBtasdCbpazAL0raJ5XoIt3SW5knWzLKe+97sCs764bc wB0IDzT00YPFI8ptHlSCZJidgBfyWwHBFd6AQ87UoFVg4OAx3Irvr2MfSUCT2eBddqJZ54 +ej7i7NMl9U3bgMpW2ZlC7h+dvif/+Y8tTvbC5inBDFuq2BCiQwooeRbfxKgXICGrhXcuD l69TFdIDyKysQ0S91XSkgKFQgBCPTcRSQLalkZ3auNFPTQIcbicUP8slIwNVCw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=761d4d350d1acd44724ab0bfa1d4940613f5f153 commit 761d4d350d1acd44724ab0bfa1d4940613f5f153 Author: Mark Johnston AuthorDate: 2022-08-09 20:08:13 +0000 Commit: Mark Johnston CommitDate: 2022-08-23 20:05:07 +0000 dtrace/amd64: Implement emulation of call instructions Here, the provider is responsible for updating the trapframe to redirect control flow and for computing the return address. Once software-saved registers are restored, the emulation shifts the remaining context down on the stack to make space for the return address, then copies the address provided by the invop handler. dtrace_invop() is modified to allocate temporary storage space on the stack for use by the provider to return the return address. This is to support a new provider for amd64 which can instrument arbitrary instructions, not just function entry and exit instructions as FBT does. In collaboration with: christos Sponsored by: Google, Inc. (GSoC 2022) Sponsored by: The FreeBSD Foundation (cherry picked from commit 3ba8e9dc4a0e0e9c35cfadfe25379871ce581697) --- .../contrib/opensolaris/uts/common/sys/dtrace.h | 4 ++ sys/cddl/dev/dtrace/amd64/dtrace_asm.S | 51 +++++++++++++++++++++- sys/cddl/dev/dtrace/amd64/dtrace_subr.c | 11 ++--- 3 files changed, 59 insertions(+), 7 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h index c15cc39189b1..5cad5a3b18c9 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/dtrace.h @@ -2440,6 +2440,10 @@ extern void dtrace_helpers_destroy(proc_t *); #define DTRACE_INVOP_NOP 4 #define DTRACE_INVOP_RET 5 +#if defined(__amd64) +#define DTRACE_INVOP_CALL 6 +#endif + #elif defined(__powerpc__) #define DTRACE_INVOP_BCTR 1 diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S index 13bd930d5f2f..3270aedfb3c8 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_asm.S +++ b/sys/cddl/dev/dtrace/amd64/dtrace_asm.S @@ -59,6 +59,8 @@ swapgs; \ 1: addq $TF_RIP,%rsp; +.globl dtrace_invop_callsite +.type dtrace_invop_callsite,@function ENTRY(dtrace_invop_start) @@ -70,11 +72,22 @@ movq TF_RIP(%rsp), %rdi decq %rdi movq %rsp, %rsi - movq TF_RAX(%rsp), %rdx + + /* + * Allocate some scratch space to let the invop handler return a value. + * This is needed when emulating "call" instructions. + */ + subq $16, %rsp + movq %rsp, %rdx + call dtrace_invop - ALTENTRY(dtrace_invop_callsite) +dtrace_invop_callsite: + addq $16, %rsp + cmpl $DTRACE_INVOP_PUSHL_EBP, %eax je bp_push + cmpl $DTRACE_INVOP_CALL, %eax + je bp_call cmpl $DTRACE_INVOP_LEAVE, %eax je bp_leave cmpl $DTRACE_INVOP_NOP, %eax @@ -110,6 +123,40 @@ bp_push: iretq /* return from interrupt */ /*NOTREACHED*/ +bp_call: + /* + * Emulate a "call" instruction. The invop handler must have already + * updated the saved copy of %rip in the register set. It's our job to + * pull the hardware-saved registers down to make space for the return + * address, which is provided by the invop handler in our scratch + * space. + */ + INTR_POP + subq $16, %rsp /* make room for %rbp */ + pushq %rax /* push temp */ + pushq %rbx /* push temp */ + + movq 32(%rsp), %rax /* load calling RIP */ + movq %rax, 16(%rsp) /* store calling RIP */ + movq 40(%rsp), %rax /* load calling CS */ + movq %rax, 24(%rsp) /* store calling CS */ + movq 48(%rsp), %rax /* load calling RFLAGS */ + movq %rax, 32(%rsp) /* store calling RFLAGS */ + movq 56(%rsp), %rax /* load calling RSP */ + subq $8, %rax /* make room for return address */ + movq %rax, 40(%rsp) /* store calling RSP */ + movq 64(%rsp), %rax /* load calling SS */ + movq %rax, 48(%rsp) /* store calling SS */ + + movq -(TF_RIP - 16)(%rsp), %rax /* load return address */ + movq 40(%rsp), %rbx /* reload calling RSP */ + movq %rax, (%rbx) /* store return address */ + + popq %rbx /* pop temp */ + popq %rax /* pop temp */ + iretq /* return from interrupt */ + /*NOTREACHED*/ + bp_leave: /* * We must emulate a "leave", which is the same as a "movq %rbp, %rsp" diff --git a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c index 4f9d9995cbab..f4fb70f80a6b 100644 --- a/sys/cddl/dev/dtrace/amd64/dtrace_subr.c +++ b/sys/cddl/dev/dtrace/amd64/dtrace_subr.c @@ -50,7 +50,7 @@ extern void dtrace_getnanotime(struct timespec *tsp); extern int (*dtrace_invop_jump_addr)(struct trapframe *); -int dtrace_invop(uintptr_t, struct trapframe *, uintptr_t); +int dtrace_invop(uintptr_t, struct trapframe *, void **); int dtrace_invop_start(struct trapframe *frame); void dtrace_invop_init(void); void dtrace_invop_uninit(void); @@ -63,15 +63,16 @@ typedef struct dtrace_invop_hdlr { dtrace_invop_hdlr_t *dtrace_invop_hdlr; int -dtrace_invop(uintptr_t addr, struct trapframe *frame, uintptr_t eax) +dtrace_invop(uintptr_t addr, struct trapframe *frame, void **scratch) { dtrace_invop_hdlr_t *hdlr; int rval; - for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) - if ((rval = hdlr->dtih_func(addr, frame, eax)) != 0) + for (hdlr = dtrace_invop_hdlr; hdlr != NULL; hdlr = hdlr->dtih_next) { + rval = hdlr->dtih_func(addr, frame, (uintptr_t)scratch); + if (rval != 0) return (rval); - + } return (0); }