Received: by 2002:ac0:a594:0:0:0:0:0 with SMTP id m20-v6csp1691300imm; Wed, 16 May 2018 01:24:49 -0700 (PDT) X-Google-Smtp-Source: AB8JxZrFUvwsa0xWw6W+3eXXSfJinLIl9LPXMEoNy/KJ/7p6xsLmYVZste8upAO5Ihq/nIcZniZU X-Received: by 2002:a17:902:b216:: with SMTP id t22-v6mr18357008plr.105.1526459089680; Wed, 16 May 2018 01:24:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1526459089; cv=none; d=google.com; s=arc-20160816; b=EsXegYnXmFaDZi1/BK2kDQ3esKpOYraRRWMLr/SCcbbHKYRlC9X6KBu5cR+R86pY7Y DRjumvSTYeQKNnUfGtaMi6bnoK6ya1/g3jc7sV2FXgyQTWYpepytU2fqJNzBaxhfgfMT 3A3f1wcoqC32gwc6pQpK1C3ak/eCsuKsUXFnV9RPh0Tb6bNGzEfVXNAuPh9SKAtvVdcQ pTZ13Y0bz7VrcwiMbbaO/Q3jx1VuzLvNSWcncFJu9bTn1DCkphIEt3TwznTwd7uc5ikh ib9ESRC+fVxWOeHNu8wG4/2QWekIrGhL4J5McK9ZKPgYUuvlwR5FmBqTZtHzXzHAba9j 2qHw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:spamdiagnosticmetadata :spamdiagnosticoutput:mime-version:references:in-reply-to:message-id :date:subject:cc:to:from:dkim-signature:arc-authentication-results; bh=CAu+1a9S+Gzhj2aEcuv3SLuKKsnLIXUynWAqDdQmCRQ=; b=ytBxJ6bbzh4zuCNjEPq58XE7TB1gTcCdqGfkIOq3+ImPedXQIkNU8hHPYXSkV6BMeW pPCfJ1Ku7w5nKLA7RpbD4Nz6h10AfsCX1gdcDLqU+RZ283sjx4xxhH1feQScW+7iMiOM uwKGDfCs7o8JklrUDIAEEGaSV4WrRHh6qdc0kOhK23JfSXXcgt17OMRFSL4Wj8brigef JfP3Yldx1CqcnDuMPbH1bzrthghgybB9QDDy2O0qgqzEbV1PwLxHnIGvnCTdIqsZjsjp 24esigQe7kcQTrnVW6a09Cwut68cT6udcHmDB8tKeuyCOjnlZqhIXyGqZER34+eq2eJA VNyw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@CAVIUMNETWORKS.onmicrosoft.com header.s=selector1-cavium-com header.b=aCrm5uks; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d30-v6si2084452pld.528.2018.05.16.01.24.35; Wed, 16 May 2018 01:24:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@CAVIUMNETWORKS.onmicrosoft.com header.s=selector1-cavium-com header.b=aCrm5uks; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753082AbeEPIXA (ORCPT + 99 others); Wed, 16 May 2018 04:23:00 -0400 Received: from mail-dm3nam03on0080.outbound.protection.outlook.com ([104.47.41.80]:41283 "EHLO NAM03-DM3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1752716AbeEPIWr (ORCPT ); Wed, 16 May 2018 04:22:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=CAu+1a9S+Gzhj2aEcuv3SLuKKsnLIXUynWAqDdQmCRQ=; b=aCrm5uksHuqX1uQFpBng9aUWcVgeVWi158NCblM0qd5roV14PXUGe9IvXScb59mZE6fCSc5eotDaBahIOB5/XGB5RQ4Tqn2KaAoXs5hnwy6cnCERuIjIF3r+HrQpE/JAC9fWUxbY3xWE9lWloSGdycq2gNefSRH/fsKsUTjfbhw= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Yuri.Norov@cavium.com; Received: from localhost (176.59.36.13) by SN6PR07MB4381.namprd07.prod.outlook.com (2603:10b6:805:58::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P256) id 15.20.755.16; Wed, 16 May 2018 08:22:41 +0000 From: Yury Norov To: Catalin Marinas , Arnd Bergmann , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org, linux-arch@vger.kernel.org, linux-api@vger.kernel.org Cc: Yury Norov , Adam Borowski , Alexander Graf , Alexey Klimov , Andreas Schwab , Andrew Pinski , Bamvor Zhangjian , Chris Metcalf , Christoph Muellner , Dave Martin , "David S . Miller" , Florian Weimer , Geert Uytterhoeven , Heiko Carstens , James Hogan , James Morse , Joseph Myers , Lin Yongting , Manuel Montezelo , Mark Brown , Martin Schwidefsky , Maxim Kuvyrkov , Nathan_Lynch , Philipp Tomsich , Prasun Kapoor , Ramana Radhakrishnan , Steve Ellcey , Szabolcs Nagy Subject: [PATCH 18/24] arm64: signal: share lp64 signal structures and routines to ilp32 Date: Wed, 16 May 2018 11:19:03 +0300 Message-Id: <20180516081910.10067-19-ynorov@caviumnetworks.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180516081910.10067-1-ynorov@caviumnetworks.com> References: <20180516081910.10067-1-ynorov@caviumnetworks.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [176.59.36.13] X-ClientProxiedBy: VI1PR08CA0121.eurprd08.prod.outlook.com (2603:10a6:800:d4::23) To SN6PR07MB4381.namprd07.prod.outlook.com (2603:10b6:805:58::12) X-MS-PublicTrafficType: Email X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(7020095)(4652020)(5600026)(4534165)(4627221)(201703031133081)(201702281549075)(2017052603328)(7153060)(7193020);SRVR:SN6PR07MB4381; X-Microsoft-Exchange-Diagnostics: 1;SN6PR07MB4381;3:QBANSMVlzKfo28s8Z6/+1TnpTvnpjOq5ik/RHr8xhe2D9dC5oL/y49qGQRYxZFIb1de5iS2sh1OKsYz5CmBlB7SKs4WQWa3SK8/TGjg6sqEwOlboNUP7JCpcQLPuKJlA+hkpCsTtssup0+SZK7RYJRW+Ghg2d4+iekObgAzC/f+zqEpmnM+NkzJ93TZJvY/J2HHb9rPuS2FIYPdkheOrBl5t3IP9PvkC2lEQ5O//fbr8/JQIMbEBFI89N7CcvFqU;25:0aKia9i04By5xpiFQcDFxjtGvRCYoIM7aGenkj/NXf5jhYh7RKGmRjB1d3xSV95O/F2jtQtcq1KExP3UCQR0JOkFMobmHfsY1aIX/qXblN8R66sMY1GsCup8AV4dXPxV9ykLcVLJOCyJEbNqpnweL5vkouwtGNoFRVpbGC2kJyCoYTC2j/E+/l6vhKuw/6ejn7DgaOPcEsUkN1QLI6DOJo3K/k7RranU/dGCqepOqKwBXWTplHwajT3OrJeRXRe4FysWalEk23Yp0aJOkEZTSBd1vhXJHROBGovYrgvKO7JZk/iccTYDA69Rt3psdbU2A9TVn+l++p+rfA7W1g0TNg==;31:gC2p0Ytp175g/uQxPIP+/ilkrvJfxdx4n5yziUUpzbuy4/q3IuUAIVggw5TmXFW7DdVw6ZslpSc2mhkqEPIKTZQqbHUkWwe0WIYQ8ATEjGYuIA07/R38SfAool6S19TYRbV0FMw0eUr53QMOM6zajGVUZJKiA9D5T2Qt9oKe6XZAep0mhO14P8GYiCmBf5cZQUPkd0Obx/uFQq9KIJU75ambdjOBDCYpHeBoHpTNmY4= X-MS-TrafficTypeDiagnostic: SN6PR07MB4381: X-Microsoft-Exchange-Diagnostics: 1;SN6PR07MB4381;20:FmNSLQeVyO8cZrGiRpwa9ZG8ZmFUkjlnSN8jvifdN39pLJh7nkgPXZ6/74DeIfZrM3/n6s7rbog+e3zJUroxWPW9z3xIMTghgBlE/l3cOItxcjz3iOO6V7z86eKcGHT/zpN/kaSfnZCusKHMhHmoyusuHLhL0iEXBHFR5knk1twpmofPcM+ONBubDbnVfag+B6B1rWt+dCR3MAiUCYCJcCysX0D212PuVuYtjSOLLvmgKyTGfRyaMX5/k4vG5BnUgWm6BGyx8Xzv90z/dqwLrSFW4y4mFl+Kp+gF9G2t25IA5KNlaMzzkmypI5gomw5kD7gIFV4q+btUv/qh+6VTPp/B1667u0L2oVH1HA8n6cXrpbcDw2v+mLLlWJZebp0dy7p4nXhtrzJt7GjfS0s+nTd/KOB9LTnEEq1mIdZUkK4BC+/TmMUHAcpxkwUc8GQuwvhG0ee+Qn4jGbH5Zb4BxLwtAD2Mi6Y61sPVG9vMBPzOtqEW5vBjrbOtrZYcatueqCUqLUT6/0UGJIiwTCRUTrpJILZv4PfgSH01X3s7EySmlsacUpFLgAJFiJpjN3JpbmqUawhJhvnoBjHh3mUa78EW73ou5wfcITbzffwVMxg=;4:qrpVwTXCve/VEumlXzM45qe7joXQlpS3vp4s4sfl4PLMhtQ2EIK4slrxZ0nvOdMqoycA950IORQVQLboBb0VQV1oijklOCXHwAExZDvqhlrojJItG1+HUmsdzd6bY+NNxjGOzaC9GpoWyOKBIkuw2UCMH0aJCWhu/SaqcTuGA+5IQjspLYkrk3eZhCE2pJLBOZQ/awfSoo84eyzZVMSKpeXVME2uXGOhcCZG7Y8i/7s8XwuwoZxQSSfdBX4QGvRk69Bi2jl0qtdfr+dXTWT8SQ== X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(8121501046)(5005006)(3002001)(93006095)(3231254)(944501410)(52105095)(10201501046)(149027)(150027)(6041310)(20161123560045)(20161123558120)(20161123564045)(20161123562045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(6072148)(201708071742011);SRVR:SN6PR07MB4381;BCL:0;PCL:0;RULEID:;SRVR:SN6PR07MB4381; X-Forefront-PRVS: 0674DC6DD3 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(6069001)(39860400002)(376002)(396003)(39380400002)(346002)(366004)(199004)(189003)(386003)(478600001)(5660300001)(16586007)(6666003)(36756003)(2906002)(54906003)(316002)(110136005)(68736007)(97736004)(51416003)(76176011)(72206003)(6496006)(52116002)(3846002)(7416002)(7406005)(53936002)(59450400001)(1076002)(16526019)(26005)(186003)(6116002)(486006)(66066001)(47776003)(6486002)(7736002)(305945005)(42882007)(446003)(476003)(956004)(2616005)(76506005)(25786009)(50466002)(106356001)(4326008)(81156014)(39060400002)(50226002)(105586002)(8936002)(11346002)(48376002)(81166006)(8676002);DIR:OUT;SFP:1101;SCL:1;SRVR:SN6PR07MB4381;H:localhost;FPR:;SPF:None;LANG:en;PTR:InfoNoRecords;A:1;MX:1; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;SN6PR07MB4381;23:lCurgLHPz8WPQKi6aOmN/9oz81qrUDf+89Po1bgkC?= =?us-ascii?Q?P7l6JgdM9wjgAMEVbm6kcVFYEbD/2r9YIUVDNcRaONZ8HbGG+GxjH7BnQlFM?= =?us-ascii?Q?SN1ky/P73hllNcYsvGkPcZtCd6RMzAeJXoW2HS2iDYwtgnLh0EbVMCrsqI5G?= =?us-ascii?Q?pLFI8buZBtanx7aIAnyvH9THj4bPz3pe2K1XPAyO8Bac1ih8IgUNpuADV1gl?= =?us-ascii?Q?npLJtbONQvQPXK//k1XOVAZVEYxvKESRgp7M5n5DsiG2kouzEAwd7M55lr5j?= =?us-ascii?Q?OUSQRchzwjN72ztgrjXJ8C8evi393pBxzXFiD27pbonVMyhhWcZe4MRr/Op4?= =?us-ascii?Q?4IuDc6yZVdrlDkKPoPb04RvWm0s0CesBWeUk6UEVjbT2ehdZOfSe2gVzIDuG?= =?us-ascii?Q?avNYiTiEu9qAHNdAG4noFPkMlDRLmZ75MpdAMKXcBLnK2936Z3Ok865aIpy0?= =?us-ascii?Q?A3ZwXixbgrBkTJl7rnhnYP60YCYbxNb6RI7/TcAcD89hI4tZw1PfMjxLiuHv?= =?us-ascii?Q?RTerPXmrthvNHOSJ7bh5uHj2+SmdV6XAGyS4Y027xyFtDRk65I5RfAjnmSMJ?= =?us-ascii?Q?LV6zkpqa/sT+zmqR2E1+fxZUoNy89MhgS1GR11Wroc/bXIIGX6mno4xMY+VW?= =?us-ascii?Q?45A80OUXSHLgjhgrKLqHN70gUDhncBP0tLna/H0R1GoitgG6PEiWrjZ8QrGZ?= =?us-ascii?Q?JvEpzfbrlYWBbfMxLMIhPRec/eK1Kl5NVgqmhebNh7RnTcWT2hhe6vZF7GpP?= =?us-ascii?Q?I1Aj1vTjBkc2KZ89WAgvYKy6ZXtDtBsLaZdxvfO6ABGla8XttciIzn8NrveM?= =?us-ascii?Q?30kKFGlqvRhNg3zB81s6XyXguTN/PQUtHHZTNr2yjEB9Msb15vmLWmJHpdUJ?= =?us-ascii?Q?Uhx+2+erqWOT47TU/qzoFLVqFcgFthHNiweZH8vaMPVuYJZ0kJGFL9kuLOlU?= =?us-ascii?Q?vpsI1xCpWxKzBfkWQkf4LmnGh9gpUQzjhSz8BfxUys7VwUQHv9TohCE56/KM?= =?us-ascii?Q?F4vL5gkeS9g2mNHRpERATfy0zND1pO5hMal7FeqkcjT4Cvj3aYv0FBu+qCRD?= =?us-ascii?Q?jFFpM3qU7+1AlW5Coc0fyk4pusMRIgIlqAkvlHzXHsJr0iRVGHPL0vzZru60?= =?us-ascii?Q?AKhdvUWDon3lRKlB7gQmbwnP2Y4SDUy5ZWnMYPbtdiBZTW0hPzp01xCLS37q?= =?us-ascii?Q?oDtkIVYkkGk+Gpj25qO8pj+kzTrnt9vl6EHXUbV66n7nVBfDMcI9iCW2twJJ?= =?us-ascii?Q?dZ0GjjePk0KQtQl4jk9NbNfSN8WjC9MAX8nkNGU0hPHMMA6obya2qm4WRPgS?= =?us-ascii?Q?HvncKkNvSqNrO08YlHiwRS9OFoT/GxjWNYO4Ji+EuZzIblDCp9EhPm4B9zOY?= =?us-ascii?Q?+p+cQ=3D=3D?= X-Microsoft-Antispam-Message-Info: oOojlP17Q1Sicj442UMzmU114MPQkLJJt1w4DqmAI/1Q1TPsRAIWVfxv2/XF/3vt+CJ7ObsXBX4JoUa/ElCyx5X2DgiDvITV6wbxdYHKUZGgx4G8is120uyTuGfkpNwLIGCsu+7KMWDaHIqCDZHoICU8J6bzeDIalO31UU833npHZMzYS2WUi3LjMxWfxfbD X-Microsoft-Exchange-Diagnostics: 1;SN6PR07MB4381;6:qQGZQa7EsMM9l4uaLrKb2B+qitCbq09M27kRbP2S0zywH/hohti9vYOt+hsC2mwpKSLACurTQxkA/B21/9Z/M9Oys9GkvJsDuozbYQhitXKDpd5qZ2SDGJeCf9ZLQ50SnEIzeNToA0gMR3z3DV8izz5PxXm0te4Ln0uYX/HTIZgOtsEab0cEBGQOpr0qgBg/fSwYdpBlV5AuXn4c9aBYi08LyJ/l1CK5kUM8qZLN3jP/glOeOfqJ0r7REb2Mg1yjbnr8rqYlWYvwaFovNa1wMUZnhTI+fx/E1j4OjRubrKMxa184o5RAFE0VD3h6cSHHP8Masxot9kSD2buCiCPrAwLhxd+5+wyP+SmidhvYp0uxRCtG5ozil9nZpDm/bv3H9jC64nXSY2ECPHiaOFFkETamVzrFkxF2svyn0krh4votb3cd7VBhXo+zLbKVJ/IhW7wWgCDsOrGA5UKD66gImw==;5:Xga3SyukxhnCf3RWVoQUZKYa62FGXkJVsbXXcLbXeadB0qnVKV0oUotj7wClEtz/YnFZrOGXEUwBYbj3/U+bfnwRlcoHZY0gpMHoSeq/qBpe3iVClPKCdvwrJ3wU6qmRb963RD1IpxS/mE4XPYnjSbcALXcrIInlptC6/Nr0Xe0=;24:DY1niTohacreNqDjV1Hw3JE+E3Q5ek2ZMNpcvcPCkKJ530+iSKNFILZL3+50K/rK/XKqH/3ovGUhY/7PY2uHGDWqTJCigzmdsAUX9A5nQsA= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;SN6PR07MB4381;7:UBWdEj4UOjyHbTslzgLLclidMcaj84Lo0A20bhBuRRGXzRTebL7hb4MW2pypRYOgxMGKh6qbWbMpds7SrwHV/EylcAMkQxCDfR3Gi/ZI9juJXUmxcG11hyWbK+e/jjqGSmTkfNu5uQOAgoeYciKJSAMYaAklFvM+8hmqppXRl/vghtAE4k1YyM2SpGMg5uib2yqJgG/9M2VJ5LDYwsKHn2HWWF2mXfPjE6qmLNEu3RbsWRmA8fpe0Vm9Tc6rGZrU X-MS-Office365-Filtering-Correlation-Id: 0515d64b-33c3-4627-800c-08d5bb063206 X-OriginatorOrg: caviumnetworks.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 16 May 2018 08:22:41.9402 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 0515d64b-33c3-4627-800c-08d5bb063206 X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 711e4ccf-2e9b-4bcf-a551-4094005b6194 X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN6PR07MB4381 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Following patches of the series introduce ILP32-specific structures and handlers for signal subsystem. In this patch, functions and structures that common for LP64 and ILP32 are moved to arch/arm64/include/asm/signal_common.h to let ILP32 code reuse them. Some functions work with struct rt_sigframe which differs for ILP32. Therefore, to let ILP32 generate correct code, body of that functions are moved to arch/arm64/include/asm/signal_common.h. Others just declared in new header. Signed-off-by: Yury Norov --- arch/arm64/include/asm/signal_common.h | 306 ++++++++++++++++++++++ arch/arm64/kernel/signal.c | 336 ++++--------------------- 2 files changed, 359 insertions(+), 283 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 000000000000..84abe973e8b3 --- /dev/null +++ b/arch/arm64/include/asm/signal_common.h @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ + +/* + * Copyright (C) 1995-2009 Russell King + * Copyright (C) 2012 ARM Ltd. + * Copyright (C) 2018 Cavium Networks. + */ + +#ifndef __ASM_SIGNAL_COMMON_H +#define __ASM_SIGNAL_COMMON_H + +#include +#include + +#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) +#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) +#define SIGCONTEXT_RESERVED_SIZE sizeof(((struct sigcontext *)0)->__reserved) +#define RT_SIGFRAME_RESERVED_OFFSET \ + offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved) + +/* + * Sanity limit on the approximate maximum size of signal frame we'll + * try to generate. Stack alignment padding and the frame record are + * not taken into account. This limit is not a guarantee and is + * NOT ABI. + */ +#define SIGFRAME_MAXSZ SZ_64K + +struct rt_sigframe_user_layout { + void __user *sigframe; + struct frame_record __user *next_frame; + + unsigned long size; /* size of allocated sigframe data */ + unsigned long limit; /* largest allowed size */ + + unsigned long fpsimd_offset; + unsigned long esr_offset; + unsigned long sve_offset; + unsigned long extra_offset; + unsigned long end_offset; +}; + +struct user_ctxs { + struct fpsimd_context __user *fpsimd; + struct sve_context __user *sve; +}; + +struct frame_record { + u64 fp; + u64 lr; +}; + +void __user *apply_user_offset(struct rt_sigframe_user_layout const *user, + unsigned long offset); + +int setup_sigframe_layout(struct rt_sigframe_user_layout *user); +int setup_extra_context(char __user *sfp, unsigned long sf_size, + char __user *exprap); +int __parse_user_sigcontext(struct user_ctxs *user, + struct sigcontext __user const *sc, + void __user const *sigframe_base); +#define parse_user_sigcontext(user, sf) \ + __parse_user_sigcontext(user, &(sf)->uc.uc_mcontext, sf) + +int preserve_fpsimd_context(struct fpsimd_context __user *ctx); +int restore_fpsimd_context(struct fpsimd_context __user *ctx); + +#ifdef CONFIG_ARM64_SVE +int preserve_sve_context(struct sve_context __user *ctx); +int restore_sve_fpsimd_context(struct user_ctxs *user); +#else /* ! CONFIG_ARM64_SVE */ + +/* Turn any non-optimised out attempts to use these into a link error: */ +extern int preserve_sve_context(void __user *ctx); +extern int restore_sve_fpsimd_context(struct user_ctxs *user); + +#endif /* ! CONFIG_ARM64_SVE */ + +int sigframe_alloc(struct rt_sigframe_user_layout *user, + unsigned long *offset, size_t size); +int sigframe_alloc_end(struct rt_sigframe_user_layout *user); + +void __setup_return(struct pt_regs *regs, struct k_sigaction *ka, + struct rt_sigframe_user_layout *user, int usig); + +static void init_user_layout(struct rt_sigframe_user_layout *user) +{ + memset(user, 0, sizeof(*user)); + user->size = RT_SIGFRAME_RESERVED_OFFSET; + + user->limit = user->size + SIGCONTEXT_RESERVED_SIZE; + + user->limit -= TERMINATOR_SIZE; + user->limit -= EXTRA_CONTEXT_SIZE; + /* Reserve space for extension and terminator ^ */ +} + +static size_t sigframe_size(struct rt_sigframe_user_layout const *user) +{ + return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); +} + +static int get_sigframe(struct rt_sigframe_user_layout *user, + struct ksignal *ksig, struct pt_regs *regs) +{ + unsigned long sp, sp_top; + int err; + + init_user_layout(user); + err = setup_sigframe_layout(user); + if (err) + return err; + + sp = sp_top = sigsp(regs->sp, ksig); + + sp = round_down(sp - sizeof(struct frame_record), 16); + user->next_frame = (struct frame_record __user *)sp; + + sp = round_down(sp, 16) - sigframe_size(user); + user->sigframe = (void __user *)sp; + + /* + * Check that we can actually write to the signal frame. + */ + if (!access_ok(VERIFY_WRITE, user->sigframe, sp_top - sp)) + return -EFAULT; + + return 0; +} + +static int restore_sigframe(struct pt_regs *regs, + struct rt_sigframe __user *sf) +{ + sigset_t set; + int i, err; + struct user_ctxs user; + + err = get_sigset(&set, &sf->uc.uc_sigmask); + if (err == 0) + set_current_blocked(&set); + + for (i = 0; i < 31; i++) + __get_user_error(regs->regs[i], &sf->uc.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); + + /* + * Avoid sys_rt_sigreturn() restarting. + */ + forget_syscall(regs); + + err |= !valid_user_regs(®s->user_regs, current); + if (err == 0) + err = parse_user_sigcontext(&user, sf); + + if (err == 0) { + if (!user.fpsimd) + return -EINVAL; + + if (user.sve) { + if (!system_supports_sve()) + return -EINVAL; + + err = restore_sve_fpsimd_context(&user); + } else { + err = restore_fpsimd_context(user.fpsimd); + } + } + + return err; +} + +static int setup_sigframe(struct rt_sigframe_user_layout *user, + struct pt_regs *regs, sigset_t *set) +{ + int i, err = 0; + struct rt_sigframe __user *sf = user->sigframe; + + /* set up the stack frame for unwinding */ + __put_user_error(regs->regs[29], &user->next_frame->fp, err); + __put_user_error(regs->regs[30], &user->next_frame->lr, err); + + for (i = 0; i < 31; i++) + __put_user_error(regs->regs[i], &sf->uc.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); + + err |= put_sigset(set, &sf->uc.uc_sigmask); + + if (err == 0) { + struct fpsimd_context __user *fpsimd_ctx = + apply_user_offset(user, user->fpsimd_offset); + err |= preserve_fpsimd_context(fpsimd_ctx); + } + + /* fault information, if valid */ + if (err == 0 && user->esr_offset) { + struct esr_context __user *esr_ctx = + apply_user_offset(user, user->esr_offset); + + __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); + __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); + __put_user_error(current->thread.fault_code, + &esr_ctx->esr, err); + } + + /* Scalable Vector Extension state, if present */ + if (system_supports_sve() && err == 0 && user->sve_offset) { + struct sve_context __user *sve_ctx = + apply_user_offset(user, user->sve_offset); + err |= preserve_sve_context(sve_ctx); + } + + if (err == 0 && user->extra_offset) + setup_extra_context((char __user *)user->sigframe, user->size, + (char __user *)apply_user_offset(user, + user->extra_offset)); + + /* set the "end" magic */ + if (err == 0) { + struct _aarch64_ctx __user *end = + apply_user_offset(user, user->end_offset); + + __put_user_error(0, &end->magic, err); + __put_user_error(0, &end->size, err); + } + + return err; +} + +static long __sys_rt_sigreturn(struct pt_regs *regs) +{ + struct 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 (regs->sp & 15) + goto badframe; + + frame = (struct rt_sigframe __user *)regs->sp; + + if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + + if (restore_sigframe(regs, frame)) + goto badframe; + + if (restore_altstack(&frame->uc.uc_stack)) + goto badframe; + + return regs->regs[0]; + +badframe: + if (show_unhandled_signals) + pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", + current->comm, task_pid_nr(current), __func__, + regs->pc, regs->sp); + force_sig(SIGSEGV, current); + return 0; +} + +static int __setup_rt_frame(int usig, struct ksignal *ksig, + sigset_t *set, struct pt_regs *regs) +{ + struct rt_sigframe_user_layout user; + struct rt_sigframe __user *frame; + int err = 0; + + fpsimd_signal_preserve_current_state(); + + if (get_sigframe(&user, ksig, regs)) + return 1; + + frame = user.sigframe; + + __put_user_error(0, &frame->uc.uc_flags, err); + __put_user_error((typeof(frame->uc.uc_link)) 0, + &frame->uc.uc_link, err); + + err |= __save_altstack(&frame->uc.uc_stack, regs->sp); + err |= setup_sigframe(&user, regs, set); + if (err == 0) { + setup_return(regs, &ksig->ka, &user, 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; + } + } + + return err; +} + +#endif /* __ASM_SIGNAL_COMMON_H */ diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index 0a829f6f1832..c1a2523bac02 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -41,6 +41,10 @@ #include #include #include +#include + +#define get_sigset(s, m) __copy_from_user(s, m, sizeof(*s)) +#define put_sigset(s, m) __copy_to_user(m, s, sizeof(*s)) /* * Do a signal return; undo the signal stack. These are aligned to 128-bit. @@ -49,57 +53,12 @@ struct rt_sigframe { struct siginfo info; struct ucontext uc; }; +struct rt_sigframe_user_layout; -struct frame_record { - u64 fp; - u64 lr; -}; - -struct rt_sigframe_user_layout { - struct rt_sigframe __user *sigframe; - struct frame_record __user *next_frame; - - unsigned long size; /* size of allocated sigframe data */ - unsigned long limit; /* largest allowed size */ - - unsigned long fpsimd_offset; - unsigned long esr_offset; - unsigned long sve_offset; - unsigned long extra_offset; - unsigned long end_offset; -}; - -#define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) -#define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) -#define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) - -static void init_user_layout(struct rt_sigframe_user_layout *user) -{ - const size_t reserved_size = - sizeof(user->sigframe->uc.uc_mcontext.__reserved); - - memset(user, 0, sizeof(*user)); - user->size = offsetof(struct rt_sigframe, uc.uc_mcontext.__reserved); - - user->limit = user->size + reserved_size; - - user->limit -= TERMINATOR_SIZE; - user->limit -= EXTRA_CONTEXT_SIZE; - /* Reserve space for extension and terminator ^ */ -} - -static size_t sigframe_size(struct rt_sigframe_user_layout const *user) -{ - return round_up(max(user->size, sizeof(struct rt_sigframe)), 16); -} +static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, + struct rt_sigframe_user_layout *user, int usig); -/* - * Sanity limit on the approximate maximum size of signal frame we'll - * try to generate. Stack alignment padding and the frame record are - * not taken into account. This limit is not a guarantee and is - * NOT ABI. - */ -#define SIGFRAME_MAXSZ SZ_64K +#include static int __sigframe_alloc(struct rt_sigframe_user_layout *user, unsigned long *offset, size_t size, bool extend) @@ -144,14 +103,14 @@ static int __sigframe_alloc(struct rt_sigframe_user_layout *user, * signal frame. The offset from the signal frame base address to the * allocated block is assigned to *offset. */ -static int sigframe_alloc(struct rt_sigframe_user_layout *user, +int sigframe_alloc(struct rt_sigframe_user_layout *user, unsigned long *offset, size_t size) { return __sigframe_alloc(user, offset, size, true); } /* Allocate the null terminator record and prevent further allocations */ -static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) +int sigframe_alloc_end(struct rt_sigframe_user_layout *user) { int ret; @@ -168,7 +127,7 @@ static int sigframe_alloc_end(struct rt_sigframe_user_layout *user) return 0; } -static void __user *apply_user_offset( +void __user *apply_user_offset( struct rt_sigframe_user_layout const *user, unsigned long offset) { char __user *base = (char __user *)user->sigframe; @@ -176,7 +135,7 @@ static void __user *apply_user_offset( return base + offset; } -static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) +int preserve_fpsimd_context(struct fpsimd_context __user *ctx) { struct user_fpsimd_state const *fpsimd = ¤t->thread.fpsimd_state.user_fpsimd; @@ -194,7 +153,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 user_fpsimd_state fpsimd; __u32 magic, size; @@ -223,15 +182,9 @@ static int restore_fpsimd_context(struct fpsimd_context __user *ctx) return err ? -EFAULT : 0; } - -struct user_ctxs { - struct fpsimd_context __user *fpsimd; - struct sve_context __user *sve; -}; - #ifdef CONFIG_ARM64_SVE -static int preserve_sve_context(struct sve_context __user *ctx) +int preserve_sve_context(struct sve_context __user *ctx) { int err = 0; u16 reserved[ARRAY_SIZE(ctx->__reserved)]; @@ -263,7 +216,7 @@ static int preserve_sve_context(struct sve_context __user *ctx) return err ? -EFAULT : 0; } -static int restore_sve_fpsimd_context(struct user_ctxs *user) +int restore_sve_fpsimd_context(struct user_ctxs *user) { int err; unsigned int vq; @@ -326,15 +279,9 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) return err ? -EFAULT : 0; } -#else /* ! CONFIG_ARM64_SVE */ - -/* Turn any non-optimised out attempts to use these into a link error: */ -extern int preserve_sve_context(void __user *ctx); -extern int restore_sve_fpsimd_context(struct user_ctxs *user); - #endif /* ! CONFIG_ARM64_SVE */ -static int __parse_user_sigcontext(struct user_ctxs *user, +int __parse_user_sigcontext(struct user_ctxs *user, struct sigcontext __user const *sc, void __user const *sigframe_base) { @@ -492,91 +439,13 @@ static int __parse_user_sigcontext(struct user_ctxs *user, return -EINVAL; } -#define parse_user_sigcontext(user, sf) \ - __parse_user_sigcontext(user, &(sf)->uc.uc_mcontext, sf) - -static int restore_sigframe(struct pt_regs *regs, - struct rt_sigframe __user *sf) -{ - sigset_t set; - int i, err; - struct user_ctxs user; - - err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); - if (err == 0) - set_current_blocked(&set); - - for (i = 0; i < 31; i++) - __get_user_error(regs->regs[i], &sf->uc.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); - - /* - * Avoid sys_rt_sigreturn() restarting. - */ - forget_syscall(regs); - - err |= !valid_user_regs(®s->user_regs, current); - if (err == 0) - err = parse_user_sigcontext(&user, sf); - - if (err == 0) { - if (!user.fpsimd) - return -EINVAL; - - if (user.sve) { - if (!system_supports_sve()) - return -EINVAL; - - err = restore_sve_fpsimd_context(&user); - } else { - err = restore_fpsimd_context(user.fpsimd); - } - } - - return err; -} - asmlinkage long sys_rt_sigreturn(struct pt_regs *regs) { - struct 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 (regs->sp & 15) - goto badframe; - - frame = (struct rt_sigframe __user *)regs->sp; - - if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) - goto badframe; - - if (restore_sigframe(regs, frame)) - goto badframe; - - if (restore_altstack(&frame->uc.uc_stack)) - goto badframe; - - return regs->regs[0]; - -badframe: - if (show_unhandled_signals) - pr_info_ratelimited("%s[%d]: bad frame in %s: pc=%08llx sp=%08llx\n", - current->comm, task_pid_nr(current), __func__, - regs->pc, regs->sp); - force_sig(SIGSEGV, current); - return 0; + return __sys_rt_sigreturn(regs); } /* Determine the layout of optional records in the signal frame */ -static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) +int setup_sigframe_layout(struct rt_sigframe_user_layout *user) { int err; @@ -608,123 +477,50 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user) return sigframe_alloc_end(user); } - -static int setup_sigframe(struct rt_sigframe_user_layout *user, - struct pt_regs *regs, sigset_t *set) +int setup_extra_context(char __user *sfp, unsigned long sf_size, + char __user *extrap) { - int i, err = 0; - struct rt_sigframe __user *sf = user->sigframe; - - /* set up the stack frame for unwinding */ - __put_user_error(regs->regs[29], &user->next_frame->fp, err); - __put_user_error(regs->regs[30], &user->next_frame->lr, err); - - for (i = 0; i < 31; i++) - __put_user_error(regs->regs[i], &sf->uc.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); - - err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); - - if (err == 0) { - struct fpsimd_context __user *fpsimd_ctx = - apply_user_offset(user, user->fpsimd_offset); - err |= preserve_fpsimd_context(fpsimd_ctx); - } - - /* fault information, if valid */ - if (err == 0 && user->esr_offset) { - struct esr_context __user *esr_ctx = - apply_user_offset(user, user->esr_offset); - - __put_user_error(ESR_MAGIC, &esr_ctx->head.magic, err); - __put_user_error(sizeof(*esr_ctx), &esr_ctx->head.size, err); - __put_user_error(current->thread.fault_code, &esr_ctx->esr, err); - } - - /* Scalable Vector Extension state, if present */ - if (system_supports_sve() && err == 0 && user->sve_offset) { - struct sve_context __user *sve_ctx = - apply_user_offset(user, user->sve_offset); - err |= preserve_sve_context(sve_ctx); - } - - if (err == 0 && user->extra_offset) { - char __user *sfp = (char __user *)user->sigframe; - char __user *userp = - apply_user_offset(user, user->extra_offset); - - struct extra_context __user *extra; - struct _aarch64_ctx __user *end; - u64 extra_datap; - u32 extra_size; - - extra = (struct extra_context __user *)userp; - userp += EXTRA_CONTEXT_SIZE; - - end = (struct _aarch64_ctx __user *)userp; - userp += TERMINATOR_SIZE; + int err = 0; + struct extra_context __user *extra; + struct _aarch64_ctx __user *end; + u64 extra_datap; + u32 extra_size; - /* - * extra_datap is just written to the signal frame. - * The value gets cast back to a void __user * - * during sigreturn. - */ - extra_datap = (__force u64)userp; - extra_size = sfp + round_up(user->size, 16) - userp; + extra = (struct extra_context __user *)extrap; + extrap += EXTRA_CONTEXT_SIZE; - __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); - __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); - __put_user_error(extra_datap, &extra->datap, err); - __put_user_error(extra_size, &extra->size, err); + end = (struct _aarch64_ctx __user *)extrap; + extrap += TERMINATOR_SIZE; - /* Add the terminator */ - __put_user_error(0, &end->magic, err); - __put_user_error(0, &end->size, err); - } + /* + * extra_datap is just written to the signal frame. + * The value gets cast back to a void __user * + * during sigreturn. + */ + extra_datap = (__force u64)extrap; + extra_size = sfp + round_up(sf_size, 16) - extrap; - /* set the "end" magic */ - if (err == 0) { - struct _aarch64_ctx __user *end = - apply_user_offset(user, user->end_offset); + __put_user_error(EXTRA_MAGIC, &extra->head.magic, err); + __put_user_error(EXTRA_CONTEXT_SIZE, &extra->head.size, err); + __put_user_error(extra_datap, &extra->datap, err); + __put_user_error(extra_size, &extra->size, err); - __put_user_error(0, &end->magic, err); - __put_user_error(0, &end->size, err); - } + /* Add the terminator */ + __put_user_error(0, &end->magic, err); + __put_user_error(0, &end->size, err); return err; } -static int get_sigframe(struct rt_sigframe_user_layout *user, - struct ksignal *ksig, struct pt_regs *regs) +void __setup_return(struct pt_regs *regs, struct k_sigaction *ka, + struct rt_sigframe_user_layout *user, int usig) { - unsigned long sp, sp_top; - int err; - - init_user_layout(user); - err = setup_sigframe_layout(user); - if (err) - return err; - - sp = sp_top = sigsp(regs->sp, ksig); - - sp = round_down(sp - sizeof(struct frame_record), 16); - user->next_frame = (struct frame_record __user *)sp; - sp = round_down(sp, 16) - sigframe_size(user); - user->sigframe = (struct rt_sigframe __user *)sp; - - /* - * Check that we can actually write to the signal frame. - */ - if (!access_ok(VERIFY_WRITE, user->sigframe, sp_top - sp)) - return -EFAULT; + regs->regs[0] = usig; + regs->sp = (unsigned long)user->sigframe; + regs->regs[29] = (unsigned long)&user->next_frame->fp; + regs->pc = (unsigned long)ka->sa.sa_handler; - return 0; } static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, @@ -732,10 +528,7 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, { __sigrestore_t sigtramp; - regs->regs[0] = usig; - regs->sp = (unsigned long)user->sigframe; - regs->regs[29] = (unsigned long)&user->next_frame->fp; - regs->pc = (unsigned long)ka->sa.sa_handler; + __setup_return(regs, ka, user, usig); if (ka->sa.sa_flags & SA_RESTORER) sigtramp = ka->sa.sa_restorer; @@ -748,32 +541,7 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) { - struct rt_sigframe_user_layout user; - struct rt_sigframe __user *frame; - int err = 0; - - fpsimd_signal_preserve_current_state(); - - if (get_sigframe(&user, ksig, regs)) - return 1; - - frame = user.sigframe; - - __put_user_error(0, &frame->uc.uc_flags, err); - __put_user_error(NULL, &frame->uc.uc_link, err); - - err |= __save_altstack(&frame->uc.uc_stack, regs->sp); - err |= setup_sigframe(&user, regs, set); - if (err == 0) { - setup_return(regs, &ksig->ka, &user, 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; - } - } - - return err; + return __setup_rt_frame(usig, ksig, set, regs); } static void setup_restart_syscall(struct pt_regs *regs) @@ -802,6 +570,8 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs) ret = a32_setup_rt_frame(usig, ksig, oldset, regs); else ret = a32_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); } -- 2.17.0