Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S964824AbcDEWNZ (ORCPT ); Tue, 5 Apr 2016 18:13:25 -0400 Received: from mail-bn1on0060.outbound.protection.outlook.com ([157.56.110.60]:15968 "EHLO na01-bn1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933827AbcDEWNR (ORCPT ); Tue, 5 Apr 2016 18:13:17 -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 23/25] arm64: ilp32: introduce ilp32-specific handlers for sigframe and ucontext Date: Wed, 6 Apr 2016 01:08:45 +0300 Message-ID: <1459894127-17698-24-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.5.0 In-Reply-To: <1459894127-17698-1-git-send-email-ynorov@caviumnetworks.com> References: <1459894127-17698-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [95.143.213.121] X-ClientProxiedBy: AM2PR03CA0038.eurprd03.prod.outlook.com (10.160.207.48) To DM2PR07MB621.namprd07.prod.outlook.com (10.141.177.140) X-MS-Office365-Filtering-Correlation-Id: 71282b05-5f1e-496e-4025-08d35d9f75b3 X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB621;2:i9vd8NVZHh0Wl+jdFaoj1Bp3Nl0zLifm9MUkb63zSUL5eQZHPLJb7b5t1e9/uB/rsJiANGjrox3paiq9WIwwBP4Wb7xqygh+OpetiK9Oq4yQad6a8u8hke/sYRjB95LpnKZ5OpKe8r6rbXBkxgur+b7tyyn91fslnvhIpxofobnRMxrmUsiLe9jzN1SpaIEW;3:uM2kGZnHB0diFy0bOeaJwGbKAgp9iyfT6DBUqIwg+XshHvgWnqliRItR+fQ0dhsNvRmEIT2h2XniwsqGn3+zvYSSsb3y0Xo/XCW8vJJ4BDd2slgQb1svr/Qy6Dxp0vLi;25:kvpyExD/3sVjKUAoAmq9uGN6t1JpYVi/sCA9U8KwxVh1xfZwTTLUx9fBvXI+XPT9SFZ4fcfH5Yfv2225A6Nvr5XU3W0wRduckDuvQh+kHs0yd2j5p8lcWvquD8hvwTfnkeCZ5YNVByujClgE7PM4B9o0rBHhlmCieOnFybgfHcWqQ6XZ6xvh6fBFf7cdAOnTW04Dhf0naFDEmjh4HTyTcbHz+te33WDHzM/3f8wBFJNcQ+wafH6jsRGmBXtlA2EEumhwJEnQMcHXYzXBpm7yFQCNFvbbbY1lUa0v6B0DPtQujWKjgDQjCtf9jK47ZzR0fUdNGy26QG6P/duXCVuhWbSSfMoGCcmVAd2dXnc46EM= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM2PR07MB621; X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB621;20:MMJ9k2aN7ANYBka5gTmZSgkyp0m7EN2ZA6isZxK+f7FQlFLb9TKPFC5/0MdS/LRJDcbpUSocaX3wZyxJafK1X9m/1FDzGjFoc2ZFEtped0bere6kvPlnsQug/PqOPFSlQ9nBjWC1Qu4EKAYei2xmZd4ArZp22ffvdac091soR97n/b3l9sZkHNjbCQ0VSNX0k1n6KGT22z40g71npxIZlchP/NQSsufeBIWkDTSyZPXaRVYlHkusL/8lYT5nqbC5E5KtDsUBGfQtpuU1Tnau+L5jVryUgkZ1oZwL3/ubaUu3eTU6ReKsXGx50/GmcVA8db02t8DfLc/r6cIAx/vUP0O3EuvJ+WDF0a7tjpRQYFL1FCskcInOsXo+yFEpvmWH87M2yyZPAQPRsquIFmYawv7AymVFHb94+hwzxSl3K8f/UE5IrDz2LhM5JBhiuIZ6kOysmL0rCHL6hYNOuE84vyJHNI35ZIEBvWevWvVsLn9tGmjaDk3JiNM0CaTS0MDBdqTV+IqD55i1WL4PAaSxhRdr1GtfznyGcdMJQTKb7Z5K6NOkT/ZwK2vLVO6vtU3+J7phikXxLFp+wbBSOFUKCAR4D3iInw5Wnv65LiR8WLA= 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:DM2PR07MB621;BCL:0;PCL:0;RULEID:;SRVR:DM2PR07MB621; X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB621;4:ZELiwv7VnzAnUXe4HFO4ShtiyKopKU7f2EsOkYkdZV9IlqYOb2KE3/+lAES2TbQ1KBBzcyjqk9T6B2RbZVyiO9xQbl+eTszc2AzwEMEuONZID+Jw+LKZw9bW8zzKDIzyZJRd+tSoPHGS53QcqAE2oay3Wf8fNW1J5Vfj8gD/I94IvCqlUWi1+BEfzTn8Bn4gVR2FNdP0CjpiywitbvKmxqkp2d9YXuvkONsqAdc2Cm9bryJyxfZjy+b75jUp10NwWh5Et+sIeZn5DSs5+FFPPtr9nXB1qHjqxB5koQl/Lxp83YiOpwNEn3LimK+mQ7tN3HlIm57CiW6a5byYoPr537DnbD/JVNvdKF7brewrCVf0dqbtaBYck/wgOn5mUyqW X-Forefront-PRVS: 0903DD1D85 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(43544003)(81166005)(107886002)(15975445007)(5004730100002)(4326007)(19580395003)(19580405001)(6116002)(3846002)(2950100001)(77096005)(586003)(66066001)(50226001)(2906002)(47776003)(33646002)(5008740100001)(48376002)(5003940100001)(5001770100001)(76176999)(76506005)(1096002)(36756003)(42186005)(229853001)(50466002)(189998001)(4001430100002)(50986999)(92566002)(2201001)(2004002)(2101003);DIR:OUT;SFP:1101;SCL:1;SRVR:DM2PR07MB621;H:localhost;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM2PR07MB621;23:Q0nLPeNKkuWYJcyijHL5fqb1LWi1stogPmN1QFteJx?= =?us-ascii?Q?1Mzb4+wnV7zbz3Xbo58o2a2FCjFUb0CWs61eVxFLVE95NGhFcSGIo1SQ9VBJ?= =?us-ascii?Q?f4HMYGY0EvZmxAIkNDiNUx0Uda/kfNkp1mh1o8suPALyz0g/TH4xBX1YLiy5?= =?us-ascii?Q?tapwF56kLUnXxIR16XLN2iV/7k4mxs6exIhmOM6T++pG9I19WqnbIZDH0Ypr?= =?us-ascii?Q?rz2Q6DHJpQv6Tjn2LQ98gDPa62gd+9yJTkpFO9MqdpoTp8TiMMX7rGoJ7B58?= =?us-ascii?Q?hl903H9DUbwyw7nG0FSg6j+eIJBNCMlqy6N/STMzp8ACHmpQ7ql/9NCniCWu?= =?us-ascii?Q?L6g1W9LVuj01177RCpqQxKLiKr2+BswPYDQ3ZvLuAT29IxZrKhap8CvdHtyw?= =?us-ascii?Q?E/8exrm9NWY0js6oLmQs17D1E4EJTjWuukxXPFuOxcJZnuoVC5fbhoLhVgpt?= =?us-ascii?Q?Knrf5xyMgh69UjiKLO5XkLwXAeq4c6y4Y+QCZfFuWgPbxbXaQUL3Ms4AxOEj?= =?us-ascii?Q?I1D6SnDBb1KHyyH+raWxDGODH57McJ5foJuGC/je1RxirQ6Q2Ah30amcS3Rn?= =?us-ascii?Q?HL8EiyKJWOLlkqurHI+V6iuCUhXvT2RzLx58UNygbcWc8vzqvqj+X/xsTu5q?= =?us-ascii?Q?B9zAjCHvBuCSo0lFnzYo/Bj2PW8JCSB0BetnsR9Vm8dTEejbP0pUd/ceWJuX?= =?us-ascii?Q?LAZ8t2dpkay01yjoP4VikE7uiYexhgwMIZeyZnR3Islv5KllyPxLGJ+vL8WZ?= =?us-ascii?Q?vl7QqAgb2ZPGD7D+Q3A7rpm3HIx67D6wdrcnyu7w6I8e2BiiHHLvg5xbsrZI?= =?us-ascii?Q?cbPTMRyTWuaX3i9E/s5Pnm+Qo8nIf+0n2jE7ckA/c7nxQaimL+k8QAVqmyIh?= =?us-ascii?Q?v0Z0yNvHvAptOhAVQX+dU80x0mqfqJrBxi2f+74NFn1t99CBfQdXWgAvOZKQ?= =?us-ascii?Q?JgOLnnDE8S4O03n0bLhdyz1uIz/NWdmwS9m3uvRs51T68+1N3d5HFTaBx+jh?= =?us-ascii?Q?MynrdQtaPeM2bs9EFZa7vkAfFxOV4vLm+Ii6HXQQ+04p2dYHUAUFk9tOnxIj?= =?us-ascii?Q?FvSoc=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM2PR07MB621;5:t7E8SxUHJjWatSt9uxTDlBU0q1qVKRpo02wXNWwvpHDynw4EmGXZ76rUMZbZ+IbbnOSWtoOeaUsiO+uJRnt6kIlUysN2wqIx/UralUChTDAdJwn5nKSwDS30mdNmTpxhfE2oLVuyAEHB118wWGKPog==;24:Lw0QpyhcIQUXTAGkH0AtNxFdKTVkKZPQGoxusKFX2tIecIdusycoci4RJ91Zcuh/97xIgg0ZWDTBSWhitGb+QZza1iKMzyqab4SEeFIIEhE= SpamDiagnosticOutput: 1:23 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 05 Apr 2016 22:13:04.1174 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM2PR07MB621 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 10468 Lines: 338 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 0996d8e..1458ad7 100644 --- a/arch/arm64/kernel/sys_ilp32.c +++ b/arch/arm64/kernel/sys_ilp32.c @@ -43,6 +43,9 @@ #define sys_llseek sys_lseek #define sys_mmap2 sys_mmap +asmlinkage long ilp32_sys_rt_sigreturn_wrapper(void); +#define compat_sys_rt_sigreturn ilp32_sys_rt_sigreturn_wrapper + #include #undef __SYSCALL -- 2.5.0