From nobody Mon Sep 02 08:50:37 2024 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 4Wy2XG3FMLz5Mnnf; Mon, 02 Sep 2024 08:50:38 +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 "R11" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4Wy2XF6vh1z428W; Mon, 2 Sep 2024 08:50:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725267038; 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=IeW3xNlzfzes12auYJumS40hCPATrVQc/Tp5aRmV6qU=; b=bB2k7iFGC/BAyUIqKcmH1T5a493OukXvqHpMGpx6Dp0b7N5Iu5KMAim1bsS8xXD2sNj2vm 8GiE/xwMcwviirr495ZhI3C1c8wFoyE/GQxZrKEnpzhMt5kv0q0xWnTVVGRlG9XOnwJ+Ug pUJtYp7GuAgBHfKxHba5uPrtaSB9Xw/OTvNAgroz+PAapyReJj8/m+QKQPheRwBIZGqK7C FzoYGqzV2sD9lFlhLS8+buJ8UDJezwPFR6utYZkvo8TxoJ0qCRaXZWJ7ydkiKOZadSqr9D iW6R/HFELZpYhEo9McVVKfNmLMA0BwfSkbcIGtq03e9ib7aQ83nOsudpJesrzQ== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1725267038; a=rsa-sha256; cv=none; b=OR2tcjlUKwL8ee+oZ3FfApUUOV3rvgDccqu3uj2LFMGWFRry1d1biFg+6sm0Ir02wawbkp Sfxa8YdsljsaraZ9UuRccP38XPb4eqzE+yLfsIme2CvEucbO+NGS4UXDO8E92o6yXeL0uj iDV1ZS+eWZ2vWZqVuzB1JZjWJ3kJRRStR/7G03oTdaebYCQmPRxOPDnbh/OMjSi0QD7+sG wwZvIVUYYvqWRIbRoccLyv2pMv7KK7x0Etg6ueLiKDihLwNj4vxBXxleJZkPPbaRTxn8Av K9jYB+mqimXNevH344SGTrQ8Gq92UOkljCx39OK2vsIXVa9X+VtpczwbL1GdEA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1725267038; 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=IeW3xNlzfzes12auYJumS40hCPATrVQc/Tp5aRmV6qU=; b=QQYSpmlbFmjjv6q5QFpJg3Qsa3TJrvT8zkgq+NaeWSd3vb8srAGfJqn8gi41wxc/ooSjC+ a7hmQ9N08IzYebWQkU2odqXhkoOR52z+83+byeNedGsxr5KOHyUIxh0x0/GymAW3wFuDdf jvNHI/GwEkWgKJBKP5+y3IKvwEUt49ask3QgOnNOJiAZhsL5F/hq7Em/mUV+Jfuy1SjTbH dbsKsgetDntbPzvBKehFQ/AQU4V4tyq7W/BiBVMTKLOsPGcBf9v0KiCGVkSo90jpZ8u4gG IA1POeGqVkN21fnF1kNlHh63Fy1w32zorWgWtfKq5DEcEswAwxJJSqQyWnOo9A== 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 4Wy2XF678bz156f; Mon, 2 Sep 2024 08:50:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4828obAR006910; Mon, 2 Sep 2024 08:50:37 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4828obmq006907; Mon, 2 Sep 2024 08:50:37 GMT (envelope-from git) Date: Mon, 2 Sep 2024 08:50:37 GMT Message-Id: <202409020850.4828obmq006907@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Andrew Turner Subject: git: 254d54f0733f - stable/14 - arm64: Support passing more registers to signals 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: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 254d54f0733fe139108cb576cf37f16102659181 Auto-Submitted: auto-generated The branch stable/14 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=254d54f0733fe139108cb576cf37f16102659181 commit 254d54f0733fe139108cb576cf37f16102659181 Author: Andrew Turner AuthorDate: 2024-03-21 10:13:16 +0000 Commit: Andrew Turner CommitDate: 2024-09-02 08:44:19 +0000 arm64: Support passing more registers to signals To support recent extensions to the Arm architecture we may need to store more or larger registers when sending a signal. To support this create a list of these extra registers. Userspace that needs to access a register in the signal handler can then walk the list to find the correct register struct and read/write its contents. Reviewed by: kib, markj (earlier version) Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D43302 (cherry picked from commit 7e6437c08415ade75403f1ecad75167257e8ea3c) --- sys/arm64/arm64/exec_machdep.c | 85 +++++++++++++++++++++++++++++++++++++++--- sys/arm64/include/ucontext.h | 16 +++++++- 2 files changed, 94 insertions(+), 7 deletions(-) diff --git a/sys/arm64/arm64/exec_machdep.c b/sys/arm64/arm64/exec_machdep.c index 4efa3ceaae40..bc4ee178db23 100644 --- a/sys/arm64/arm64/exec_machdep.c +++ b/sys/arm64/arm64/exec_machdep.c @@ -462,8 +462,12 @@ int set_mcontext(struct thread *td, mcontext_t *mcp) { #define PSR_13_MASK 0xfffffffful + struct arm64_reg_context ctx; struct trapframe *tf = td->td_frame; uint64_t spsr; + vm_offset_t addr; + int error; + bool done; spsr = mcp->mc_gpregs.gp_spsr; #ifdef COMPAT_FREEBSD13 @@ -502,8 +506,35 @@ set_mcontext(struct thread *td, mcontext_t *mcp) READ_SPECIALREG(mdscr_el1) | MDSCR_SS); isb(); } + set_fpcontext(td, mcp); + /* Read any register contexts we find */ + if (mcp->mc_ptr != 0) { + addr = mcp->mc_ptr; + + done = false; + do { + if (!__is_aligned(addr, + _Alignof(struct arm64_reg_context))) + return (EINVAL); + + error = copyin((const void *)addr, &ctx, sizeof(ctx)); + if (error != 0) + return (error); + + switch (ctx.ctx_id) { + case ARM64_CTX_END: + done = true; + break; + default: + return (EINVAL); + } + + addr += ctx.ctx_size; + } while (!done); + } + return (0); #undef PSR_13_MASK } @@ -586,6 +617,31 @@ sys_sigreturn(struct thread *td, struct sigreturn_args *uap) return (EJUSTRETURN); } +static bool +sendsig_ctx_end(struct thread *td, vm_offset_t *addrp) +{ + struct arm64_reg_context end_ctx; + vm_offset_t ctx_addr; + + *addrp -= sizeof(end_ctx); + ctx_addr = *addrp; + + memset(&end_ctx, 0, sizeof(end_ctx)); + end_ctx.ctx_id = ARM64_CTX_END; + end_ctx.ctx_size = sizeof(end_ctx); + + if (copyout(&end_ctx, (void *)ctx_addr, sizeof(end_ctx)) != 0) + return (false); + + return (true); +} + +typedef bool(*ctx_func)(struct thread *, vm_offset_t *); +static const ctx_func ctx_funcs[] = { + sendsig_ctx_end, /* Must be first to end the linked list */ + NULL, +}; + void sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) { @@ -594,6 +650,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) struct trapframe *tf; struct sigframe *fp, frame; struct sigacts *psp; + vm_offset_t addr; int onstack, sig; td = curthread; @@ -613,19 +670,15 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Allocate and validate space for the signal handler context. */ if ((td->td_pflags & TDP_ALTSTACK) != 0 && !onstack && SIGISMEMBER(psp->ps_sigonstack, sig)) { - fp = (struct sigframe *)((uintptr_t)td->td_sigstk.ss_sp + + addr = ((uintptr_t)td->td_sigstk.ss_sp + td->td_sigstk.ss_size); #if defined(COMPAT_43) td->td_sigstk.ss_flags |= SS_ONSTACK; #endif } else { - fp = (struct sigframe *)td->td_frame->tf_sp; + addr = td->td_frame->tf_sp; } - /* Make room, keeping the stack aligned */ - fp--; - fp = (struct sigframe *)STACKALIGN(fp); - /* Fill in the frame to copy out */ bzero(&frame, sizeof(frame)); get_mcontext(td, &frame.sf_uc.uc_mcontext, 0); @@ -637,6 +690,26 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) mtx_unlock(&psp->ps_mtx); PROC_UNLOCK(td->td_proc); + for (int i = 0; ctx_funcs[i] != NULL; i++) { + if (!ctx_funcs[i](td, &addr)) { + /* Process has trashed its stack. Kill it. */ + CTR4(KTR_SIG, + "sendsig: frame sigexit td=%p fp=%#lx func[%d]=%p", + td, addr, i, ctx_funcs[i]); + PROC_LOCK(p); + sigexit(td, SIGILL); + /* NOTREACHED */ + } + } + + /* Point at the first context */ + frame.sf_uc.uc_mcontext.mc_ptr = addr; + + /* Make room, keeping the stack aligned */ + fp = (struct sigframe *)addr; + fp--; + fp = (struct sigframe *)STACKALIGN(fp); + /* Copy the sigframe out to the user's stack. */ if (copyout(&frame, fp, sizeof(*fp)) != 0) { /* Process has trashed its stack. Kill it. */ diff --git a/sys/arm64/include/ucontext.h b/sys/arm64/include/ucontext.h index e9b914315a19..dedbd061ec6b 100644 --- a/sys/arm64/include/ucontext.h +++ b/sys/arm64/include/ucontext.h @@ -51,15 +51,29 @@ struct fpregs { int fp_pad; }; +/* + * Support for registers that don't fit into gpregs or fpregs, e.g. SVE. + * There are some registers that have been added so are optional. To support + * these create an array of headers that point at the register data. + */ +struct arm64_reg_context { + __uint32_t ctx_id; + __uint32_t ctx_size; +}; + +#define ARM64_CTX_END 0xa5a5a5a5 + struct __mcontext { struct gpregs mc_gpregs; struct fpregs mc_fpregs; int mc_flags; #define _MC_FP_VALID 0x1 /* Set when mc_fpregs has valid data */ int mc_pad; /* Padding */ - __uint64_t mc_spare[8]; /* Space for expansion, set to zero */ + __uint64_t mc_ptr; /* Address of extra_regs struct */ + __uint64_t mc_spare[7]; /* Space for expansion, set to zero */ }; + typedef struct __mcontext mcontext_t; #ifdef COMPAT_FREEBSD32