From patchwork Fri Jun 17 23:54:26 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 9185243 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 79D05601C0 for ; Sat, 18 Jun 2016 00:05:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5A15B27EE2 for ; Sat, 18 Jun 2016 00:05:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4E4452833E; Sat, 18 Jun 2016 00:05:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 9FD6827EE2 for ; Sat, 18 Jun 2016 00:05:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1bE3jz-0004FF-2S; Sat, 18 Jun 2016 00:03:59 +0000 Received: from mail-by2on0077.outbound.protection.outlook.com ([207.46.100.77] helo=na01-by2-obe.outbound.protection.outlook.com) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1bE3cU-0001wc-AZ for linux-arm-kernel@lists.infradead.org; Fri, 17 Jun 2016 23:56:22 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-caviumnetworks-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=ya9rsAsCQOOFAEHovkUvXSc7reu/W46ECh9ntzR40Ec=; b=kQo1qkn7bbW0y2vKQ33js9yqSZD3uGnkqrCZbyK9Bu7n5udqMLYGbagxxhiF7JCFuIgae4oWzhsmPR3Ycx1qY0zA8HkRKm24jom33KLXPqZUvh2jYubxKI8X50avTQNYcvr/MpnIgDEtoUh2wf1SZJ5y4UngoGU8gQHKHmez7Z4= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; Received: from localhost (50.233.148.158) by BN4PR07MB2242.namprd07.prod.outlook.com (10.164.63.148) with Microsoft SMTP Server (TLS) id 15.1.523.12; Fri, 17 Jun 2016 23:55:51 +0000 From: Yury Norov To: , , , , , , Subject: [PATCH 17/19] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Date: Sat, 18 Jun 2016 02:54:26 +0300 Message-ID: <1466207668-10549-18-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1466207668-10549-1-git-send-email-ynorov@caviumnetworks.com> References: <1466207668-10549-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 X-Originating-IP: [50.233.148.158] X-ClientProxiedBy: CY1PR15CA0020.namprd15.prod.outlook.com (10.163.14.30) To BN4PR07MB2242.namprd07.prod.outlook.com (10.164.63.148) X-MS-Office365-Filtering-Correlation-Id: 6c8313b4-b015-4d0b-20d2-08d3970ae9d6 X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2242; 2:jw9WmvkUTDV5txFfjq/jGIyBcMlJOOd1QOM/GsFTHShFP8CNcO2jszaRL+oDFc2/AkeFPQTIZ/CjaVsEnA9N5tUYRnym+jNc316KSQwx07rBGd45OFfisEi297eL97tY+MLbR+UpK4P3/U7IW3Rjb6aVGuvyJf76ocftQcg2jR0P7pUz25V/x08v+Ohkk+8Y; 3:KN9fgFRIm4iBwOn0BIsolgJplx9yAUxfhLjS56wbv7NA2CoBifU5spES/8yA/LpbVVrYU96op8ITu26Y4NJ651GBHz6XE78mL4nZICZ0ChklpjGx49Atft5FvhrNetLT; 25:JouPRrQjZFtk7yBe1W/0DCyN9TTENk4+KfqyAj27+VTbmLnczfP6vUR3iTOh6ZPvklbuXlj6AS9pcDcr3QDLpABXec8Li/bDPv6AA8Ja6faBhEAYh77cKCW1uAbzPHo8DTiCvV7myiHhhTIwch7MXBpYqdzZdq3tN8DitV5jJg136NUj+2AUPEdEYSf47//7WJ/oGst9/q8+BAO7gvleK/GD595uF+u0r9gxB8AQpmq/TJ8moMxk57Pz/boOsHrbEjcWk5i9bEqSQeiI5QjuCmeyvDiilsAqyq52grycnn+5D5Pw3HDDn9lO1NEC9gK8+KeY+f/v6aEromMfb+cFCD8sWX8u82Q/stCK1jEKAgFHUzHplVEk77UNXA+enm1zgDGJmP3uELP5XWjD9w/ZRJqduTpBsfe/yr5VX+awGOo= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN4PR07MB2242; X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2242; 20:PgCtPguQVMX0ywtOMxcOw+7fwSvfNWpAgQyP/GbY6jMzKy8E6SGlRRhWg+/x2wly3rEBAhX2v9wO3r6ziDTeNJ+/wH3XRaECpENO2l3Khe1l3rf6uYSJn4V+s3pytKXt74uBVqI/aLS4GwAwKs5vFDBsXheY/WfKFrdwlSOpkezDDgsATAH+o2dRjvZiZII/owZderdEbeac+/DZqaJgrPyr4qswBbAN8zbWZB13wBHPJzx7j/xbha04JjHt6TjaswjD2eQnuZ5MijwPPvUQKn7z6lRhNdTHuz6aVbPqr234XEiVKsezOmORRMQ9Wg8yaWpWB5P/iM+MmgsIEVBv+VkzIk8I8hGGbI2or6rhx3HKnDZ6WJ/2qjAUgw62aOeLaGfWWmGUzmoMrkXK6zKaaBu+W/Bw+EtXZ5ov4Gfwk9JSS+1CDf5xeYH2KGNDW6flO7VHnfwxr0u1xa5hFdPQPEft3OrfiZVszLgKTx2p4kVW1qT+SkjBOmj9ZSFKQtfaNAofL88vs7UWcshmTVqRzHIlOeW1GOzky7ylU1+vNzXQwE6tbjFQ3Ou1h6ZZy1UiRri5vszimMm39slcruBhSgVHekzRkY5YkMvw0R9ww8o= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(2401047)(5005006)(8121501046)(10201501046)(3002001); SRVR:BN4PR07MB2242; BCL:0; PCL:0; RULEID:; SRVR:BN4PR07MB2242; X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2242; 4:k+Ix9QMljOPzbsWFLZ3jIImLhx7O+t7u3/lgj6mSOP1zoqmL14c/t4sisEqCnyukSZPrY+Ee86gWYOTe7DrKnhnSV+d8/V+O7MV/5lLxmIvkyfy+N6Mqm3SyKe766ESs7LUTrzveSp3Wd4E73J7RKLjzhCoErVqIMOtrwN+samZthhWtk7VrsJS3ADilRS5Ivi4PjTfgqn81S2NeoL63D9XXPU6BGG0LawONO7jDvH1XyIlbGSHvsugbAIJUMbK5wwwxzM49KP6mhQhWJEiKjjgclyJPw2EIhgjWYROJ3r77YdORFCXItzsUCydedVAF0kiMWen8xQsv4y0JZ5doDwSj0K4tPUdAIWr0c4kRpUX0kv1UjNUlHAHAtQNeUA59btbTq7Rl26DantOqFGoHMxnC8O4czvb671/iJM3bmz8Gg5tr6896tqdese8cBP21CNCcXaZnE2bydKHORbmpoQ== X-Forefront-PRVS: 09760A0505 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6009001)(6069001)(7916002)(199003)(189002)(43544003)(50466002)(105586002)(76176999)(50986999)(92566002)(15975445007)(8676002)(2950100001)(2906002)(36756003)(97736004)(5001770100001)(189998001)(68736007)(7846002)(81166006)(101416001)(81156014)(106356001)(66066001)(48376002)(4326007)(107886002)(33646002)(50226002)(47776003)(76506005)(229853001)(19580395003)(42186005)(19580405001)(6116002)(3846002)(586003)(4001430100002)(5004730100002)(5003940100001)(77096005)(2201001)(2004002)(2101003); DIR:OUT; SFP:1101; SCL:1; SRVR:BN4PR07MB2242; H:localhost; FPR:; SPF:None; PTR:InfoNoRecords; A:1; MX:1; LANG:en; Received-SPF: None (protection.outlook.com: caviumnetworks.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BN4PR07MB2242; 23:rLxivHFmaToF/R1G2UmhwEY996W6Skb5gemzVya/K?= =?us-ascii?Q?y3I+bf7loXUICpCFMk3fqOpKTepkW31r55jNSG1DjlGxbLZNp9wUZItfGc44?= =?us-ascii?Q?LWZxTHcBss7Wqkdfd4OXVzyBwMMXWkeJw4sizgYI5mbfN9HCwDQ62tpRw5Aa?= =?us-ascii?Q?aKFTvdEL+cU/5bCTixniUFaWnAZm+gy7cR8or1gFntO7h0Dln10Jvm78Oj5Z?= =?us-ascii?Q?Yw9M8xxUuPukFFsI++HKws0juBApflRATmGVi0cSjXrUOXTkvlOeB6sZlVyG?= =?us-ascii?Q?L/Q0+n89xr9T873EmzeHOBIdciKkKPceele0fGo2HW2Y0K72F+q7LioD8fcg?= =?us-ascii?Q?AU0w/vg13uuPnFw8cyyB+yGU0fRUvm53cuDQXP9BHRLhe/1g8Wt+qDBsz4vh?= =?us-ascii?Q?b9FtRpKlWz2ATvq7gMcFyr9Igd/GwpLkeNJMsYjFALiF2R1/RY901QRvg3pO?= =?us-ascii?Q?0YEgKWUoFqXShxebCb/qiQn/bsxtfCj7j8EADY4jaf1AcIU4CDoEP60hQAkd?= =?us-ascii?Q?yVou5Wbttwxj39YugqYXMhZ2GdKiMItwtqaPPRplnqVm5euJmftZRpvVAat0?= =?us-ascii?Q?zxpFU7wZPtnNEhjswOVyYeAHs7b1ULnj2AjhAwus8jTf860mOcKUtDzfL3cY?= =?us-ascii?Q?WA62C56WtgPJjIbVjqyUYwORmaAQBVuXaAa4M8GHAH43vvPolnuZ+lCTZUf5?= =?us-ascii?Q?PoOKO0PpVb/5qATyQDLpQJltaRI0/H+etRTuzHoBn0gFd5J8pUnPcDjRcRhS?= =?us-ascii?Q?uHJtjrc9R6wGt3GsR4vqkIzB1309YdEJT4Uj1wozI3UF4M1c9yrCDUat3Ve8?= =?us-ascii?Q?keJTitNrlk/6Nt6Iar8orM45FrHb8BRq8A6ag4SxX8D+yq04FHriHOu07nl/?= =?us-ascii?Q?u3Pd/HQg/eN7ZPsLFx196eNdH83hqabtdaW6L82w5D+vbZw09BstpvpNvL3U?= =?us-ascii?Q?PLurdBHQ0Wg1CDM88ufVHLDrkKmSszlfy1G20QMlgv+mOxeV98Zf2pVDL8D8?= =?us-ascii?Q?0T/7OiDGM8+uZ6dOGTeI2NmOUpqTalkzemWPCEzf1ktTib9dRuihHjzQzR66?= =?us-ascii?Q?jTeA9ceoxordfjU+oERnZi79BMjpmhhaSKejvx3Y2SK4gdHdPjI8QbK4MyD2?= =?us-ascii?Q?Drc6Hmp6/Ky0iPIRECG9SmgxijIWh1c8rgz7nJhxgDAMrUvGhu9lxehrl5G0?= =?us-ascii?Q?m0l2H4b0RI2cY0tcryrgjKvNokOb4YtpcegixgBB/kEnuFcZObeV00f/w=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2242; 6:CINSO3o1yHBB0ZGJzkLCNnZijapW010qRvoHzpWtzdMvuivumOxL53DZl9iqLSa5kexXAAogAqno2pNJFdNmi6nxSNr2RAQfsYqDVCy9Ns5jWDnqiQMnfmsrW3G1Cfd4jJuIvR6Ca0bUB7DGRzL4nHuYp14JcDsZqER1B7AjnDqsdXm8W9oKCidKMJd6GWylFazXMrXgcaaRm2KSP7fWSEL7OWwfDA6+p7axZkx1MEmT9OjMNKoKpio4egEFTVo1Nf+O88cUFhMEhJLOMMUohCdYxqhEpzgh0wsr0o/prjo=; 5:C9b9KjiDHrieUJaW0Gqby/HgNK2jN7+7rtqyWkbLD595a0B4/x5gYT2TKJGLQDiwoOc/CbefCVJsGa2rDFdmaamOKX7Bnb+YDpcvm6MN/gJkFs6J7U+lJhT0mR5/ZfK6+polSTYx2/u1NNQxPjhxLg==; 24:Ujdb9QLzk/3kZxucGmxSWmtoABAMucxEBzzQ+LwFKJGhidC3je2o+kaMlGfsBpZnglQCjRdDNxcYMzQy2lOrrviGMp1/Wsr6pUB/Or7qKKE=; 7:3IFccACY6dpU65ZMk7tGgectSjHmiHKGiin1WLCjvxAOPxOxo5cIlOyfTNutjrF/nNfnsqsljSchUckDzQMEV3pY+df1qvb04msigLfxGJMTriQJT2B9jVlpaz6D6SG4E74AOE9HHdZJXMk/ZRnHp5Hd6sfMLOUIgff5+NIwK8gNf/guUfhEMb9o80hsXpiCMPop/08nzOQMX722MptG39t53A+An5ILBGcE12KVFPfc5jdgEoln82sNI75Ttz1z SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Jun 2016 23:55:51.5891 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN4PR07MB2242 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160617_165615_137446_A1A26BC3 X-CRM114-Status: GOOD ( 14.85 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: szabolcs.nagy@arm.com, heiko.carstens@de.ibm.com, ynorov@caviumnetworks.com, philipp.tomsich@theobroma-systems.com, joseph@codesourcery.com, Prasun.Kapoor@caviumnetworks.com, agraf@suse.de, Andrew Pinski , geert@linux-m68k.org, kilobyte@angband.pl, manuel.montezelo@gmail.com, pinskia@gmail.com, linyongting@huawei.com, klimov.linux@gmail.com, broonie@kernel.org, bamvor.zhangjian@huawei.com, maxim.kuvyrkov@linaro.org, Nathan_Lynch@mentor.com, Andrew Pinski , schwidefsky@de.ibm.com, davem@davemloft.net, christoph.muellner@theobroma-systems.com Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP From: Andrew Pinski ILP32 uses AARCH32 compat structures and syscall handlers for signals. But ILP32 struct rt_sigframe and ucontext differs from both LP64 and AARCH32. So some specific mechanism is needed to take care of it. Signed-off-by: Andrew Pinski Signed-off-by: Yury Norov --- arch/arm64/include/asm/signal_ilp32.h | 34 ++++++ arch/arm64/kernel/Makefile | 3 +- arch/arm64/kernel/entry_ilp32.S | 23 ++++ arch/arm64/kernel/signal.c | 3 + arch/arm64/kernel/signal_ilp32.c | 194 ++++++++++++++++++++++++++++++++++ 5 files changed, 256 insertions(+), 1 deletion(-) create mode 100644 arch/arm64/include/asm/signal_ilp32.h create mode 100644 arch/arm64/kernel/entry_ilp32.S create mode 100644 arch/arm64/kernel/signal_ilp32.c diff --git a/arch/arm64/include/asm/signal_ilp32.h b/arch/arm64/include/asm/signal_ilp32.h new file mode 100644 index 0000000..30eff23 --- /dev/null +++ b/arch/arm64/include/asm/signal_ilp32.h @@ -0,0 +1,34 @@ +/* + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __ASM_SIGNAL_ILP32_H +#define __ASM_SIGNAL_ILP32_H + +#ifdef CONFIG_ARM64_ILP32 + +#include + +int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs); + +#else + +static inline int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, + struct pt_regs *regs) +{ + return -ENOSYS; +} + +#endif /* CONFIG_ARM64_ILP32 */ + +#endif /* __ASM_SIGNAL_ILP32_H */ diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index d69bd40..ae8aacb 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -28,7 +28,8 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \ sys_compat.o entry32.o \ ../../arm/kernel/opcodes.o binfmt_elf32.o -arm64-obj-$(CONFIG_ARM64_ILP32) += binfmt_ilp32.o sys_ilp32.o +arm64-obj-$(CONFIG_ARM64_ILP32) += binfmt_ilp32.o sys_ilp32.o \ + signal_ilp32.o entry_ilp32.o arm64-obj-$(CONFIG_COMPAT) += entry32_common.o signal32_common.o arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o diff --git a/arch/arm64/kernel/entry_ilp32.S b/arch/arm64/kernel/entry_ilp32.S new file mode 100644 index 0000000..5063172 --- /dev/null +++ b/arch/arm64/kernel/entry_ilp32.S @@ -0,0 +1,23 @@ +/* + * ILP32 system call wrappers + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +ENTRY(ilp32_sys_rt_sigreturn_wrapper) + mov x0, sp + b ilp32_sys_rt_sigreturn +ENDPROC(ilp32_sys_rt_sigreturn_wrapper) + diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 5c73864..241bfeb 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -35,6 +35,7 @@ #include #include #include +#include #define RT_SIGFRAME_FP_POS (offsetof(struct rt_sigframe, sig) \ + offsetof(struct sigframe, fp)) @@ -325,6 +326,8 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) ret = compat_setup_rt_frame(usig, ksig, oldset, regs); else ret = compat_setup_frame(usig, ksig, oldset, regs); + } else if (is_ilp32_compat_task()) { + ret = ilp32_setup_rt_frame(usig, ksig, oldset, regs); } else { ret = setup_rt_frame(usig, ksig, oldset, regs); } diff --git a/arch/arm64/kernel/signal_ilp32.c b/arch/arm64/kernel/signal_ilp32.c new file mode 100644 index 0000000..8ca64b9 --- /dev/null +++ b/arch/arm64/kernel/signal_ilp32.c @@ -0,0 +1,194 @@ +/* + * Based on arch/arm/kernel/signal.c + * + * Copyright (C) 1995-2009 Russell King + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2016 Cavium Networks. + * Yury Norov + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + + +#define ILP32_RT_SIGFRAME_FP_POS (offsetof(struct ilp32_rt_sigframe, sig) \ + + offsetof(struct ilp32_sigframe, fp)) + +struct ilp32_ucontext { + u32 uc_flags; + u32 uc_link; + compat_stack_t uc_stack; + compat_sigset_t uc_sigmask; + /* glibc uses a 1024-bit sigset_t */ + __u8 __unused[1024 / 8 - sizeof(compat_sigset_t)]; + /* last for future expansion */ + struct sigcontext uc_mcontext; +}; + +struct ilp32_sigframe { + struct ilp32_ucontext uc; + u64 fp; + u64 lr; +}; + +struct ilp32_rt_sigframe { + struct compat_siginfo info; + struct ilp32_sigframe sig; +}; + +static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set) +{ + compat_sigset_t cset; + + cset.sig[0] = set->sig[0] & 0xffffffffull; + cset.sig[1] = set->sig[0] >> 32; + + return copy_to_user(uset, &cset, sizeof(*uset)); +} + +static inline int get_sigset_t(sigset_t *set, + const compat_sigset_t __user *uset) +{ + compat_sigset_t s32; + + if (copy_from_user(&s32, uset, sizeof(*uset))) + return -EFAULT; + + set->sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); + return 0; +} + +static int restore_ilp32_sigframe(struct pt_regs *regs, + struct ilp32_sigframe __user *sf) +{ + sigset_t set; + int err; + err = get_sigset_t(&set, &sf->uc.uc_sigmask); + if (err == 0) + set_current_blocked(&set); + err |= restore_sigcontext(regs, &sf->uc.uc_mcontext); + return err; +} + +static int setup_ilp32_sigframe(struct ilp32_sigframe __user *sf, + struct pt_regs *regs, sigset_t *set) +{ + int err = 0; + /* set up the stack frame for unwinding */ + __put_user_error(regs->regs[29], &sf->fp, err); + __put_user_error(regs->regs[30], &sf->lr, err); + + err |= put_sigset_t(&sf->uc.uc_sigmask, set); + err |= setup_sigcontext(&sf->uc.uc_mcontext, regs); + return err; +} + +asmlinkage long ilp32_sys_rt_sigreturn(struct pt_regs *regs) +{ + struct ilp32_rt_sigframe __user *frame; + + /* Always make any pending restarted system calls return -EINTR */ + current->restart_block.fn = do_no_restart_syscall; + + /* + * Since we stacked the signal on a 128-bit boundary, + * then 'sp' should be word aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (regs->sp & 15) + goto badframe; + + frame = (struct ilp32_rt_sigframe __user *)regs->sp; + + if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) + goto badframe; + + if (restore_ilp32_sigframe(regs, &frame->sig)) + goto badframe; + + if (compat_restore_altstack(&frame->sig.uc.uc_stack)) + goto badframe; + + return regs->regs[0]; + +badframe: + if (show_unhandled_signals) + pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", + current->comm, task_pid_nr(current), __func__, + regs->pc, regs->sp); + force_sig(SIGSEGV, current); + return 0; +} + +static struct ilp32_rt_sigframe __user *ilp32_get_sigframe(struct ksignal *ksig, + struct pt_regs *regs) +{ + unsigned long sp, sp_top; + struct ilp32_rt_sigframe __user *frame; + + sp = sp_top = sigsp(regs->sp, ksig); + + sp = (sp - sizeof(struct ilp32_rt_sigframe)) & ~15; + frame = (struct ilp32_rt_sigframe __user *)sp; + + /* + * Check that we can actually write to the signal frame. + */ + if (!access_ok(VERIFY_WRITE, frame, sp_top - sp)) + frame = NULL; + + return frame; +} + +/* + * ILP32 signal handling routines called from signal.c + */ +int ilp32_setup_rt_frame(int usig, struct ksignal *ksig, + sigset_t *set, struct pt_regs *regs) +{ + struct ilp32_rt_sigframe __user *frame; + int err = 0; + + frame = ilp32_get_sigframe(ksig, regs); + + if (!frame) + return 1; + + err |= copy_siginfo_to_user32(&frame->info, &ksig->info); + + __put_user_error(0, &frame->sig.uc.uc_flags, err); + __put_user_error(0, &frame->sig.uc.uc_link, err); + + err |= __compat_save_altstack(&frame->sig.uc.uc_stack, regs->sp); + err |= setup_ilp32_sigframe(&frame->sig, regs, set); + if (err == 0) { + setup_return(regs, &ksig->ka, frame, ILP32_RT_SIGFRAME_FP_POS, usig); + regs->regs[1] = (unsigned long)&frame->info; + regs->regs[2] = (unsigned long)&frame->sig.uc; + } + + return err; +} +