From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753314AbdCATZJ (ORCPT ); Wed, 1 Mar 2017 14:25:09 -0500 Received: from mail-sn1nam02on0051.outbound.protection.outlook.com ([104.47.36.51]:23784 "EHLO NAM02-SN1-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753271AbdCATY5 (ORCPT ); Wed, 1 Mar 2017 14:24:57 -0500 Authentication-Results: lists.infradead.org; dkim=none (message not signed) header.d=none;lists.infradead.org; dmarc=none action=none header.from=caviumnetworks.com; From: Yury Norov To: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, Arnd Bergmann , Catalin Marinas Cc: Yury Norov , Andrew Pinski , Andrew Pinski , Adam Borowski , Chris Metcalf , Steve Ellcey , Maxim Kuvyrkov , Ramana Radhakrishnan , Florian Weimer , Bamvor Zhangjian , Andreas Schwab , Chris Metcalf , Heiko Carstens , schwidefsky@de.ibm.com, broonie@kernel.org, Joseph Myers , christoph.muellner@theobroma-systems.com, szabolcs.nagy@arm.com, klimov.linux@gmail.com, Nathan_Lynch@mentor.com, agraf@suse.de, Prasun.Kapoor@caviumnetworks.com, geert@linux-m68k.org, philipp.tomsich@theobroma-systems.com, manuel.montezelo@gmail.com, linyongting@huawei.com, davem@davemloft.net, zhouchengming1@huawei.com, Bamvor Jian Zhang Subject: [PATCH 15/20] arm64: signal: share lp64 signal routines to ilp32 Date: Thu, 2 Mar 2017 00:49:23 +0530 Message-Id: <1488395968-14313-16-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1488395968-14313-1-git-send-email-ynorov@caviumnetworks.com> References: <1488395968-14313-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [27.97.135.110] X-ClientProxiedBy: VI1P194CA0012.EURP194.PROD.OUTLOOK.COM (10.175.178.22) To CY1PR07MB2248.namprd07.prod.outlook.com (10.164.112.150) X-MS-Office365-Filtering-Correlation-Id: adab1b09-1e3e-4874-03de-08d460d85079 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:CY1PR07MB2248; X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2248;3:d4TQdpDAbcrrNWcJdizBC4YnHyG+DEChxRFBcoyNPfXxa4BEz3FnPILyROuZldffRM/xwBjH7EmweKGF2GwLGWYpJ1LfncxDVSUK0/ie2j9jMFa3N7iezCInJ3nrjdLd8VDbqwS9kWn8l06m1Y81XM04U1xT1rCTpvGMessZUqbMk/o5gEOewVgKEJs30lLnI0m+f06GVh/LDCAkHJOzRBqnEZLJYraEA3laGERRbXtBVh9P3GglhEkPsGkV06Pu7pv22T16UqptSPOuHS28jQ==;25:r9Caq2kiQM3S4i1fK0HBPjnI6+oTQiA6YHw+VoZP7bXyz5yvsHyL76SaBc2W2bbcM75iTABjL340U2xFWMi/3/u0o8atTs64FaHLS1AuYmv7x7WknKHLjutXl4gdaPuxIKWXdjDaew5/qqJHSzdi0/xTQnWI0CucZ3ykyyRqK8gp+I/w/67iKVYUGlSjMIXB6M3fDc+lHppYvmXODz1tgsu+IE6Zul7C/PFHKPFh/Dt6RIJxaBtIHKFBuDUp3/Y/LFyqtiLRzGq0zYT6QBbXwIl4X/lHNIWeS6zHFU7Cuybb/jyDCWrJEc5rDJ1t+3AVRf96UZJ+6aeYCTF4CyFk7VaafT++Q0Za7KCVRGWBM2Bf9fwGWHvoZxAMNxlf5T8bWsiWz0m5nG/Q6ZTXk4Pkh8KEeFI8ILLTq//4/QIW77PjtaXvW6jxsDZyP8QlgNkjen6IIFuHmvxyYsPXKmC5KA== X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2248;31:S3eckfbEUKO+iF77xnZWFReDwSsoz9SxGuA4Zh9rRJYOc2/+Bo3QOFkU5bI5nHSqcRxu//XM9phr2R5Prw4oOVwjac4P6IaqSxtgprfBjQ7X7cbfqNkShcLKnF4LqTKc8q3Xz3CYovog7F6U+p0Sp/y2NVokJmW8hm8DvJYEQ3IpBhuX3s2SdQiZNwBDLHo+1mbwrkaqFCQo7iOQGMSCc2tX3KdLPa1lXZLRM1xhDZJHQ292VFqjlOWMOhwlAmvTq7sXYK50Xrjpz7+PS5ySnQ==;20:SO6KpcXBUoH2vYRw7ckkqPbYX4CFKyP3ozYih2dIAqdronOh5sOCsdx+YdjNmrhfGEDsO7dV4DfjiY6belFB2pLiNIa1k5Himy2DaR+xyXbbWfSgPiAMbEvUPdear/DzIMAdePSexLH1stf9pnAnmwT7YosOMoaelvORd48PB253A3En2/qJsrvH/Sn+OekGvxOoTPr+mFpA2FcLZfxvP9T3VFyvHSDLkt814mpJ1qWGoJ16jqxBri57brxcvs/TcktTgdVDKndSjkpME45geEKWr6aHYeXZVarvcv7V22ojAK8cpcjPYWlwwaucm8U9/Lq8yUsI+Gko69+sP1EJKapDf2g0FLfe4+N5aGULfhaXI0LFKxrUZSRoM6qvzS5z4JhQnaXzJoNq9Q081ykgzi7CLctaA1/zylCFrkCnjv4ABOk0v4IMXaMgCatbZa+4esmx9MN//xMBvS9erFlqhYM8oBFviDayah8wBUmQes30uIzaA8h6K/F13C7g7pMmlZv6z2SEHzFt/rnLh7uowxNUNYtWUGsTF8ajCh0Y4M4Vwh9sQUhUU0axkAijyYwvOVZCDp4nl9z4AOJVQ70aa/yXDYb56Q3faZQKBw2R0k0= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(250305191791016)(22074186197030); X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(3002001)(10201501046)(6041248)(20161123562025)(20161123555025)(20161123564025)(20161123560025)(20161123558025)(6072148);SRVR:CY1PR07MB2248;BCL:0;PCL:0;RULEID:;SRVR:CY1PR07MB2248; X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2248;4:rkuJm38my4r8DEgAmfmytbO5NQ+gYrs/giLOcEWwVQfG9jDa1aY60dej1r58dT1QPFXzcdwJeY2gGdXANrgHPyQzvx++1GWhgSx2wQvh6dOMIDrMnLQSAU/tXff25zt8OBCVhHJgJHZX7W1/MaCpdOmGgm+ketntA61vzpmKoSZAbYeTOOJg9UmuR+rZqHdhYfiFXwoKpH9rzwTIp9+ryX5VW7poAUhrPyMOYBgZQKN/jjzkhNaRTELG39Rrtgp1jDh1ytGf4hIwF/aI406OLRQM+EK+Svb3Wwdjy3MiAAkPp5TNx11YifbcrYCUDLzcYZJQrNY+TUeuwPefhrC5fi8uxPgAtdmG+XDxYMxUoLW5/B8HQIFLH3SwxlWvUkXHDBQ39u9PYeOtxhRa+NA0UsAivHrDnclEwozYsA33jBTAvQSpmgpIyt/gl1EFihL4/8eCxfqqCrOfjqAjBhBFJC7JOGt8k4L4JvdM0VOTH1sSgXjgjniEFYdBguw1eciw/QKAEgbHuq3OfM+8ajjIWNzcPrfH7+FbXl0GU1N7gJXEBuHIXtvTPakPaI9opY4d/5fxUGKS/GQJ5q2kHdjGh4xDUrc5GEK0uwMxsZTBb+UBhRNcXOK394awZdTJ1C2jmjswJpVQf9R4Da2WpsGkXwmOEli+vOaiaTISnpDLjKBoPzseYfe9fFS3x8Fz1iYg X-Forefront-PRVS: 0233768B38 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(7916002)(39450400003)(50226002)(36756003)(53936002)(38730400002)(76506005)(5003940100001)(42186005)(6496005)(7736002)(6666003)(4326008)(5660300001)(2950100002)(50986999)(92566002)(76176999)(8676002)(305945005)(81166006)(5009440100003)(50466002)(6116002)(66066001)(189998001)(48376002)(54906002)(6306002)(3846002)(47776003)(25786008)(7416002)(2906002)(33646002)(6486002);DIR:OUT;SFP:1101;SCL:1;SRVR:CY1PR07MB2248;H:localhost;FPR:;SPF:None;MLV:sfv;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;CY1PR07MB2248;23:UQPF4bZWX5tOz/J6plqdKH2+JJzYdeYpvsgwMfNTr?= =?us-ascii?Q?459XAaAvOM9K95JqJUqGRZ1BE9A05gwCcFJOMZfnLCPX6m8wOROnQBxqEwTN?= =?us-ascii?Q?/ef3j1Vt0e6GqwfUWnrdLgvMRVy+uh9HF4qeJXH7WqCuBOIXOrMXQNcAK4n4?= =?us-ascii?Q?T3HP9FgNDLeeYgatUma3X71Mi1TgnxA/+A3wTpJSnPwWToOJw5awcj0CMg0O?= =?us-ascii?Q?r+fSbepjwzE4eLsULMGq6ecRtfPsrC8AXJO6DqEwyjAfc5sfPC1dU6SbBWiL?= =?us-ascii?Q?hypKgt20sLRs/WvVrJJdZ0tXRhRhuapurSay9ytxVnP5HByki4hrfGb2IPOA?= =?us-ascii?Q?Ks7mMrXy5cF7/nym/CTL+VmLh0UkinEoOZY50bYShEO6zS6CmAeoRJ/ind7J?= =?us-ascii?Q?Ca3OUTD07hCHON8WmD+rM1va5moFe283sUzdqCnqba9fLVu3QXgZhgFDc2AN?= =?us-ascii?Q?I7nyAqYOwFBZQk5NubUruQuPqLDcWJ8Vs79OnnEVifv7/9TU/EPy1xhfwgg5?= =?us-ascii?Q?LjWVkcNeRGHEejeaaXB/KFbt54ucmh/X6OV1XeOOsHtzhl9IYcqKhFFyRaom?= =?us-ascii?Q?nki9Ejlo+4b1MnzU2CtK5CqoZEGm2FlOAMwATf5SzbEd9xz6tPyASIDL+7km?= =?us-ascii?Q?i0SRD/FSgu3SyPys7tdfBcclPgMDTnwLlU2z3bHe+kHnXjKjZAbw2dEb87ZJ?= =?us-ascii?Q?yb55ZolbkOJVpScdcn36eErZTZqbsjhmDoBhBA7f6sJ0074yeIL5ew7R43zb?= =?us-ascii?Q?gi28cJCADBIZXDoCI2wZPQkzPqY+PQjAXRJoC29fUyP1ZBJLr+LyUte5LcMU?= =?us-ascii?Q?TXAFhsl80TNdc3Fzv+QoE2Gw3qcw+wWoYO6QagCfwCu6ZAWb5hHQOkLPnH5c?= =?us-ascii?Q?xYdc0vPRZh3szAk+QUmMSp+gfQAIMZ5empr5+EnrlEDQefk0NanKdyke5itR?= =?us-ascii?Q?YIv6s7S49grNYIestzpPTbq+emjlePbGl6CEJSesHXF+V7AJsX9batPtrhqL?= =?us-ascii?Q?Qo=3D?= X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2248;6:i4ISn/FG3XqhJrjA8cnvMqGn5DsHuHrbAmqDltMGd/BMJv998Rpznk7Es0nr0lnhyxrP55xRDaPp6gKgRDNMEzhwtC121H01yR7lKkhysK+qc6LHqgSexLMRriF1M2QEGuLuLiDYYNJcwfFDG/B7sdOQsagp8UGykhKQgrY+Brx2mrwKDD38VAaFxtXJtXvVPgj7na5YIDGmYKgQ+upt1kY6HXdqQKO82twy6tcSvMI6hvGiJqcao10KKddXH/TNYmXSWp0afK/MLaen6Au/Q8123ulYmQwt4XhD9Qc2F9g7KWyIYF+OstvbMVa32qfPei/cqfYjCkUiMRS3jrfQjmdzfyuf+WmyjHA9O/S61RI0vwZmfzUdoJe5Ifkwlvk/8ZpKkQYEXxVwpKiCTml5Qg==;5:eP6sfHDTeXS1d62HQEaC27k5ZgGuphiGxgA0kT/kZPNGmqTBz0kGyaOWy8pkSlmudUhrzRqw9sUv5VE5O37N4hCIqtXk3TOZHQC+OrB3qeAZUDF+qmOMPC/FnTQMv+aE3qM5tEUeRWXTnjtdyiR3BI6AcnkXKUWV+IhNYtGqIW8=;24:iTt/Ye287si7TWk2pLtpmAOaK+geAklqhSxDgVi70OHyQLPEd+sWqDFdmVBhKKqF5l9YVtoYVFoVOtTpc/habrUE/U7ASiO8X18ogFmfTeQ= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;CY1PR07MB2248;7:DAsnK8SvOoEdY1HnH3fSPmBoTwXs66EfD10kCSxA6r3huY2Kvzux1Js8cKIbMO5ocK/PQn6K2zFK/cVAvrqUX/XoY8URcD7FbMJ0AhfhXPgRYe7eDBa4PpEJJcmF4Bh8avYcKzSP8xb4HoDgloXSl+By3v3QZoX58b0l/kUvHZ9qEf4FzQvSWNLxPutZ+VPF7PnuMbVRM35rJCst7UIlD2r+4nhqmwbyMQWNEfGllnqQyit0gVS7ABitrGfPjH7HVtwiWCObVd2SctxKM0kibg9qtrnGmPEyY65KPKLbpcdDpxfNISPvB1hdNGqlQMefqcoYseddbY6iTtkXaM9Qqg== X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Mar 2017 19:22:33.5080 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY1PR07MB2248 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After that, it will be possible to reuse it in ilp32. Signed-off-by: Yury Norov Signed-off-by: Bamvor Jian Zhang --- arch/arm64/include/asm/signal_common.h | 33 ++++++++++++ arch/arm64/kernel/signal.c | 93 +++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 arch/arm64/include/asm/signal_common.h diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h new file mode 100644 index 0000000..f682381 --- /dev/null +++ b/arch/arm64/include/asm/signal_common.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 1995-2009 Russell King + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2017 Cavium Networks. + * + * 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_COMMON_H +#define __ASM_SIGNAL_COMMON_H + +#include +#include +#include + +int preserve_fpsimd_context(struct fpsimd_context __user *ctx); +int restore_fpsimd_context(struct fpsimd_context __user *ctx); +int setup_sigcontext(struct sigcontext __user *uc_mcontext, struct pt_regs *regs); +int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sf); +void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + void __user *frame, off_t sigframe_off, int usig); + +#endif /* __ASM_SIGNAL_COMMON_H */ diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 5fa1b40..9f2ea60 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -34,18 +34,26 @@ #include #include #include +#include + +#define RT_SIGFRAME_FP_POS (offsetof(struct rt_sigframe, sig) \ + + offsetof(struct sigframe, fp)) + +struct sigframe { + struct ucontext uc; + u64 fp; + u64 lr; +}; /* * Do a signal return; undo the signal stack. These are aligned to 128-bit. */ struct rt_sigframe { struct siginfo info; - struct ucontext uc; - u64 fp; - u64 lr; + struct sigframe sig; }; -static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) +int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; int err; @@ -65,7 +73,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; } -static int restore_fpsimd_context(struct fpsimd_context __user *ctx) +int restore_fpsimd_context(struct fpsimd_context __user *ctx) { struct fpsimd_state fpsimd; __u32 magic, size; @@ -93,22 +101,30 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx) } static int restore_sigframe(struct pt_regs *regs, - struct rt_sigframe __user *sf) + struct sigframe __user *sf) { sigset_t set; - int i, err; - void *aux = sf->uc.uc_mcontext.__reserved; - + int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) set_current_blocked(&set); + err |= restore_sigcontext(regs, &sf->uc.uc_mcontext); + return err; +} + + +int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *uc_mcontext) +{ + int i, err = 0; + void *aux = uc_mcontext->__reserved; + for (i = 0; i < 31; i++) - __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + __get_user_error(regs->regs[i], &uc_mcontext->regs[i], err); - __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); + __get_user_error(regs->sp, &uc_mcontext->sp, err); + __get_user_error(regs->pc, &uc_mcontext->pc, err); + __get_user_error(regs->pstate, &uc_mcontext->pstate, err); /* * Avoid sys_rt_sigreturn() restarting. @@ -145,10 +161,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) goto badframe; - if (restore_sigframe(regs, frame)) + if (restore_sigframe(regs, &frame->sig)) goto badframe; - if (restore_altstack(&frame->uc.uc_stack)) + if (restore_altstack(&frame->sig.uc.uc_stack)) goto badframe; return regs->regs[0]; @@ -162,27 +178,36 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) return 0; } -static int setup_sigframe(struct rt_sigframe __user *sf, +static int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { - int i, err = 0; - void *aux = sf->uc.uc_mcontext.__reserved; - struct _aarch64_ctx *end; + 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 |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); + err |= setup_sigcontext(&sf->uc.uc_mcontext, regs); + + return err; +} + +int setup_sigcontext(struct sigcontext __user *uc_mcontext, + struct pt_regs *regs) +{ + void *aux = uc_mcontext->__reserved; + struct _aarch64_ctx *end; + int i, err = 0; for (i = 0; i < 31; i++) - __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + __put_user_error(regs->regs[i], &uc_mcontext->regs[i], err); - __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); - __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); + __put_user_error(regs->sp, &uc_mcontext->sp, err); + __put_user_error(regs->pc, &uc_mcontext->pc, err); + __put_user_error(regs->pstate, &uc_mcontext->pstate, err); - err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); + __put_user_error(current->thread.fault_address, &uc_mcontext->fault_address, err); if (err == 0) { struct fpsimd_context *fpsimd_ctx = @@ -229,14 +254,14 @@ static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig, return frame; } -static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, - void __user *frame, int usig) +void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + void __user *frame, off_t fp_pos, int usig) { __sigrestore_t sigtramp; regs->regs[0] = usig; regs->sp = (unsigned long)frame; - regs->regs[29] = regs->sp + offsetof(struct rt_sigframe, fp); + regs->regs[29] = regs->sp + fp_pos; regs->pc = (unsigned long)ka->sa.sa_handler; if (ka->sa.sa_flags & SA_RESTORER) @@ -257,17 +282,17 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, if (!frame) return 1; - __put_user_error(0, &frame->uc.uc_flags, err); - __put_user_error(NULL, &frame->uc.uc_link, err); + __put_user_error(0, &frame->sig.uc.uc_flags, err); + __put_user_error(NULL, &frame->sig.uc.uc_link, err); - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigframe(frame, regs, set); + err |= __save_altstack(&frame->sig.uc.uc_stack, regs->sp); + err |= setup_sigframe(&frame->sig, regs, set); if (err == 0) { - setup_return(regs, &ksig->ka, frame, usig); + setup_return(regs, &ksig->ka, frame, RT_SIGFRAME_FP_POS, usig); if (ksig->ka.sa.sa_flags & SA_SIGINFO) { err |= copy_siginfo_to_user(&frame->info, &ksig->info); regs->regs[1] = (unsigned long)&frame->info; - regs->regs[2] = (unsigned long)&frame->uc; + regs->regs[2] = (unsigned long)&frame->sig.uc; } } -- 2.7.4 From mboxrd@z Thu Jan 1 00:00:00 1970 From: ynorov@caviumnetworks.com (Yury Norov) Date: Thu, 2 Mar 2017 00:49:23 +0530 Subject: [PATCH 15/20] arm64: signal: share lp64 signal routines to ilp32 In-Reply-To: <1488395968-14313-1-git-send-email-ynorov@caviumnetworks.com> References: <1488395968-14313-1-git-send-email-ynorov@caviumnetworks.com> Message-ID: <1488395968-14313-16-git-send-email-ynorov@caviumnetworks.com> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org After that, it will be possible to reuse it in ilp32. Signed-off-by: Yury Norov Signed-off-by: Bamvor Jian Zhang --- arch/arm64/include/asm/signal_common.h | 33 ++++++++++++ arch/arm64/kernel/signal.c | 93 +++++++++++++++++++++------------- 2 files changed, 92 insertions(+), 34 deletions(-) create mode 100644 arch/arm64/include/asm/signal_common.h diff --git a/arch/arm64/include/asm/signal_common.h b/arch/arm64/include/asm/signal_common.h new file mode 100644 index 0000000..f682381 --- /dev/null +++ b/arch/arm64/include/asm/signal_common.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 1995-2009 Russell King + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2017 Cavium Networks. + * + * 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_COMMON_H +#define __ASM_SIGNAL_COMMON_H + +#include +#include +#include + +int preserve_fpsimd_context(struct fpsimd_context __user *ctx); +int restore_fpsimd_context(struct fpsimd_context __user *ctx); +int setup_sigcontext(struct sigcontext __user *uc_mcontext, struct pt_regs *regs); +int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sf); +void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + void __user *frame, off_t sigframe_off, int usig); + +#endif /* __ASM_SIGNAL_COMMON_H */ diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 5fa1b40..9f2ea60 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -34,18 +34,26 @@ #include #include #include +#include + +#define RT_SIGFRAME_FP_POS (offsetof(struct rt_sigframe, sig) \ + + offsetof(struct sigframe, fp)) + +struct sigframe { + struct ucontext uc; + u64 fp; + u64 lr; +}; /* * Do a signal return; undo the signal stack. These are aligned to 128-bit. */ struct rt_sigframe { struct siginfo info; - struct ucontext uc; - u64 fp; - u64 lr; + struct sigframe sig; }; -static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) +int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { struct fpsimd_state *fpsimd = ¤t->thread.fpsimd_state; int err; @@ -65,7 +73,7 @@ static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; } -static int restore_fpsimd_context(struct fpsimd_context __user *ctx) +int restore_fpsimd_context(struct fpsimd_context __user *ctx) { struct fpsimd_state fpsimd; __u32 magic, size; @@ -93,22 +101,30 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx) } static int restore_sigframe(struct pt_regs *regs, - struct rt_sigframe __user *sf) + struct sigframe __user *sf) { sigset_t set; - int i, err; - void *aux = sf->uc.uc_mcontext.__reserved; - + int err; err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); if (err == 0) set_current_blocked(&set); + err |= restore_sigcontext(regs, &sf->uc.uc_mcontext); + return err; +} + + +int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *uc_mcontext) +{ + int i, err = 0; + void *aux = uc_mcontext->__reserved; + for (i = 0; i < 31; i++) - __get_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + __get_user_error(regs->regs[i], &uc_mcontext->regs[i], err); - __get_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __get_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __get_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); + __get_user_error(regs->sp, &uc_mcontext->sp, err); + __get_user_error(regs->pc, &uc_mcontext->pc, err); + __get_user_error(regs->pstate, &uc_mcontext->pstate, err); /* * Avoid sys_rt_sigreturn() restarting. @@ -145,10 +161,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) goto badframe; - if (restore_sigframe(regs, frame)) + if (restore_sigframe(regs, &frame->sig)) goto badframe; - if (restore_altstack(&frame->uc.uc_stack)) + if (restore_altstack(&frame->sig.uc.uc_stack)) goto badframe; return regs->regs[0]; @@ -162,27 +178,36 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) return 0; } -static int setup_sigframe(struct rt_sigframe __user *sf, +static int setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) { - int i, err = 0; - void *aux = sf->uc.uc_mcontext.__reserved; - struct _aarch64_ctx *end; + 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 |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); + err |= setup_sigcontext(&sf->uc.uc_mcontext, regs); + + return err; +} + +int setup_sigcontext(struct sigcontext __user *uc_mcontext, + struct pt_regs *regs) +{ + void *aux = uc_mcontext->__reserved; + struct _aarch64_ctx *end; + int i, err = 0; for (i = 0; i < 31; i++) - __put_user_error(regs->regs[i], &sf->uc.uc_mcontext.regs[i], + __put_user_error(regs->regs[i], &uc_mcontext->regs[i], err); - __put_user_error(regs->sp, &sf->uc.uc_mcontext.sp, err); - __put_user_error(regs->pc, &sf->uc.uc_mcontext.pc, err); - __put_user_error(regs->pstate, &sf->uc.uc_mcontext.pstate, err); - __put_user_error(current->thread.fault_address, &sf->uc.uc_mcontext.fault_address, err); + __put_user_error(regs->sp, &uc_mcontext->sp, err); + __put_user_error(regs->pc, &uc_mcontext->pc, err); + __put_user_error(regs->pstate, &uc_mcontext->pstate, err); - err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); + __put_user_error(current->thread.fault_address, &uc_mcontext->fault_address, err); if (err == 0) { struct fpsimd_context *fpsimd_ctx = @@ -229,14 +254,14 @@ static struct rt_sigframe __user *get_sigframe(struct ksignal *ksig, return frame; } -static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, - void __user *frame, int usig) +void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + void __user *frame, off_t fp_pos, int usig) { __sigrestore_t sigtramp; regs->regs[0] = usig; regs->sp = (unsigned long)frame; - regs->regs[29] = regs->sp + offsetof(struct rt_sigframe, fp); + regs->regs[29] = regs->sp + fp_pos; regs->pc = (unsigned long)ka->sa.sa_handler; if (ka->sa.sa_flags & SA_RESTORER) @@ -257,17 +282,17 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, if (!frame) return 1; - __put_user_error(0, &frame->uc.uc_flags, err); - __put_user_error(NULL, &frame->uc.uc_link, err); + __put_user_error(0, &frame->sig.uc.uc_flags, err); + __put_user_error(NULL, &frame->sig.uc.uc_link, err); - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigframe(frame, regs, set); + err |= __save_altstack(&frame->sig.uc.uc_stack, regs->sp); + err |= setup_sigframe(&frame->sig, regs, set); if (err == 0) { - setup_return(regs, &ksig->ka, frame, usig); + setup_return(regs, &ksig->ka, frame, RT_SIGFRAME_FP_POS, usig); if (ksig->ka.sa.sa_flags & SA_SIGINFO) { err |= copy_siginfo_to_user(&frame->info, &ksig->info); regs->regs[1] = (unsigned long)&frame->info; - regs->regs[2] = (unsigned long)&frame->uc; + regs->regs[2] = (unsigned long)&frame->sig.uc; } } -- 2.7.4