From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S935074AbcJUVJM (ORCPT ); Fri, 21 Oct 2016 17:09:12 -0400 Received: from mail-by2nam01on0084.outbound.protection.outlook.com ([104.47.34.84]:5078 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933451AbcJUVJJ (ORCPT ); Fri, 21 Oct 2016 17:09:09 -0400 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@caviumnetworks.com; From: Yury Norov To: , , , , , CC: , , , , , , , , , , , , , , , , , , , , , , Bamvor Zhang Jian Subject: [PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32 Date: Fri, 21 Oct 2016 23:33:12 +0300 Message-ID: <1477081997-4770-14-git-send-email-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> References: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [95.143.213.121] X-ClientProxiedBy: AM4PR02CA0032.eurprd02.prod.outlook.com (10.165.239.170) To DM3PR07MB2249.namprd07.prod.outlook.com (10.164.33.147) X-MS-Office365-Filtering-Correlation-Id: adc647c8-17b0-4028-c0de-08d3f9f1d59f X-Microsoft-Exchange-Diagnostics: 1;DM3PR07MB2249;2:okEVqE//L3KGHjmoCnVNAyZofIHkht81Sw8vmWn0jW9yJL7RdH3fl9KTyxJORCsPjaztZm25Ewo70DjNXk43UcFXgoLAqj7rJtjvznSTY4JgQFzNJ55Z1tcixz8r8u/3tmtyQAyvM5zapCuvHfVwEhJX/Ddgy07p1jMniUh55eprg+C1gvdqff3OlAu/LJIemzi1UOQGAgfvC8r6I8CIUA==;3:WkvsfQtGIXZbfyQZtyCZ7uQtC5dw9jqW42AX0WxLfSDIQZLUAFDCmrGa6zHvLRg+TwOJFS00OUlQBGABIsTf5T1R3nmEqF2ZmSMAgUcnvG4N0AbAqWIKO/iOjdcQz673ZCvzwnNQRicU6XLvyLuILw== X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:DM3PR07MB2249; X-Microsoft-Exchange-Diagnostics: 1;DM3PR07MB2249;25:j+YI5boy5SCTy1wWMsW2xuVpLrf9qDobe5ihNSITkasKqku8sDoxOLDwsaxRBLCVcFVBiyaXaAjV4S5wYl5qrj4ZsXgNVdiRMnSPM8aREc1ScI3DhyzwQqcYsrGlQe8B954xDeCVTUlnP9DDsTsAaUce6h5dEPFGbohb0dc1c+RimW3O0Btk1xoO7rVagxjbmq4N3mGq7C7Opgo9tRFjgeTEM53hHVRj7XBP9j3piiL9Aeyf5YQ088OeVqkk7bRzpXF69xgb/5lgh5+DPiVTVyuBCw/vFFKDChfHuQ1232tjYh+t7ZFICGxh2zsaeTM0hxKz4vivZRhUH+7sM2+pUQExRWi0XjqEsGIk/ohF8g+2X1mP3auSFr2kDlAvPWTOdlxAp1SCtUjqW98c3wA6st1HHUXHhV6XRl/7I665c02hfukU4qezzr1hH3d60PDuS6LBxzogLWcwzPJSIwfZ/ih3xNTJnxpejt7xhMQlZ+fmUdYlh58uMgxFxZITSvq1emlTyeijBTbdB95s1MoueV0qONjDHk9O3ykvFXlsabiLCfD5Dwmc39t1ZmW8rfBub3+c9OsJnGTzN1YWyzURoncQOXAzsYOAbngIfddsBSJuZ2wnubvVqCpZ1VlEnbPvxFarTDWLfLlvHqQmOagE64CbaEhByDTOCqUMoZz60TzP8Im7bZCueqIienjp58VdqtTEATWnIIBg9eDlfo8+68rGvDUyZEv7Zv6KeTjitFUiQqexALVAqHhQeDBm/zG9rTxu78MGPB1/7Jo92lRP1pQNQ/W93Ksh1wxN6FZVsEnZA2q/NAv9IoG70aG7rYGBukPj6XPUV8+DoEtTl9KKgPfBoWZ2KB1mWitOTOfirdqNo2E7EgojMJRJnlU15JYF X-Microsoft-Exchange-Diagnostics: 1;DM3PR07MB2249;31:S4GkkWoIkkfsJlKgMM0lJRTiFgJ3e5l2R+IMdt+Sd3NlmkASMwJ7h7lkXp2OLPfeR1gvqo6ly0NXs9xh0nnAqKuswouBMPOyWdj3tcv/autmLDl5+OnhJp/IO7b3WeBPTylKRoqICMWnvpR1n2ZBxhArqbbbnvUkqWKPODMgA6jurHKtZQH7JFCkoTdkKa1aifpaQJuxT4psZxSlAc6QsYaWG4u3j/oyU7QyUPB7QVjVE1GB4Ltu8WXLnL5UqIi5;20:fvZ0w6g/6LvOioIOCZsQ8nuBPD1qrXs4Y0iv/oSAfj2avCcXsrcI77PU1+t2VKeumVkbIFWt/iLtQie7quuZ9+td9VnKINwnX9njFBHbg4ociSmuNgt4Q6vIXzS/8M2myroVlwXg2tCd4mgHY+Mi6xfjqCndBO+kai7LYGDdK1IT3l25dqKH5m2HTzk33hOvre8EFwsM8d6FacteWaoXv/cY4eaQHr5DaCcyzArAv1Yr0vdrjfNMy35zVDyHIHSh1O4EKJYjN4YcuBOiIrBzMAFGmgBHbq4cjc5kU5Tf+NkaIVDc+KSirWW9ZO7Uaa6pD5DNUd8nYTmcfPvWdi6o7ZeWJiSD5EiBm5eI5da0lzZGzJIXb9fMacNHmazDG2P4yP4hJCBiVWz0hWl17vFzzTaeQDU37XxKCSH4fFCECZ50w1xYHOBJCLouqcVdZuM9fiVD1WvycrZ9v0dYsv5btJ4caC8lcCqImVGpa2+vY0e2rMIk7vSMwSNhZ2rBlmw4GUiWCJL8NTLTURarMzkLrNtK5VyHUKBnAVMFPvkh6r5BhIlRTYe5Td/AVuUhLmv3Lzejwajzj/Z87HdCCk4BuJoumdt0G5gSP/mArmyjMRE= 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:DM3PR07MB2249;BCL:0;PCL:0;RULEID:;SRVR:DM3PR07MB2249; X-Microsoft-Exchange-Diagnostics: 1;DM3PR07MB2249;4:NlTp4OPPXzyq+C6lV0RksIwXHNuLCYi78SGekVrnXTVjrRHMIXyvUg9Q3yaZ5cohJ+MDk1L7lFwk+eMmtxqDlI7r1sr1X8EXoq4+BBcAXpBezpGkv5FaLecpehOJbnuUhM+JsGlgWlbvM2KkWiiMpHe4hFDA/G2DmyH6GjOZFnDCF4qGuPqSMwNZBwDi5yoYzW4ViZxv7ryjZS4QDtocukotuupm6vhnNJiP+bkG/hohHuqMr6tnJCKC0NkGuX1uqAPvZw1e89sow8ROEpO6I46AsEnldVKdYAavb3fYPUhwTOgS/kXXDgnov5eAmYl3evVCzM8qETZ3HwBy8Jkj13JfLwG+NuJbzZe2XoHdawKTA/CEXcQJ0tdp27/HjdsBjP3935MZZrO80CtBMXJMW42PWSxNOByhhBZKvLuzdodsuyKLLdI2/iuArQdTKr4mTT2koRx+OHVMPpUwXq0RD0oMlyyJYXpRx/QOjbj60Ps= X-Forefront-PRVS: 01026E1310 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6069001)(6009001)(7916002)(189002)(199003)(50466002)(68736007)(5001770100001)(5660300001)(106356001)(101416001)(2906002)(7736002)(48376002)(305945005)(2201001)(4326007)(7846002)(47776003)(6116002)(77096005)(15975445007)(6666003)(2950100002)(19580405001)(19580395003)(36756003)(97736004)(586003)(229853001)(5003940100001)(66066001)(76506005)(7416002)(189998001)(42186005)(3846002)(92566002)(81156014)(105586002)(33646002)(50226002)(8676002)(76176999)(50986999)(81166006)(2004002)(2101003);DIR:OUT;SFP:1101;SCL:1;SRVR:DM3PR07MB2249;H:localhost;FPR:;SPF:None;PTR:InfoNoRecords;MX:1;A:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;DM3PR07MB2249;23:mH3taPTaMV5ar/+SJm19xGL4vjYd54i9g1EmHQpBK?= =?us-ascii?Q?OdhIhzpl4quadkOYwFj/vTrTqtmBoftHb2ZXdwG+mAK9QdtCc+z4GlNXx1pA?= =?us-ascii?Q?D9owj7O+14NSTTvEdz0L8EfqqlUU066pdiybktL+mtVUcrXIqyq5B0Ai/0h8?= =?us-ascii?Q?X2FEgA81D5fHJzds9L1ZoMb5tJlA8/WjExaz60n3eGLSlHgYjapG7rqiK/IK?= =?us-ascii?Q?PtktZl2gWTgWMDMuTaEgeI6A/QNZRfjGo2f/2tLr9xbc4o7A/0pfFjvf0SjW?= =?us-ascii?Q?0aw3QimubguhdPOzX3+6L5yTXWxboFfWBlBbRWhmjjeH33ToobHuSF8HRaAg?= =?us-ascii?Q?+n+7ZbRPZBcCmLMRe3ksLAsLx8ER3h4AiOdpT1cgyXFJuyYif3vH1wbqjFKb?= =?us-ascii?Q?vYIRPbLJuPj4O+s8CdZkhsN030KPaxD342sjnIqmyFjS0WaLW5iyH2/m4H0V?= =?us-ascii?Q?LGgq7qwG9/0ySUGB71d46nIGyNX6KfDMmYdjAW9erliiCM36Zikk5ynh5sPn?= =?us-ascii?Q?UWSk1RAMBfO3HXXZdVoqgcv/kCyu4P3Jra/5PG6piHusXbJx6iNwALPzOGl+?= =?us-ascii?Q?KRgO7+vq3SPg2Z63PzBOerbQBRjQAheHmAi2N+ti60uY0NMZDfTEbRv/Jd2L?= =?us-ascii?Q?JI0KZSDHLrmqfhtNWfPhZ9Tfv4nu3xuVXgFDeQ8aRc0BprPObBXWB5W5LJhp?= =?us-ascii?Q?KTPJ+AHk84AQBuI2YMlfkfUD3c9A7nLfWARVNHWfzd08Op5dAR7nRDs1+2Gj?= =?us-ascii?Q?Umw1TjLfGAx4I1ArdENzMWw3WoYAj3W0nnGHw9Ig7C9pz6mqoOUp3aICzlpY?= =?us-ascii?Q?5NfSbgmAzfkqSLQSdJQmnhwiEh5t6aN9rUKyohCVYuJ+dzNXgVtpawtv66NX?= =?us-ascii?Q?MjMaSKwPmXIhVTXkb6eb9vb4qQnqUV5TWuBtMrtB2DaBbafJ0VUXNIwCuEQz?= =?us-ascii?Q?YbSbe8I2rt1gOfoLwJ6gsJkVjc8GHAtaAFzCMEbTB/CiJHsBLcinx0QoCO5X?= =?us-ascii?Q?JBjOm7j7I4IP+f5qkCr7RgibcYX2F8uWOS6lM75/MKDwFyEkNBsgK5pfRSh9?= =?us-ascii?Q?6ZERjriNxbRAGAWNZoKiQPd01S44Klm+L7RFB197IKAYAzgAhpTapEBjSuNn?= =?us-ascii?Q?XzKykD+u25+wYv0uKiv4z7xHT9K4llNBBwd2BLEXlp4xJCDxrkbdIV+7nvEu?= =?us-ascii?Q?0w9S3nQTS7LkxfnXmha26XJHuL+yKfxqSwf1cpI+QUdob37NuZymrxhNQ=3D?= =?us-ascii?Q?=3D?= X-Microsoft-Exchange-Diagnostics: 1;DM3PR07MB2249;6:B+EAB8ndfmDZ3KDmyCnIFr/Nqu2aiBCeE33TrNS3alE7/Qpzhpqqd0X8dZkJYspfgc6re/FehBbsTJeAha/4jl8JsMfRoOTpF1pmErrgfJokxdbg5X2InMLUD0kgryq1Rraz2D1bL2Da7wn9YE+rKhnH+AkC/sihSjl2KrA2+pGYltK9owwkC8QqhJs0HqQ5ahsvzugRN9ptZ3TMg2ZiKka0w1UL1nUXF2Jdzx6A3DpG7lhi7kyQvggapsC3jgggioFYHTy8V+1s0TCx0qYMq77QWJqxhGuqSBztLbEiHh5+48brHWozKGRmr6RYHcK/;5:UatBLktqOHP+AjMatGLBE5BQDqx4DXu0Ins4n0tD11Yz3Iojovb5VX0ZFP/cfWRzWO1KqOniuhrsVgGyikQjFsEiJhE6YqZQKegiu/kUo8luPHSPGP/zvX7Lxodg+1k3Q41SELVFJ0rfIRHMcL8P5vqplIaJIS330sji2EfwfQs=;24:dCVX82mskmy6ecbo2+QK6P9Ld5Ry5/ImTfdH4ho5ZU4n3G7O7V2t5f95JCKbEntbHaVvRn8FoQBNrOBJX3aDGbD+nDhmqGOp6psNM0RsQ98=;7:Z1CL6L724XjBtAfOmy5iKU3eC3/hZIm5jRDgZe854K0vl6TB1M0m4iHpbMBFjzDoCXWOMeYeE388uKPCx2zxztD+OsecS/2QznhdmGCO6dEkGsZi4TuRpv8KTHnSnAZvdq9fPzNzzbWJb8keU4r8PMz0PWGDCY40GAEO8pfNP3CUHRlh3QWt0b3VMv3zd2m0XF7XB5zwQptBSPU7NFRy0AmsoqiyAiqz2mWAxjt6n1iSU4/D+SE2zAQRs3jIGKu7nk9lPB9Q6U3RZnxsQgetcRLImizNgSi2OvnkJAwOI6eHwnwFp0Rvg6z48nhoWcWmWfS6PvAiWLm2g4augqMYLGWJlenlTTBauBXRBmsbzhk= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 21 Oct 2016 20:35:45.2160 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM3PR07MB2249 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 Zhang Jian --- 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..756ed2c --- /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) 2016 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 f90cdf5..478d6c5 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: Yury Norov Subject: [PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32 Date: Fri, 21 Oct 2016 23:33:12 +0300 Message-ID: <1477081997-4770-14-git-send-email-ynorov@caviumnetworks.com> References: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=m.gmane.org@lists.infradead.org To: arnd@arndb.de, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-arch@vger.kernel.org Cc: szabolcs.nagy@arm.com, heiko.carstens@de.ibm.com, cmetcalf@ezchip.com, ynorov@caviumnetworks.com, philipp.tomsich@theobroma-systems.com, joseph@codesourcery.com, zhouchengming1@huawei.com, Prasun.Kapoor@caviumnetworks.com, agraf@suse.de, 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, Bamvor Zhang Jian , maxim.kuvyrkov@linaro.org, Nathan_Lynch@mentor.com, schwidefsky@de.ibm.com, davem@davemloft.net, christoph.muellner@theobroma-systems.com List-Id: linux-arch.vger.kernel.org After that, it will be possible to reuse it in ilp32. Signed-off-by: Yury Norov Signed-off-by: Bamvor Zhang Jian --- 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..756ed2c --- /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) 2016 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 f90cdf5..478d6c5 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 Return-Path: Received: from mail-by2nam01on0084.outbound.protection.outlook.com ([104.47.34.84]:5078 "EHLO NAM01-BY2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S933451AbcJUVJJ (ORCPT ); Fri, 21 Oct 2016 17:09:09 -0400 From: Yury Norov Subject: [PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32 Date: Fri, 21 Oct 2016 23:33:12 +0300 Message-ID: <1477081997-4770-14-git-send-email-ynorov@caviumnetworks.com> In-Reply-To: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> References: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain Sender: linux-arch-owner@vger.kernel.org List-ID: To: arnd@arndb.de, catalin.marinas@arm.com, linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-arch@vger.kernel.org Cc: schwidefsky@de.ibm.com, heiko.carstens@de.ibm.com, ynorov@caviumnetworks.com, pinskia@gmail.com, broonie@kernel.org, joseph@codesourcery.com, christoph.muellner@theobroma-systems.com, bamvor.zhangjian@huawei.com, szabolcs.nagy@arm.com, klimov.linux@gmail.com, Nathan_Lynch@mentor.com, agraf@suse.de, Prasun.Kapoor@caviumnetworks.com, kilobyte@angband.pl, geert@linux-m68k.org, philipp.tomsich@theobroma-systems.com, manuel.montezelo@gmail.com, linyongting@huawei.com, maxim.kuvyrkov@linaro.org, davem@davemloft.net, zhouchengming1@huawei.com, cmetcalf@ezchip.com, Bamvor Zhang Jian Message-ID: <20161021203312.qv030CcCTwSVQkQrqipCVmxlMVQKQu1r5qD7q6_1ZAE@z> After that, it will be possible to reuse it in ilp32. Signed-off-by: Yury Norov Signed-off-by: Bamvor Zhang Jian --- 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..756ed2c --- /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) 2016 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 f90cdf5..478d6c5 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: Fri, 21 Oct 2016 23:33:12 +0300 Subject: [PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32 In-Reply-To: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> References: <1477081997-4770-1-git-send-email-ynorov@caviumnetworks.com> Message-ID: <1477081997-4770-14-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 Zhang Jian --- 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..756ed2c --- /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) 2016 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 f90cdf5..478d6c5 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