From nobody Mon Sep 30 12:23:39 2024 X-Original-To: dev-commits-src-main@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 4XHKx76ggrz5YDHS; Mon, 30 Sep 2024 12:23:39 +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 4XHKx73zyTz4LPx; Mon, 30 Sep 2024 12:23:39 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727699019; 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=gkbzKiFriJ8X+C3G77V3Lx8EU04ADWDzGp3bx7Ig4C0=; b=uWEi7XhbRJqZvtIlRYCi4c1HV9p57kxHYDJc5dgs2Ktgfv9b8YKwOnNEUrZSvM48VzWFGN NUfNdUZlpF+0mp3oRrdA6D2wBMsLXlMzfogXYAJ8SmFXzxz1/o/DrJ533074DvnhBvQCKg H3RWhK4Iu2b7pnl/aGs3F5gU+4eRYyY7lnPkDHeDo9jN9T7FsJ+AlUVA7FZ4Sebda0Ib41 N4CStUvunT6WHGBRrO5+r59FgswxZS4R/wAXuo8pjdgw2K5W7s0qMnLSnLBIXZXmsypC/2 kComJjBYlitvl0YUik6z1sRuEDZDWA8LSEagdk0ellrSAmoF/y0fNxTVFGeG+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1727699019; 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=gkbzKiFriJ8X+C3G77V3Lx8EU04ADWDzGp3bx7Ig4C0=; b=IOM9RU425PGnIkfajJzB7z7HqiwqTDnuYfb1/rpkZxwIQu+zrwfiCNAEizGGNN2r3IcIVz 0OdB5sOBRGlpS3DDZoeHwgknNZkTOl0cnr8RNeqX1AaBpJHRuPVl7qvkfPxUI6Jqw9uTGl 08+OaCV6xS25LIbiobcewiEKr3GoYsfTOsK9pf3S0lMJ/m+keYExtGPMKTU1C/AuOEyXz7 hb/9FBLylf8gc//r5PWdxhcKJmCWhu0frXSUUflIBHR2U+2g8I5XldcDmPvYu4pYdSZHoM d9DJ4rwc8QPyypHp1UFQPmHV+Ch4f+xpG+czZIsmmE+pprXHcg4G9UbB096Fig== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1727699019; a=rsa-sha256; cv=none; b=sj4wavq424K2iA3+x1x8OSh2WUzCy6TzmhQYjSJDbG1F+Ob4O1l1FwO+Eg+znhKh/f2cVn Yj6cVWg+actwiJ81mPQGmxJPO2EFROhr37btfOwv4LCVko5Sfg+nqsz082zthsGasUoUUS 5ihtpoahFUd++qlYRlfZSdlybL2yOnhVWP3MVN2jZBgJio8R28O1ectuIaofrdTFlbgThQ gAfgzLvErwscB6U7BRDrios0zn4BJcWhPmy18weH9rQhTipy9Ylk6RVR54W3dqRDQiIkIC vteNzXbXgnsMBpEBQv0T96Gh8YAy12K8Tahr9O9SoIikE3+ts1u/Udlj0avOSg== 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 4XHKx739nJzsZn; Mon, 30 Sep 2024 12:23:39 +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 48UCNd3K071011; Mon, 30 Sep 2024 12:23:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 48UCNdNK071008; Mon, 30 Sep 2024 12:23:39 GMT (envelope-from git) Date: Mon, 30 Sep 2024 12:23:39 GMT Message-Id: <202409301223.48UCNdNK071008@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: aab60068943d - main - arm64: Support SVE in ptrace and core dumps List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@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/main X-Git-Reftype: branch X-Git-Commit: aab60068943d733b0b4573e5481c543ab3d45a00 Auto-Submitted: auto-generated The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=aab60068943d733b0b4573e5481c543ab3d45a00 commit aab60068943d733b0b4573e5481c543ab3d45a00 Author: Andrew Turner AuthorDate: 2024-09-27 13:37:17 +0000 Commit: Andrew Turner CommitDate: 2024-09-30 12:04:23 +0000 arm64: Support SVE in ptrace and core dumps Add the NT_ARM_SVE note type and use it to access the SVE registers from ptrace. This allows userspace to modify the full SVE register values. Try to follow the Linux semantics to allow debuggers to use this with minimal changes. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D43309 --- sys/arm64/arm64/vfp.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++ sys/arm64/include/reg.h | 13 +++++ sys/sys/elf_common.h | 1 + 3 files changed, 155 insertions(+) diff --git a/sys/arm64/arm64/vfp.c b/sys/arm64/arm64/vfp.c index d57927991c03..a3aa77ed6180 100644 --- a/sys/arm64/arm64/vfp.c +++ b/sys/arm64/arm64/vfp.c @@ -30,12 +30,14 @@ #ifdef VFP #include #include +#include #include #include #include #include #include #include +#include #include #include @@ -918,6 +920,145 @@ sve_init(const void *dummy __unused) } SYSINIT(sve, SI_SUB_SMP, SI_ORDER_ANY, sve_init, NULL); +static bool +get_arm64_sve(struct regset *rs, struct thread *td, void *buf, + size_t *sizep) +{ + struct svereg_header *header; + struct pcb *pcb; + size_t buf_size; + uint16_t sve_flags; + + pcb = td->td_pcb; + + /* If there is no SVE support in HW then we don't support NT_ARM_SVE */ + if (pcb->pcb_sve_len == 0) + return (false); + + sve_flags = 0; + if ((pcb->pcb_fpflags & PCB_FP_SVEVALID) == 0) { + /* If SVE hasn't been used yet provide the VFP registers */ + buf_size = sizeof(struct fpreg); + sve_flags |= SVEREG_FLAG_FP; + } else { + /* We have SVE registers */ + buf_size = sve_buf_size(td); + sve_flags |= SVEREG_FLAG_SVE; + KASSERT(pcb->pcb_svesaved != NULL, ("%s: no saved sve", + __func__)); + } + + if (buf != NULL) { + KASSERT(*sizep == sizeof(struct svereg_header) + buf_size, + ("%s: invalid size", __func__)); + + if (td == curthread && (pcb->pcb_fpflags & PCB_FP_STARTED) != 0) + vfp_save_state(td, pcb); + + header = buf; + memset(header, 0, sizeof(*header)); + + header->sve_size = sizeof(struct svereg_header) + buf_size; + header->sve_maxsize = sizeof(struct svereg_header) + + sve_max_buf_size(); + header->sve_vec_len = pcb->pcb_sve_len; + header->sve_max_vec_len = sve_max_vector_len; + header->sve_flags = sve_flags; + + if ((sve_flags & SVEREG_FLAG_REGS_MASK) == SVEREG_FLAG_FP) { + struct fpreg *fpregs; + + fpregs = (void *)(&header[1]); + memcpy(fpregs->fp_q, pcb->pcb_fpustate.vfp_regs, + sizeof(fpregs->fp_q)); + fpregs->fp_cr = pcb->pcb_fpustate.vfp_fpcr; + fpregs->fp_sr = pcb->pcb_fpustate.vfp_fpsr; + } else { + memcpy((void *)(&header[1]), pcb->pcb_svesaved, + buf_size); + } + } + *sizep = sizeof(struct svereg_header) + buf_size; + + return (true); +} + +static bool +set_arm64_sve(struct regset *rs, struct thread *td, void *buf, size_t size) +{ + struct svereg_header *header; + struct pcb *pcb; + size_t buf_size; + uint16_t sve_flags; + + pcb = td->td_pcb; + + /* If there is no SVE support in HW then we don't support NT_ARM_SVE */ + if (pcb->pcb_sve_len == 0) + return (false); + + sve_flags = 0; + if ((pcb->pcb_fpflags & PCB_FP_SVEVALID) == 0) { + /* + * If the SVE state is invalid it provide the FP registers. + * This may be beause it hasn't been used, or it has but + * was switched out in a system call. + */ + buf_size = sizeof(struct fpreg); + sve_flags |= SVEREG_FLAG_FP; + } else { + /* We have SVE registers */ + MPASS(pcb->pcb_svesaved != NULL); + buf_size = sve_buf_size(td); + sve_flags |= SVEREG_FLAG_SVE; + KASSERT(pcb->pcb_svesaved != NULL, ("%s: no saved sve", + __func__)); + } + + if (size != sizeof(struct svereg_header) + buf_size) + return (false); + + header = buf; + /* Sanity checks on the header */ + if (header->sve_size != sizeof(struct svereg_header) + buf_size) + return (false); + + if (header->sve_maxsize != sizeof(struct svereg_header) + + sve_max_buf_size()) + return (false); + + if (header->sve_vec_len != pcb->pcb_sve_len) + return (false); + + if (header->sve_max_vec_len != sve_max_vector_len) + return (false); + + if (header->sve_flags != sve_flags) + return (false); + + if ((sve_flags & SVEREG_FLAG_REGS_MASK) == SVEREG_FLAG_FP) { + struct fpreg *fpregs; + + fpregs = (void *)(&header[1]); + memcpy(pcb->pcb_fpustate.vfp_regs, fpregs->fp_q, + sizeof(fpregs->fp_q)); + pcb->pcb_fpustate.vfp_fpcr = fpregs->fp_cr; + pcb->pcb_fpustate.vfp_fpsr = fpregs->fp_sr; + } else { + /* Restore the SVE registers */ + memcpy(pcb->pcb_svesaved, (void *)(&header[1]), buf_size); + } + + return (true); +} + +static struct regset regset_arm64_sve = { + .note = NT_ARM_SVE, + .get = get_arm64_sve, + .set = set_arm64_sve, +}; +ELF_REGSET(regset_arm64_sve); + struct fpu_kern_ctx * fpu_kern_alloc_ctx(u_int flags) { diff --git a/sys/arm64/include/reg.h b/sys/arm64/include/reg.h index c699752197a8..4226385480e8 100644 --- a/sys/arm64/include/reg.h +++ b/sys/arm64/include/reg.h @@ -63,6 +63,19 @@ struct fpreg32 { int dummy; }; +#define SVEREG_FLAG_REGS_MASK 0x0001 +#define SVEREG_FLAG_FP 0x0000 +#define SVEREG_FLAG_SVE 0x0001 + +struct svereg_header { + __uint32_t sve_size; + __uint32_t sve_maxsize; + __uint16_t sve_vec_len; + __uint16_t sve_max_vec_len; + __uint16_t sve_flags; + __uint16_t sve_reserved; +}; + struct dbreg { __uint8_t db_debug_ver; __uint8_t db_nbkpts; diff --git a/sys/sys/elf_common.h b/sys/sys/elf_common.h index 6cb92d1011fe..ec5bbbf9f0e6 100644 --- a/sys/sys/elf_common.h +++ b/sys/sys/elf_common.h @@ -826,6 +826,7 @@ typedef struct { #define NT_X86_XSTATE 0x202 /* x86 XSAVE extended state. */ #define NT_ARM_VFP 0x400 /* ARM VFP registers */ #define NT_ARM_TLS 0x401 /* ARM TLS register */ +#define NT_ARM_SVE 0x405 /* ARM SVE registers */ #define NT_ARM_ADDR_MASK 0x406 /* arm64 address mask (e.g. for TBI) */ /* GNU note types. */