Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/808350/?format=api
{ "id": 808350, "url": "http://patchwork.ozlabs.org/api/patches/808350/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-imx/patch/1504198860-12951-14-git-send-email-Dave.Martin@arm.com/", "project": { "id": 19, "url": "http://patchwork.ozlabs.org/api/projects/19/?format=api", "name": "Linux IMX development", "link_name": "linux-imx", "list_id": "linux-imx-kernel.lists.patchwork.ozlabs.org", "list_email": "linux-imx-kernel@lists.patchwork.ozlabs.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<1504198860-12951-14-git-send-email-Dave.Martin@arm.com>", "list_archive_url": null, "date": "2017-08-31T17:00:45", "name": "[v2,13/28] arm64/sve: Signal handling support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "212e9199754d43944a486148848c445874ba7744", "submitter": { "id": 26612, "url": "http://patchwork.ozlabs.org/api/people/26612/?format=api", "name": "Dave Martin", "email": "Dave.Martin@arm.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-imx/patch/1504198860-12951-14-git-send-email-Dave.Martin@arm.com/mbox/", "series": [ { "id": 883, "url": "http://patchwork.ozlabs.org/api/series/883/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-imx/list/?series=883", "date": "2017-08-31T17:00:33", "name": "ARM Scalable Vector Extension (SVE)", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/883/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/808350/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/808350/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming-imx@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming-imx@bilbo.ozlabs.org", "Authentication-Results": [ "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=lists.infradead.org\n\t(client-ip=65.50.211.133; helo=bombadil.infradead.org;\n\tenvelope-from=linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (2048-bit key;\n\tunprotected) header.d=lists.infradead.org\n\theader.i=@lists.infradead.org\n\theader.b=\"HfJTf7qX\"; dkim-atps=neutral" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n\t[65.50.211.133])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xjphZ4hcDz9s81\n\tfor <incoming-imx@patchwork.ozlabs.org>;\n\tFri, 1 Sep 2017 03:07:26 +1000 (AEST)", "from localhost ([127.0.0.1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux))\n\tid 1dnSw6-0004C9-OB; Thu, 31 Aug 2017 17:07:22 +0000", "from usa-sjc-mx-foss1.foss.arm.com ([217.140.101.70]\n\thelo=foss.arm.com)\n\tby bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux))\n\tid 1dnSqt-0007M1-NW for linux-arm-kernel@lists.infradead.org;\n\tThu, 31 Aug 2017 17:02:20 +0000", "from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249])\n\tby usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 3C7322B;\n\tThu, 31 Aug 2017 10:01:40 -0700 (PDT)", "from e103592.cambridge.arm.com (usa-sjc-imap-foss1.foss.arm.com\n\t[10.72.51.249])\n\tby usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPA id\n\t908DC3F58F; Thu, 31 Aug 2017 10:01:38 -0700 (PDT)" ], "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20170209; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=wfVs6vNmoR6EEX+hcIho/FN4GiErqylrkB1XCyyNT7g=;\n\tb=HfJTf7qXU7omcb\n\tEtxfJ9C4fr7XRjAINbByf2XYJR/naGNcmXesjf0g/Ng1spyRiXSsIP7kadAwMHLi3+4l/5PId1Xld\n\twXS9kgm7SSqv795osITN2EpkWU40Yxomtc6ly6tLcoK+Wa5tgJeBSn3bTbaEnf3AhEy8oe+oVmCQL\n\tuA3EcSeP7IFrT/+SSbd3ncb4OiFn0k2tCoourvV0mFhTGF3OZC5etYJF3qhgCyHN+8oDDf5agGL/v\n\te5rRCLZYHcJg5aL/AF3yanzvPV7/GaGntzB2rEshXcG8bpdXH2fZrkvtt5W1bE+915opMF64JqJVj\n\tgmZCo9LCydcVY2aH9Gsw==;", "From": "Dave Martin <Dave.Martin@arm.com>", "To": "linux-arm-kernel@lists.infradead.org", "Subject": "[PATCH v2 13/28] arm64/sve: Signal handling support", "Date": "Thu, 31 Aug 2017 18:00:45 +0100", "Message-Id": "<1504198860-12951-14-git-send-email-Dave.Martin@arm.com>", "X-Mailer": "git-send-email 2.1.4", "In-Reply-To": "<1504198860-12951-1-git-send-email-Dave.Martin@arm.com>", "References": "<1504198860-12951-1-git-send-email-Dave.Martin@arm.com>", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20170831_100200_169372_98411A92 ", "X-CRM114-Status": "GOOD ( 24.68 )", "X-Spam-Score": "-6.9 (------)", "X-Spam-Report": "SpamAssassin version 3.4.1 on bombadil.infradead.org summary:\n\tContent analysis details: (-6.9 points)\n\tpts rule name description\n\t---- ----------------------\n\t--------------------------------------------------\n\t-5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/,\n\thigh trust [217.140.101.70 listed in list.dnswl.org]\n\t-0.0 SPF_PASS SPF: sender matches SPF record\n\t-0.0 RP_MATCHES_RCVD Envelope sender domain matches handover relay\n\tdomain\n\t-1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\n\t[score: 0.0000]", "X-BeenThere": "linux-arm-kernel@lists.infradead.org", "X-Mailman-Version": "2.1.21", "Precedence": "list", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/linux-arm-kernel>,\n\t<mailto:linux-arm-kernel-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/linux-arm-kernel/>", "List-Post": "<mailto:linux-arm-kernel@lists.infradead.org>", "List-Help": "<mailto:linux-arm-kernel-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/linux-arm-kernel>,\n\t<mailto:linux-arm-kernel-request@lists.infradead.org?subject=subscribe>", "Cc": "linux-arch@vger.kernel.org, libc-alpha@sourceware.org, Ard Biesheuvel\n\t<ard.biesheuvel@linaro.org>, Szabolcs Nagy <szabolcs.nagy@arm.com>,\n\tCatalin Marinas\n\t<catalin.marinas@arm.com>, Will Deacon <will.deacon@arm.com>, Richard\n\tSandiford <richard.sandiford@arm.com>, =?utf-8?q?Alex_Benn=C3=A9e?=\n\t<alex.bennee@linaro.org>, kvmarm@lists.cs.columbia.edu", "Content-Type": "text/plain; charset=\"utf-8\"", "Content-Transfer-Encoding": "base64", "Sender": "\"linux-arm-kernel\" <linux-arm-kernel-bounces@lists.infradead.org>", "Errors-To": "linux-arm-kernel-bounces+incoming-imx=patchwork.ozlabs.org@lists.infradead.org", "List-Id": "linux-imx-kernel.lists.patchwork.ozlabs.org" }, "content": "This patch implements support for saving and restoring the SVE\nregisters around signals.\n\nA fixed-size header struct sve_context is always included in the\nsignal frame encoding the thread's vector length at the time of\nsignal delivery, optionally followed by a variable-layout structure\nencoding the SVE registers.\n\nBecause of the need to preserve backwards compatibility, the FPSIMD\nview of the SVE registers is always dumped as a struct\nfpsimd_context in the usual way, in addition to any sve_context.\n\nThe SVE vector registers are dumped in full, including bits 127:0\nof each register which alias the corresponding FPSIMD vector\nregisters in the hardware. To avoid any ambiguity about which\nalias to restore during sigreturn, the kernel always restores bits\n127:0 of each SVE vector register from the fpsimd_context in the\nsignal frame (which must be present): userspace needs to take this\ninto account if it wants to modify the SVE vector register contents\non return from a signal.\n\nFPSR and FPCR, which are used by both FPSIMD and SVE, are not\nincluded in sve_context because they are always present in\nfpsimd_context anyway.\n\nFor signal delivery, a new helper\nfpsimd_signal_preserve_current_state() is added to update _both_\nthe FPSIMD and SVE views in the task struct, to make it easier to\npopulate this information into the signal frame. Because of the\nredundancy between the two views of the state, only one is updated\notherwise. In order to avoid racing with a pending discard of the\nSVE state, this flush is hoisted before the sigframe layout phase,\nso that the layout and population phases see a consistent view of\nthe thread.\n\nSigned-off-by: Dave Martin <Dave.Martin@arm.com>\nCc: Ard Biesheuvel <ard.biesheuvel@linaro.org>\nCc: Alex Bennée <alex.bennee@linaro.org>\n\n---\n\nChanges since v1\n----------------\n\nRequested by Ard Biesheuvel:\n\n* Fix unbalanced ifelse bracing to conform to the kernel coding style.\n\nRequested by Alex Bennée:\n\n* Add comments to explain the barrier()s when writing thread.sve_state\nin restore_sve_fpsimd_context().\n\n* Thin out BUG_ON()s:\nRedundant BUG_ON()s and ones that just check invariants are removed.\nImportant sanity-checks are migrated to WARN_ON()s, with some\nminimal best-effort patch-up code.\n\nOther:\n\n* Delete spurious barrier() from restore_sve_fpsimd_context().\n\nOnce TIF_FOREIGN_FPSTATE is set, context switch won't write to\nthread_struct any more, so it doesn't matter what TIF_SVE is until the\nnext ret_to_user or ptrace interaction, neither of which can race\nwith this function.\n\nSigned-off-by: Dave Martin <Dave.Martin@arm.com>\n---\n arch/arm64/include/asm/fpsimd.h | 1 +\n arch/arm64/kernel/fpsimd.c | 23 ++++--\n arch/arm64/kernel/signal.c | 173 ++++++++++++++++++++++++++++++++++++++--\n arch/arm64/kernel/signal32.c | 2 +-\n 4 files changed, 183 insertions(+), 16 deletions(-)", "diff": "diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h\nindex 72090a1..7efd04e 100644\n--- a/arch/arm64/include/asm/fpsimd.h\n+++ b/arch/arm64/include/asm/fpsimd.h\n@@ -63,6 +63,7 @@ extern void fpsimd_load_state(struct fpsimd_state *state);\n extern void fpsimd_thread_switch(struct task_struct *next);\n extern void fpsimd_flush_thread(void);\n \n+extern void fpsimd_signal_preserve_current_state(void);\n extern void fpsimd_preserve_current_state(void);\n extern void fpsimd_restore_current_state(void);\n extern void fpsimd_update_current_state(struct fpsimd_state *state);\ndiff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c\nindex e20b44d..f82cde8 100644\n--- a/arch/arm64/kernel/fpsimd.c\n+++ b/arch/arm64/kernel/fpsimd.c\n@@ -205,8 +205,6 @@ static void fpsimd_to_sve(struct task_struct *task)\n \t\t sizeof(fst->vregs[i]));\n }\n \n-#ifdef CONFIG_ARM64_SVE\n-\n static void sve_to_fpsimd(struct task_struct *task)\n {\n \tunsigned int vq;\n@@ -223,6 +221,8 @@ static void sve_to_fpsimd(struct task_struct *task)\n \t\t sizeof(fst->vregs[i]));\n }\n \n+#ifdef CONFIG_ARM64_SVE\n+\n size_t sve_state_size(struct task_struct const *task)\n {\n \treturn SVE_SIG_REGS_SIZE(sve_vq_from_vl(task->thread.sve_vl));\n@@ -414,13 +414,17 @@ void fpsimd_preserve_current_state(void)\n \t\treturn;\n \n \tlocal_bh_disable();\n-\n-\tif (!test_thread_flag(TIF_FOREIGN_FPSTATE))\n-\t\tfpsimd_save_state(¤t->thread.fpsimd_state);\n-\n+\ttask_fpsimd_save();\n \tlocal_bh_enable();\n }\n \n+void fpsimd_signal_preserve_current_state(void)\n+{\n+\tfpsimd_preserve_current_state();\n+\tif (system_supports_sve() && test_thread_flag(TIF_SVE))\n+\t\tsve_to_fpsimd(current);\n+}\n+\n /*\n * Load the userland FPSIMD state of 'current' from memory, but only if the\n * FPSIMD state already held in the registers is /not/ the most recent FPSIMD\n@@ -456,7 +460,12 @@ void fpsimd_update_current_state(struct fpsimd_state *state)\n \n \tlocal_bh_disable();\n \n-\tfpsimd_load_state(state);\n+\tif (system_supports_sve() && test_thread_flag(TIF_SVE)) {\n+\t\tcurrent->thread.fpsimd_state = *state;\n+\t\tfpsimd_to_sve(current);\n+\t}\n+\ttask_fpsimd_load();\n+\n \tif (test_and_clear_thread_flag(TIF_FOREIGN_FPSTATE)) {\n \t\tstruct fpsimd_state *st = ¤t->thread.fpsimd_state;\n \ndiff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c\nindex 4991e87..c3f94cf 100644\n--- a/arch/arm64/kernel/signal.c\n+++ b/arch/arm64/kernel/signal.c\n@@ -62,6 +62,7 @@ struct rt_sigframe_user_layout {\n \n \tunsigned long fpsimd_offset;\n \tunsigned long esr_offset;\n+\tunsigned long sve_offset;\n \tunsigned long extra_offset;\n \tunsigned long end_offset;\n };\n@@ -178,9 +179,6 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)\n \tstruct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state;\n \tint err;\n \n-\t/* dump the hardware registers to the fpsimd_state structure */\n-\tfpsimd_preserve_current_state();\n-\n \t/* copy the FP and status/control registers */\n \terr = __copy_to_user(ctx->vregs, fpsimd->vregs, sizeof(fpsimd->vregs));\n \t__put_user_error(fpsimd->fpsr, &ctx->fpsr, err);\n@@ -213,6 +211,8 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)\n \t__get_user_error(fpsimd.fpsr, &ctx->fpsr, err);\n \t__get_user_error(fpsimd.fpcr, &ctx->fpcr, err);\n \n+\tclear_thread_flag(TIF_SVE);\n+\n \t/* load the hardware registers from the fpsimd_state structure */\n \tif (!err)\n \t\tfpsimd_update_current_state(&fpsimd);\n@@ -220,10 +220,118 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx)\n \treturn err ? -EFAULT : 0;\n }\n \n+\n struct user_ctxs {\n \tstruct fpsimd_context __user *fpsimd;\n+\tstruct sve_context __user *sve;\n };\n \n+#ifdef CONFIG_ARM64_SVE\n+\n+static int preserve_sve_context(struct sve_context __user *ctx)\n+{\n+\tint err = 0;\n+\tu16 reserved[ARRAY_SIZE(ctx->__reserved)];\n+\tunsigned int vl = current->thread.sve_vl;\n+\tunsigned int vq = 0;\n+\n+\tif (test_thread_flag(TIF_SVE))\n+\t\tvq = sve_vq_from_vl(vl);\n+\n+\tmemset(reserved, 0, sizeof(reserved));\n+\n+\t__put_user_error(SVE_MAGIC, &ctx->head.magic, err);\n+\t__put_user_error(round_up(SVE_SIG_CONTEXT_SIZE(vq), 16),\n+\t\t\t &ctx->head.size, err);\n+\t__put_user_error(vl, &ctx->vl, err);\n+\tBUILD_BUG_ON(sizeof(ctx->__reserved) != sizeof(reserved));\n+\terr |= copy_to_user(&ctx->__reserved, reserved, sizeof(reserved));\n+\n+\tif (vq) {\n+\t\t/*\n+\t\t * This assumes that the SVE state has already been saved to\n+\t\t * the task struct by calling preserve_fpsimd_context().\n+\t\t */\n+\t\terr |= copy_to_user((char __user *)ctx + SVE_SIG_REGS_OFFSET,\n+\t\t\t\t current->thread.sve_state,\n+\t\t\t\t SVE_SIG_REGS_SIZE(vq));\n+\t}\n+\n+\treturn err ? -EFAULT : 0;\n+}\n+\n+static int restore_sve_fpsimd_context(struct user_ctxs *user)\n+{\n+\tint err;\n+\tunsigned int vq;\n+\tstruct fpsimd_state fpsimd;\n+\tstruct sve_context sve;\n+\n+\tif (__copy_from_user(&sve, user->sve, sizeof(sve)))\n+\t\treturn -EFAULT;\n+\n+\tif (sve.vl != current->thread.sve_vl)\n+\t\treturn -EINVAL;\n+\n+\tif (sve.head.size <= sizeof(*user->sve)) {\n+\t\tclear_thread_flag(TIF_SVE);\n+\t\tgoto fpsimd_only;\n+\t}\n+\n+\tvq = sve_vq_from_vl(sve.vl);\n+\n+\tif (sve.head.size < SVE_SIG_CONTEXT_SIZE(vq))\n+\t\treturn -EINVAL;\n+\n+\t/*\n+\t * Careful: we are about __copy_from_user() directly into\n+\t * thread.sve_state with preemption enabled, so protection is\n+\t * needed to prevent a racing context switch from writing stale\n+\t * registers back over the new data.\n+\t */\n+\n+\tfpsimd_flush_task_state(current);\n+\tbarrier();\n+\t/* From now, fpsimd_thread_switch() won't clear TIF_FOREIGN_FPSTATE */\n+\n+\tset_thread_flag(TIF_FOREIGN_FPSTATE);\n+\tbarrier();\n+\t/* From now, fpsimd_thread_switch() won't touch thread.sve_state */\n+\n+\tsve_alloc(current);\n+\terr = __copy_from_user(current->thread.sve_state,\n+\t\t\t (char __user const *)user->sve +\n+\t\t\t\t\tSVE_SIG_REGS_OFFSET,\n+\t\t\t SVE_SIG_REGS_SIZE(vq));\n+\tif (err)\n+\t\treturn err;\n+\n+\tset_thread_flag(TIF_SVE);\n+\n+fpsimd_only:\n+\t/* copy the FP and status/control registers */\n+\t/* restore_sigframe() already checked that user->fpsimd != NULL. */\n+\terr = __copy_from_user(fpsimd.vregs, user->fpsimd->vregs,\n+\t\t\t sizeof(fpsimd.vregs));\n+\t__get_user_error(fpsimd.fpsr, &user->fpsimd->fpsr, err);\n+\t__get_user_error(fpsimd.fpcr, &user->fpsimd->fpcr, err);\n+\n+\t/* load the hardware registers from the fpsimd_state structure */\n+\tif (!err)\n+\t\tfpsimd_update_current_state(&fpsimd);\n+\n+\treturn err;\n+}\n+\n+#else /* ! CONFIG_ARM64_SVE */\n+\n+/* Turn any non-optimised out attempts to use these into a link error: */\n+extern int preserve_sve_context(void __user *ctx);\n+extern int restore_sve_fpsimd_context(struct user_ctxs *user);\n+\n+#endif /* ! CONFIG_ARM64_SVE */\n+\n+\n static int parse_user_sigframe(struct user_ctxs *user,\n \t\t\t struct rt_sigframe __user *sf)\n {\n@@ -236,6 +344,7 @@ static int parse_user_sigframe(struct user_ctxs *user,\n \tchar const __user *const sfp = (char const __user *)sf;\n \n \tuser->fpsimd = NULL;\n+\tuser->sve = NULL;\n \n \tif (!IS_ALIGNED((unsigned long)base, 16))\n \t\tgoto invalid;\n@@ -286,6 +395,19 @@ static int parse_user_sigframe(struct user_ctxs *user,\n \t\t\t/* ignore */\n \t\t\tbreak;\n \n+\t\tcase SVE_MAGIC:\n+\t\t\tif (!system_supports_sve())\n+\t\t\t\tgoto invalid;\n+\n+\t\t\tif (user->sve)\n+\t\t\t\tgoto invalid;\n+\n+\t\t\tif (size < sizeof(*user->sve))\n+\t\t\t\tgoto invalid;\n+\n+\t\t\tuser->sve = (struct sve_context __user *)head;\n+\t\t\tbreak;\n+\n \t\tcase EXTRA_MAGIC:\n \t\t\tif (have_extra_context)\n \t\t\t\tgoto invalid;\n@@ -358,9 +480,6 @@ static int parse_user_sigframe(struct user_ctxs *user,\n \t}\n \n done:\n-\tif (!user->fpsimd)\n-\t\tgoto invalid;\n-\n \treturn 0;\n \n invalid:\n@@ -394,8 +513,19 @@ static int restore_sigframe(struct pt_regs *regs,\n \tif (err == 0)\n \t\terr = parse_user_sigframe(&user, sf);\n \n-\tif (err == 0)\n-\t\terr = restore_fpsimd_context(user.fpsimd);\n+\tif (err == 0) {\n+\t\tif (!user.fpsimd)\n+\t\t\treturn -EINVAL;\n+\n+\t\tif (user.sve) {\n+\t\t\tif (!system_supports_sve())\n+\t\t\t\treturn -EINVAL;\n+\n+\t\t\terr = restore_sve_fpsimd_context(&user);\n+\t\t} else {\n+\t\t\terr = restore_fpsimd_context(user.fpsimd);\n+\t\t}\n+\t}\n \n \treturn err;\n }\n@@ -454,6 +584,18 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user)\n \t\t\treturn err;\n \t}\n \n+\tif (system_supports_sve()) {\n+\t\tunsigned int vq = 0;\n+\n+\t\tif (test_thread_flag(TIF_SVE))\n+\t\t\tvq = sve_vq_from_vl(current->thread.sve_vl);\n+\n+\t\terr = sigframe_alloc(user, &user->sve_offset,\n+\t\t\t\t SVE_SIG_CONTEXT_SIZE(vq));\n+\t\tif (err)\n+\t\t\treturn err;\n+\t}\n+\n \treturn sigframe_alloc_end(user);\n }\n \n@@ -495,6 +637,13 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user,\n \t\t__put_user_error(current->thread.fault_code, &esr_ctx->esr, err);\n \t}\n \n+\t/* Scalable Vector Extension state, if present */\n+\tif (system_supports_sve() && err == 0 && user->sve_offset) {\n+\t\tstruct sve_context __user *sve_ctx =\n+\t\t\tapply_user_offset(user, user->sve_offset);\n+\t\terr |= preserve_sve_context(sve_ctx);\n+\t}\n+\n \tif (err == 0 && user->extra_offset) {\n \t\tchar __user *sfp = (char __user *)user->sigframe;\n \t\tchar __user *userp =\n@@ -594,6 +743,14 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set,\n \tstruct rt_sigframe __user *frame;\n \tint err = 0;\n \n+\t/*\n+\t * Ensure FPSIMD/SVE state in task_struct is up-to-date.\n+\t * This is needed here in order to complete any pending SVE discard:\n+\t * otherwise, discard may occur between deciding on the sigframe\n+\t * layout and dumping the register data.\n+\t */\n+\tfpsimd_signal_preserve_current_state();\n+\n \tif (get_sigframe(&user, ksig, regs))\n \t\treturn 1;\n \ndiff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c\nindex 4e5a664..202337d 100644\n--- a/arch/arm64/kernel/signal32.c\n+++ b/arch/arm64/kernel/signal32.c\n@@ -244,7 +244,7 @@ static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame)\n \t * Note that this also saves V16-31, which aren't visible\n \t * in AArch32.\n \t */\n-\tfpsimd_preserve_current_state();\n+\tfpsimd_signal_preserve_current_state();\n \n \t/* Place structure header on the stack */\n \t__put_user_error(magic, &frame->magic, err);\n", "prefixes": [ "v2", "13/28" ] }