From patchwork Wed Aug 17 11:46:40 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yury Norov X-Patchwork-Id: 660081 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3sDnZx1gtXz9sBc for ; Wed, 17 Aug 2016 21:49:45 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; secure) header.d=sourceware.org header.i=@sourceware.org header.b=wwkuVJNk; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type; q=dns; s=default; b=n+9MI FeuxcylKox6oriv5j4MeeiqTLLarHE96OyDGr3eOwsJIvPOI6p+S2EkV0GvGg1GU PnKiYmO8/fdws+9vVUBvzlR4Qz/l7D9x9PFoSsxGYHvU7U9F5kMTniGXPTVfloIY gpXg8uZlsuIrma1mXMDvRdxNH4rEVPlhbA5dDw= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type; s=default; bh=BN3tTCOUkJm qOa0gd15eCuIZRSI=; b=wwkuVJNkiQ1zgcd0+VaRgP0f9cH8D7FuAXgHUdkgb2b ZpqMi9YeQgE+q+S15Cls6n6BcEU0/lxZaLeuRw7C9H3s3ITMZ1A9qrE5VQ7K3w8L 2U60rJCrp/r1GGQAS1VA5PvK5vO2YS/p1h5m0TTqjuJrORHvcN2I7+ru9WcrBHcE = Received: (qmail 115136 invoked by alias); 17 Aug 2016 11:49:34 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 115045 invoked by uid 89); 17 Aug 2016 11:49:33 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=3.6 required=5.0 tests=AWL, BAYES_80, KAM_MANYTO, RCVD_IN_DNSWL_NONE, SPF_HELO_PASS, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 spammy=King, Based, 1, 23, FORCE X-HELO: NAM01-BN3-obe.outbound.protection.outlook.com Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; From: Yury Norov To: , , , , , , CC: , , , , , , , , , , , , , , , , , , , , , , Andrew Pinski , Andrew Pinski Subject: [PATCH 15/18] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Date: Wed, 17 Aug 2016 14:46:40 +0300 Message-ID: <1471434403-25291-16-git-send-email-ynorov@caviumnetworks.com> In-Reply-To: <1471434403-25291-1-git-send-email-ynorov@caviumnetworks.com> References: <1471434403-25291-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 X-ClientProxiedBy: AM3PR03CA024.eurprd03.prod.outlook.com (10.141.191.152) To BN4PR07MB2244.namprd07.prod.outlook.com (10.164.63.150) X-MS-Office365-Filtering-Correlation-Id: 310a3fa6-0dd4-4afd-cbc8-08d3c6948607 X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2244; 2:pIj+r3i5ketgM2+PM+fBWJP59RRA8N7vfdoA1sIxO0ejPbvqrjiosa6L6jBTiVhz9mL/CLESoG2D6ISwc2abzIM10oqdPPH0x4lq+wFfb5vaN05DE7b6rXCO3poVxmLuovfTw6Vrko9Mv+FhaRMiKB66KMOH0UKznApxaQkLCAwRsUlLSDvN4xeBJhokZYZJ; 3:WUBSQceUzzzygKnLSdI+Z8NDTwSs/aiYtubdAn2n/BjAazFTVXzVlA8zud79IqEFN5fqelbMYh/KY9AiFvGDX27qtesITt/VjEKXYeIqxXZgSAYMiFyZEk+ng/kXv2Je X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:BN4PR07MB2244; X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2244; 25:HnUocLSeq+2hlonKhP5LayciL3nQIF91Ju8AYudH0LPzhAAGFyNFO7sJbfn0/zR2zzxklqkLCytnnvGTaqR07JB8qq6WDMM6lLAFgS1wSAFJmfLcR7q6ITNzCBljYI7bEkcJNBWPGsgIX0EKssR8YGHsyWmspkkjCE63ErPfc4cVyGBkp2rSOWL6zJ0zXrYUqzc8CTwvONQ9YFTKBCbcaDC6Ee/NaLn3uNY8F2j8Nv+REI1nUT7JW4tL4wOboCXlKzu79PScvPZSeJYsB4cZyTOrEenMsgZctylyi1heli1BoWhoRXnF2hRDNz6n9G/ZApHBxExfv9hGv9IFf64rjAy+mlw8lyRSE1/Dz8UwAbNg4n7BuKFMhHV9kYgblJzl3LY03HZ94Wd6/wux+R0wqk26PhS4c6lPgxRW0GdhZmrVmUcLin40/5yZEGdWwYHI6rShdulgv8eQrp0OFEqnc7nHlb9Pa4MLCdopNMztUVF+xuOCkgoqYH6en3/8Fr1vDBFBNrcY/aqJu7SDCvZMETYwLw2IjVaGZP7uKJo52ZvHPAA8v7XmGweHQznCG16mzUfMpNGkv2XkLrz7t6X83lOsbpV4Lg9xQX2Bo+GTZLNurw1IVtfk6fgB2xLVZaIyjYv9rPATUe+Ud+h4flme4xex3yO3flNHkh4bqDE/QzBfcu2hLIX0NqZCXdjLqLD86b/u4TIRjJSH1YAMHxI434KtlRLMBciIRreMQ8BF+ELpAkn2DiIS13E7IapC7NjsjAm4NcJjni8KWRdbtJV+kX1e2wDe7WTWQwHKfVRYLPCVqOx1GQ/Fw2kitQsKhnHYb0NO6EC2VF0fnV4tsA6wY0najsgYUc1hVOy7HtPDANjGy+HgSGEXrxxS8Te+eP8n X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2244; 31:zn32x7JMOCNcr+rBCTpR5zQL5Lfasy+Lx1M4Su5cMSDR6bmM6pr8dxrW920+s1h3Ex9ZOnEhKCBBj7OSo3XwcqJY9YMQ61oAZOFbeZ/eRXyD3z6PjDVAJlmf0rhKb5qERVavdBWMmCpg3TQ4vmtZYI7tFxroBaZS3pgQVzBaHEl12OP+H9bH/WCRR9wVupOUGrDyyZIiukSKqhk7Nplqph0lX+rDNO65GrnD6hctqOo=; 20:PSkYZtmsFmrGPFIney6Vm8Ert9UvRjDDKGYnDZB6NgMPbgjYzoLskmfxCgntJ+kHc+jBVZlQI1vSWb1MKL0BaU/Hxob5c7HE5YDDwoxuPjGjIUsL3/kHLL6Lds2XYYqvi4kRdvs1VHLZ/0d4J9FiLm6Jds1p5sBbbj4zEjAbnJr83IJIi1c+HNi1i+5bLVzQH6D4r6rE9EBJtWRD19fYo3F94Th5ZaD5RC6vDluO9YyZ9V4/EN+PWBdqGxG2aUqf5jCJ4n+dyzgUUnC1pFOr18n86Uv2ZB1EmtJcn0vEBREm9s95yqWPUZkQNPLnwhORWSYrsakLkGVWBTgCnJrNiYGBOyZ+rKeB/PJDmWiHPQnSFd7J598VqwVpvkyDjRvUniK25pkREm8Wp/RyJI9V1e4jD1txXOJZJ8ZTI9OIsUyJgEy0rALU6lFYdy6goloht5Ex58wxxnx76FMF07Ue+x+4hi2cPZ9n3kJ1SEc0AAhTWfxnU2LiQvS2kpEvxiNko860Cut3SJZyLMUgcNW2fPIn0hOz3pi/VBjfznraAhADKyBTFg0rbosIllOAEhp8GeA7DuNPcO4pE6sSSv9Wm82JP7r2sZlRRSYHsMjNhFs= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(6040176)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046); SRVR:BN4PR07MB2244; BCL:0; PCL:0; RULEID:; SRVR:BN4PR07MB2244; X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2244; 4:2O7V10FVdg/P44S88fDvbNGbG9lLIlSaIs4Qa7Dpx6fCcE/dhwVWcuVcI3N3wH9k1TCMcVWN+mqteb7iPXeyn8QQgxGquDSznQ9kUQJBZBdSvFuXtaRFFnA+iNNsjWI9tXW7Hqr7kiSVwkEooHAxyCndhaopi9Axd7XEDofAeKe7tfJGfw9bbcLmrLq0mHfI6LNm+CFQAUOgkQAQWcHclC8KXMK+NS+Ejs6DsLOtq2114qbjvCU2Zgan8st3ML+LZA8VrwMY6dT27lWWo0rjEZdXJbMgo2kWtMwJXu2A9oqpkvs+1uT+skK3kSc3vrql6cDRgZYcXs+GXuQCQ1ZpNdZqn39FMvtbql4ks8Ga7gJ7zJbGuaf+r95fQdShCgYWW38AYSewNyMdUU7qVwuMDvG8927Zph3r4ytDEAAGJzXY4Hblv9pAaDO9HKnnnjqCZG3DNmF2SHOj+N4trV61BA== X-Forefront-PRVS: 0037FD6480 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(4630300001)(6069001)(6009001)(7916002)(199003)(189002)(43544003)(68736007)(4326007)(101416001)(2906002)(8676002)(81156014)(47776003)(66066001)(229853001)(5001770100001)(81166006)(97736004)(106356001)(107886002)(189998001)(105586002)(19580405001)(2201001)(77096005)(15975445007)(19580395003)(92566002)(2950100001)(50986999)(48376002)(76176999)(50466002)(33646002)(5003940100001)(50226002)(305945005)(4001430100002)(586003)(3846002)(36756003)(42186005)(76506005)(7846002)(6116002)(7416002)(7736002)(2004002)(2101003); DIR:OUT; SFP:1101; SCL:1; SRVR:BN4PR07MB2244; 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; BN4PR07MB2244; 23:+rxlPlVTbke+GnNiUn1W8H/ZLx5CNKA4A5moprrRm?= =?us-ascii?Q?I2450rrQU6nfm4BHfd2BY1Py02gXkVIpY5kGm03V7pVgW3JNX6Q9HDbelhCW?= =?us-ascii?Q?OmqI70dVWDGYOR3FukUsJFIKWR308jJfyw/rj8ZT+GBJkY86KR6PY9e9XbJQ?= =?us-ascii?Q?yVNY+C8Lq3Oul+9yHmDHfo/EnuPuKbq1t3z452Dkhm8pPVmWEoUr4fBpFpdU?= =?us-ascii?Q?mCtEuOW0eS/9JVIatlI32MFaIbFpvklW0oypwcwcnwIEFUmH2Uf4hB4nfxdV?= =?us-ascii?Q?Iwdz8ACLnsXCN4FM1gkU6Nn1nFvBYUoYB5EXANtoSveEqSlolCRs17PODAom?= =?us-ascii?Q?AAQyTYNiSTYRceMvkU4KBDY+LlE3ZE+7iU67TSU5AASYjv4pj0b4IctzC6eY?= =?us-ascii?Q?uHWJ8mEoaZ5VQZyi7WhKfBWQtJEWiXsd6f6fqQm+4Duoo7eFxVJ2OXyXjEdO?= =?us-ascii?Q?OicG0dKZt5ZtdFRqL2jJ3W2d1QY8UyYOvXprzZH4dPD2jk9nuym1flxtQWgm?= =?us-ascii?Q?fjG2MNH7HBNpvmVnqCRhRA/UegtTlODLHj+IhyXZP0Q8XZ9ASreJG/cwcLX1?= =?us-ascii?Q?+vyZOWwtRuOcJ5ZxKq91Hz5rPsS+Y/dWaygO+bbuLkznk/kBDbiwpPprtajR?= =?us-ascii?Q?2lLXqm8IrmhQFubQigeYWD+qvHqCsvjgkdto6ZuUAVHG0LiwM+95MR20SsB4?= =?us-ascii?Q?xIyF43ZTGtZ+IwcwcZueggbG1JJ6UmavrIideJyEim+1Px+NYyOh1uspF8nK?= =?us-ascii?Q?mDtfBipSoedW3FTYSAjtg2F0bZZFpEFyW9RQJLP23YvxXKyd3pScEUGxTQTB?= =?us-ascii?Q?xjigJyJsdRtkUeRbYP02L+ijrlPEBbXX1+CRVacyMcDAAUI0bWQlPXHqfA8W?= =?us-ascii?Q?L3jyLsI+jZ6uIBsWufiLmO7U7oPYIXBJh52xSHi0b3yPhUOg2T8WsLnAkPtQ?= =?us-ascii?Q?c3JqkUCRT98DYtL/r+mmOXn8yjUaj18IETfQVVClzm2QY6IxBNC5gn2+c8ps?= =?us-ascii?Q?014tw8Sr4xoAcEtXUqUUehyz1Lf5CY27U74seNQJhjjN5bksUwfjrI5EkyYL?= =?us-ascii?Q?LAQixvpZf60OphG1m7Q1yLmJGoP1rvkDrSPKNJDlU/5TGBPu/NgYUKJcwxdC?= =?us-ascii?Q?YgsRnBoNYCyqfTYR0wHwbr552GE4F88aP4CHV35pZ7aTEtw4W6TyIXtMeDqS?= =?us-ascii?Q?9ELdt0owV4/CL0bB+1pWkCIS5k7RbvP5nICojEgByw4tgt+rpCKA0PnTQkSg?= =?us-ascii?Q?UDnuzkaW+H6QONHL6s=3D?= X-Microsoft-Exchange-Diagnostics: 1; BN4PR07MB2244; 6:D83R15LPvqhG5rNyp1faHG+1/LKWrPQwFDXiILop8pbsbg8zACCm0MYjXFFAjUPIkil5JFjbT8jLQI1jqp6nW/QD38fdoadu1FwTGzX+eORVqSAxRxOGvfo4mqcy1Kb505N0LjuxB/Js5yPP+dlNb52EXpomLxu21eDQmX67W06BmFcBafm1ev5OdCd75/XfjKyrdb0zpUOZNrSmyfIaqqi7NGsDH05WIzIBn93PJi5O4mV2L+5DBH6ANneQxt3v3aUjZcPz8wMPTa45tvkrIQipE3mP42P/9IpsMOcrR1g=; 5:BW4aduSQuA61VYXOQzfQXiS7mo/ykkP+byzotWlUrh6wQV45z2CXX+I6RA8JSD0IzPuOjmuZ/nI+kNCHQEZd0srK6S6mOJ+Bc99uCIFSZjL1EIdbxxTiu5+Ill4Sr72OPpb+4QFS7lX/e4C/w1/mCQ==; 24:uKdTE9XGwUJZ5Zapf5+WWjcC58tlKS4+kPThup7Qe183FU8X5GC+88+g3naEQWGFFsmJvwo7Sb2oQw8pNAbGoszZXWESYKw1MNuhhGMgkwU=; 7:X3mV1cXkKMPFFQERzCmOWBJjk8WTQpZkPXD7TzbKXMTosZyfl1z1K+R0q7zN/A84c5JF5LZCchavVt+aeVY3m8/eIX1gvQ8CSNVJOGj8k9QSXqz/7vVLgDDkdGPDNvEml5gVOT7hHLXtKhlkfV79NWPyM31Be43XI2aMSHW/M0zuxU9eZr9wdCT6OOGPtrQNG8cFgQXZidciCZ8njPlwh3ZB/QHw1oZEu5kOUJabUnjH8Ygrl3BQlHxXpMMjITyk SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 17 Aug 2016 11:49:19.2737 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN4PR07MB2244 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 | 38 ++++++++ arch/arm64/kernel/Makefile | 3 +- arch/arm64/kernel/entry_ilp32.S | 23 +++++ arch/arm64/kernel/signal.c | 3 + arch/arm64/kernel/signal_ilp32.c | 171 ++++++++++++++++++++++++++++++++++ 5 files changed, 237 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..3c6d737 --- /dev/null +++ b/arch/arm64/include/asm/signal_ilp32.h @@ -0,0 +1,38 @@ +/* + * 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 + +#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 20e8e66..7038ffb 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -27,7 +27,8 @@ $(obj)/%.stub.o: $(obj)/%.o FORCE arm64-obj-$(CONFIG_AARCH32_EL0) += sys32.o kuser32.o signal32.o \ sys_compat.o entry32.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..7cc9122 --- /dev/null +++ b/arch/arm64/kernel/signal_ilp32.c @@ -0,0 +1,171 @@ +/* + * 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 + + +#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 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; +} +