From nobody Mon Oct 21 15:05:13 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 4XXJWt0XjYz5ZNSZ; Mon, 21 Oct 2024 15:05:14 +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 4XXJWs3hpdz4fRB; Mon, 21 Oct 2024 15:05:13 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729523113; 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=LcOhJTVwBpnQW2X1GCOsei0+1EnSKFhajxBtyN1ZqsU=; b=FY8hMwQp1kNdgCFhBxuSd7d4Ebb4ILIahiYMtVpl6mY7E6U+uqWrC53mquADoairRlHgpW g5p6ye8Xj2kpIx6+aEhz4dIWdBdedM6jgNqjxXupt1EsP+MYdlEm9MqW8w8ph2OYjklDlA mHy8P5Y0Ci4yKn6uxIsBdcL/AVTSKGiX/WdfDk1IVpAnX/VINB/BocPDHXby0TGCAqKJiH pcoddQ1MzuxF8pLG4H6zJDu1QZw/hYYe8MStOOEGIuVoSrG/78DxkkshBxOaptr8xspCGm ZXeiy0KmnWS0SE4PF4aaRcypN1uwN+fdN5bZfQXmL0yf64/cSVF2l34a3hh6KQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1729523113; 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=LcOhJTVwBpnQW2X1GCOsei0+1EnSKFhajxBtyN1ZqsU=; b=vG1Mc+REzBmWXP7O1OQL72bTRZ50H2VIRMEuK7GjYNtby6HS+OyI/KTwjCint8ZB5lBa2F tybfPB1IMMhpcgLH9q0ehzJ9g8OydJj8RIxAeSk7yN+2RuVNDNBXJBf5tUrzWLzUnifVH1 pD5R1jAOGjaa3D+q74qdFY+DQi5FIC+O5QZpPJe0xXNRZiq6wxs5v+i8mTzGQU0zqg9snO 62uGaADgM/OdekZXq8ygSdRe+tjfrtGZWPvysC70q468+UI/VZe3BUyNWE7Lu/ww0kWuR4 nHpI6X6dbZPcd0OBR+2xcJqvhThwcFNGVmHUOpOn62i+5bT6nAmhKtOwQimR2Q== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1729523113; a=rsa-sha256; cv=none; b=Jp+AR4NYtmsc8WoLwncsA2IOESykgKvGW+4m9Zwdf/MCNlqh+hIKCYaJdqijM0UII6KGaN /raM6UyyiErORaA1NogRgjZ/kgVKcMNT63D22UyMMe656a1eLR+n6xGGoG9ev0jqe3htwj 64HJcnWo1w2NBLjaapivY+HEr5DoW2IEnkXhMaiAvJsIVJE93mxhfbTJ/ej2pG3kIlygrY DWTqpgTQS8cWq3UQH5OjACdua8QrmEmkX+11G+ReN8mMY/Uvm4Gz+JJ+KCtLS3euL8YrgI 9f0d5c7hPI/z/t0jPwfLQt1PQy/oe1wzyPO3gOEs6rfpFsLR048hlGjSmImYuw== 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 4XXJWs3K0jzbDV; Mon, 21 Oct 2024 15:05:13 +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 49LF5DrL047090; Mon, 21 Oct 2024 15:05:13 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 49LF5DPS047087; Mon, 21 Oct 2024 15:05:13 GMT (envelope-from git) Date: Mon, 21 Oct 2024 15:05:13 GMT Message-Id: <202410211505.49LF5DPS047087@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: f7caa6fb7489 - stable/14 - arm64: Support SVE in ptrace and core dumps 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: f7caa6fb7489b7e9721f064e39050614ae0fc875 Auto-Submitted: auto-generated The branch stable/14 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=f7caa6fb7489b7e9721f064e39050614ae0fc875 commit f7caa6fb7489b7e9721f064e39050614ae0fc875 Author: Andrew Turner AuthorDate: 2024-09-27 13:37:17 +0000 Commit: Andrew Turner CommitDate: 2024-10-21 15:03:27 +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 (cherry picked from commit aab60068943d733b0b4573e5481c543ab3d45a00) --- 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 b9e82cb8fa35..0c7d7e2b2fc3 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. */