From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753647AbcEXAHX (ORCPT ); Mon, 23 May 2016 20:07:23 -0400 Received: from mail-bn1bn0100.outbound.protection.outlook.com ([157.56.110.100]:38820 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753230AbcEXAGi (ORCPT ); Mon, 23 May 2016 20:06:38 -0400 Authentication-Results: arndb.de; dkim=none (message not signed) header.d=none;arndb.de; dmarc=none action=none header.from=caviumnetworks.com; From: Yury Norov To: , , , , , , , CC: , , , , , , , , , , , , , , , , Andrew Pinski , Andrew Pinski Subject: [PATCH 21/23] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Date: Tue, 24 May 2016 03:04:50 +0300 Message-ID: <1464048292-30136-22-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1464048292-30136-1-git-send-email-ynorov@caviumnetworks.com> References: <1464048292-30136-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [50.233.148.158] X-ClientProxiedBy: DM3PR13CA0027.namprd13.prod.outlook.com (10.164.193.37) To SN1PR07MB2240.namprd07.prod.outlook.com (10.164.47.146) X-MS-Office365-Filtering-Correlation-Id: 97340992-44f8-4228-4177-08d383673e69 X-Microsoft-Exchange-Diagnostics: 1;SN1PR07MB2240;2:mKYUYh4ntTcAEvd8aZqcZ3OdoprFHAJFrv2dhYwuRRdTh5MHG6wdUtn5j5SxgdRPe3SjOiIf6dwyT7/MyWX+y6aK3YrjXbqJANY99hU/M5zPAvxEN07iSYseshjfw3dN9JANqhGBHeaqwZI4Bvbby9uOQ7Z8sMiLMM1dMfkGluqVt1ug+JzkIm8KRkFqlpMK;3:3y9XrcRJ0GmuIheybaU2D+JjfkBN+xkfrNVyKCx9529YMW+ErMSK1wDceUbdlcSliyDhHrgUJkuy/qwX1Cj6nnYjfhjoe9yPAzi3JxHpsVVuUCo5DcYU+7dSPL5ZtyGL;25:v+diPvw1YKNvDKbAvyjK2u8dcE9H8DwcyhJYgm5d6/6RX5+fXBR+wOvCh/RMoSlFqiZ6iMpT3CHO/o+c0tKZikwn/8u63dU1TmzqX5F75kNvNDElufUllSJFc7KIOUrDSPs1O75I2rq+f2zTCAmWus/qRxZFZYyciGQlrgKh5bZtkPWi1QhOyBUc9DYEVlpgUZPUGRHvMCXJQ5C5FeGi0BukAYaSJzq9HmRkumamscZlnfhwJSUu7cIa0P8YlQWxGbMnJx2FcV+iN7spyfctlsGjK5FkR7nVDrIGXrosUHtHiiOxyRygzVZg65dvQWOymWqDkVGaNLFgCz2CvOC7WDYh4Fj07xlnYu68cVnF69QCWSpcG4d+fdF+cZtaXzsHLbvklpxG2TOY515FVzaeTy4NDGTWpFtCld1TNM5qtE4= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:SN1PR07MB2240; X-Microsoft-Exchange-Diagnostics: 1;SN1PR07MB2240;20:rXl1wIsr0cmkwsvHNyRKNokdfiV+17cFGLM2tOsBbPHLX7Oq9bewsot5l5PNBWyKgcjyu/xK0QYMlZKwErlYib3iIP3esqU7dlMaYxr1UNdWAiYzlsmF3Q5bFl9/cigTLfSj6tqWnExLOdhptLKuaT56MNrhS/3fNbhkRQ15bpX7yXnNgPcc01d+kT+cKg2+rrj8qd9V4RQ55BOHzedv9hLitL1rzIa/0L7nkwGpSI7OZyP9lqDnpnPB5V5Kr6dEC3Y+rHniryqo7IvkjJZUOs8Y40mhsX+zJubWBtU5Qdn8lBtiT4HkwcJb2Zg4UpCIrzd9EwJAXKBdxnsGBHImxDASEYRVYN0V4Cmn2cfWhCoozxlmRE8XgI4Lf3TYE2M4sLf1xAn6ecTk+mlzXz9Yia0yjQfutSzPndbBiSfRcAdh39DlhivDSOYFJHnr2keiR+jpYkZCcHbzU5tzwQdU/2O1uvTTTOtJIY4EKP+z0mYJkAuy7UNjg07KQbDJRb2rpiVkmJnjA/jBTVrp/DwrdLPts5rorseRXwUROp1TYDRbybMHSEce9Lbo3AkbNihN7+9f2ozR2gbCf67AqN0igv1xNikbrQ3qLJZ/jJyTjV8= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(5005006)(8121501046)(3002001)(10201501046);SRVR:SN1PR07MB2240;BCL:0;PCL:0;RULEID:;SRVR:SN1PR07MB2240; X-Microsoft-Exchange-Diagnostics: 1;SN1PR07MB2240;4:L5b2pjiVtR1zR+2MC3/6APF19FtV3vM3qV4ffGmlfDsKbUx/zQAaPcTZYOEuMnCnN+EcMwC5GJTHguge7V+WzHDiz3P5Z2OzIpIqFRFXVO8IE1/TXL4dT0jNo6zl8KCittlJkAA/ei4IYEeo85TzEcZEWp4sOjKTbGc7GVTOjvnHrPRJIftynJGtjxpWwg8ubEtf7XP+gCus5Hf6SaGg6kUTI+XKOdE3acTG+y1l5xzayGZBTiemy5RS3GXwW0Ey9X8Lbq32sX3tPuJrHqGRJrNXl50kX3i5IxCMUbOsNz/cmnx/8qLs6HAYMb5ZkxTBdHPMw+sRPxFh+i67HJY+q1iEIfJdU4DBlBx+A4mkJTLhq1myNzkDeM44/m7UhUN3 X-Forefront-PRVS: 09525C61DB X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(43544003)(2906002)(5008740100001)(50986999)(2201001)(229853001)(48376002)(47776003)(5001770100001)(50466002)(33646002)(66066001)(4001430100002)(189998001)(92566002)(76176999)(81166006)(42186005)(76506005)(8676002)(19580395003)(50226002)(5003940100001)(77096005)(6116002)(15975445007)(5004730100002)(586003)(2950100001)(107886002)(19580405001)(4326007)(36756003)(2004002)(2101003);DIR:OUT;SFP:1101;SCL:1;SRVR:SN1PR07MB2240;H:localhost;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN1PR07MB2240;23:FOwdeVuE8wEbL5HMz4ts3QSqpmSt+2nx7eVrlzwP3?= =?us-ascii?Q?wiOixB8dCoSFocTmMN0WZzsqGcYmLEGYqE1GZPaEULD22B2kTr/kkcz6eKcV?= =?us-ascii?Q?I5O71J/eYcw1IEgkiSxowlgdY7T7tyV/QGcMfGE6nP/IXslvpNtxC7pz3pPK?= =?us-ascii?Q?xkYCQZF13iLWCyjMTNoTurpkNFIW7Br4RHAgSsdXgea43AzlUE66lJoF2UJF?= =?us-ascii?Q?4tg848tQMI4ZQlTS1sG+5ofnLCPCH21GsyDqO5bFR0ax7Hq+KoLJH+RUKiYO?= =?us-ascii?Q?wJCk+qO+DL1ar9xTD413tqdMaoUopiwk5YQtv5Xf16hFDyZaiQiCqr3hGY2X?= =?us-ascii?Q?qR5b4aMDHWlo5TTc2gkUnjhFREL57ANe63kMlsCMVmavlb0/0Vhx0JBT3MVe?= =?us-ascii?Q?vKNo5yJ2rxN/Gn2g0iz6eZTSdz7n7jOpF99l1zAJu+5aJk9ZOLuMs311dW5I?= =?us-ascii?Q?a1nvEFsrcEDCzx4KZI5aN//mvY7Sdbjyf2dGQ+wV69xzrzW1I2aq8dKod7eg?= =?us-ascii?Q?gR95bSMJzOiTK2oVBIGef6ae9dgZuhp3JrrThgwpmWlK5LI1E57e56xuLy1q?= =?us-ascii?Q?ocEYeqWmnSMr50Cb2ai3O3F9pIxS3Bk+LU6FsKpOPOTRG7XwnEJ0sxIYKBdW?= =?us-ascii?Q?SSKHuFltyHD60ueRQl8BqtFNyt+pZeiTniIG80+71xYHsKHl+lX/deidlf65?= =?us-ascii?Q?ka7Ri03vFQaTflronU4Ebs2v4vC6Z7zbIj3gHThkR6gTk06yM6Wg/BVvTvwr?= =?us-ascii?Q?puA7cD6LeJlQ1JlmbWVinokamatRu5t5rgo+kgErvrD/J3XFQS8JeeTTbS8f?= =?us-ascii?Q?rfGWYBjNFy5WTgwi4ndgRo3d3YiHWXmcLnCBpKfVOTboEENpNNvkvAp+H1JD?= =?us-ascii?Q?Be+izvFZAhZRpqlljWgHkvyMg3f1QfLypvkSvDSbcC/yJbPpre245Bw0nJ1Z?= =?us-ascii?Q?/fTtKnR51qvZiiCXi5xlA0zin8BMR918T9wHa0nVEEB3FqrwdxPJ/FFJNL7n?= =?us-ascii?Q?unP9S/L/i7udUI6pICrg+ma?= X-Microsoft-Exchange-Diagnostics: 1;SN1PR07MB2240;5:1oRJex/UBaH7eeG9QR3sBO4j8IwDbZACXFfDD1/IkZ1+VLolxyUziSk+8npzR/2+nykA1NP6iSawBsxni5XTSb+O5AmzPX44F8d4L8tq3/2TDMEpkQTXDwRNxWwe07CrYJWFTNE2Y/Jmzq1b+QzM+Q==;24:BBFg4GkiKCZdNCD+ORwhVIc49c5KfPoPTD4fzUgLYtl9ot7Z2JOpdbIOEv7untMytMXXU+IKVNnLBeJliqr+EmQXnAwSHctAkNtX2dLjahM=;7:wbe3ba2HixU6qv/QXIeFiLjyZA7yxN/ivFtql1J5UbE5rBYsOkyShLQlpw4ntixaZBPorp08Pczx3d3QSOYo3QEG5C/9WjUWKAwDhGLw2QR1JQ5PFuhvEFiSooUxvK2rN8DzpgBloxrAFi/AdaIAvEteqWSszoKR5ENcFO76QRyHwTLv6P7CSgBAzwyQzJIW SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 May 2016 00:06:23.9139 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN1PR07MB2240 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 | 192 ++++++++++++++++++++++++++++++++++ arch/arm64/kernel/sys_ilp32.c | 3 + 6 files changed, 257 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 3ed55eb..09e4373 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) += 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 f9fbf8a..45bcd96 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -35,6 +35,7 @@ #include #include #include +#include struct sigframe { struct ucontext uc; @@ -323,6 +324,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..841e8f8 --- /dev/null +++ b/arch/arm64/kernel/signal_ilp32.c @@ -0,0 +1,192 @@ +/* + * 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 + + +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->compat_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, + offsetof(struct ilp32_rt_sigframe, sig), usig); + regs->regs[1] = (unsigned long)&frame->info; + regs->regs[2] = (unsigned long)&frame->sig.uc; + } + + return err; +} + diff --git a/arch/arm64/kernel/sys_ilp32.c b/arch/arm64/kernel/sys_ilp32.c index d4cd2a9..a31d538 100644 --- a/arch/arm64/kernel/sys_ilp32.c +++ b/arch/arm64/kernel/sys_ilp32.c @@ -65,6 +65,9 @@ static unsigned long compat_sys_pwrite64(unsigned int fd, return sys_pwrite64(fd, (char *) ubuf, count, offset); } +asmlinkage long ilp32_sys_rt_sigreturn_wrapper(void); +#define compat_sys_rt_sigreturn ilp32_sys_rt_sigreturn_wrapper + #include #undef __SYSCALL -- 2.5.0