From patchwork Sun Jul 16 21:51:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mark Brown X-Patchwork-Id: 13314949 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7751AEB64DD for ; Sun, 16 Jul 2023 21:54:41 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 14A598D0003; Sun, 16 Jul 2023 17:54:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 0FAB58D0001; Sun, 16 Jul 2023 17:54:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EB6C28D0003; Sun, 16 Jul 2023 17:54:40 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id DA2808D0001 for ; Sun, 16 Jul 2023 17:54:40 -0400 (EDT) Received: from smtpin24.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay03.hostedemail.com (Postfix) with ESMTP id B9C44A027A for ; Sun, 16 Jul 2023 21:54:40 +0000 (UTC) X-FDA: 81018829920.24.EB2C6B3 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf03.hostedemail.com (Postfix) with ESMTP id 0402B2000A for ; Sun, 16 Jul 2023 21:54:38 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oLsGeLaX; spf=pass (imf03.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=none) header.from=kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1689544479; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=9MQtL/ArwNwDX/YLjygs6IywyThB7memAqPD3uhDop4=; b=B2tza/nRT15ioTwPDbT2oBKp6aCMJJ5+U0EU12mY3usJSzLYEIavxmiJgTSvmL5hQPnWqE oOLHalPDTo/8QRTB8Nh2rGtagVJi+hvvAKHvpXiXvnPDmZ3wW7uhWzTuln8iAQOl77vywk LKLgxvL1AqGuvSRLWnzyn4ZZ89K5G98= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1689544479; a=rsa-sha256; cv=none; b=wFKGhAQ1y/idMXNsdsGMmyN0qmIDoAlDVw2js6pIeqCr5siVnMENnCIFz3Wo6vkK4Y34HT SGBRP49Y0T8Of+gGTsSg7jAeyHIPaloVNsADwfAlqWGAJahjur8o8jNLu0xykh6S/hPlqa A6HC8I/t7nGfWzfK6LOAFAP1uIqU/uo= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=oLsGeLaX; spf=pass (imf03.hostedemail.com: domain of broonie@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=broonie@kernel.org; dmarc=pass (policy=none) header.from=kernel.org Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 43EE760EC4; Sun, 16 Jul 2023 21:54:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id EC4B4C433B7; Sun, 16 Jul 2023 21:54:31 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1689544477; bh=mWrkqBd1ZgdAaq7HlnR+KThCHQngel188UeYQ4P+8oo=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=oLsGeLaXn9rNUWq+QEOnVq1apik1w2+pWGG2yEtG6Qw4gJ30HUvNkahBZNucXuNrK 9oriVmqQBiX9JN/UGN8JWoEWRWJfyfAoMh0KhYzDnTokKKOkqH6S46GTa4252fTZ35 EqVaoaWxqQUvrza3FuAT5yAS6Z52O+2w7dZmH1dVRdMgGfJ2ZFwJ6ypb9HUwFuWQ31 pBDYdGjcDHamHKurMTtbhU4aa22cE2uEkTKLxXdi29QZEKQFoJ9gEM1c5o70ugoRJc jcQw+bhsxOTFmhqN4g51JOaYtH1MTPgTcFlPu8y+J48SAoIWQUrud4HSwOW+I8stE/ t2q/Npyg6smTQ== From: Mark Brown Date: Sun, 16 Jul 2023 22:51:13 +0100 Subject: [PATCH 17/35] arm64/traps: Handle GCS exceptions MIME-Version: 1.0 Message-Id: <20230716-arm64-gcs-v1-17-bf567f93bba6@kernel.org> References: <20230716-arm64-gcs-v1-0-bf567f93bba6@kernel.org> In-Reply-To: <20230716-arm64-gcs-v1-0-bf567f93bba6@kernel.org> To: Catalin Marinas , Will Deacon , Jonathan Corbet , Andrew Morton , Marc Zyngier , Oliver Upton , James Morse , Suzuki K Poulose , Arnd Bergmann , Oleg Nesterov , Eric Biederman , Kees Cook , Shuah Khan , "Rick P. Edgecombe" , Deepak Gupta , Ard Biesheuvel , Szabolcs Nagy Cc: "H.J. Lu" , Paul Walmsley , Palmer Dabbelt , Albert Ou , linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, kvmarm@lists.linux.dev, linux-fsdevel@vger.kernel.org, linux-arch@vger.kernel.org, linux-mm@kvack.org, linux-kselftest@vger.kernel.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, Mark Brown X-Mailer: b4 0.13-dev-099c9 X-Developer-Signature: v=1; a=openpgp-sha256; l=5938; i=broonie@kernel.org; h=from:subject:message-id; bh=mWrkqBd1ZgdAaq7HlnR+KThCHQngel188UeYQ4P+8oo=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBktGacNH7rwm/sgg2oUyKcu3FXhI9wferBx7OZxD+E Zl2t0v6JATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZLRmnAAKCRAk1otyXVSH0JbDB/ 0XEcEA/n7jpeN/DwBQPdDt2h2LFRvNJa7fuxLxIcR5oGh2yuD34aFj2tCFi4KLSSpwehv3blN02kFr 86QHafz3emOLMwDqivCev1MhVzfA3HRKaBItgRDs313MBio+xTZaBWclEOGt8sToEMSrW8KpqFnuDl nda3+ZsUhYUByk8XHt+8QOq61BIxDyXlOsKy1K8PdcAcQ1TQtyBqBS9iskVDETnsTDLFJE5EYNYt4M KylTT0qj8rerF9RhTE4iyWm7zSj280XYK8pFJGAocTesUMmwVd4Mza03sKTSNaQvf6PWOWYwaW8uxh v4QfjIVB0Zb18Wfeg746J4WGsR1gJg X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Rspamd-Queue-Id: 0402B2000A X-Rspam-User: X-Stat-Signature: mrrhpsigmsnj66mt1iafew4wws3ar9tt X-Rspamd-Server: rspam03 X-HE-Tag: 1689544478-746075 X-HE-Meta: U2FsdGVkX19GC56o4/3voAALFlCpx9IeFif0q+IAfcD+D9+6vwj9JwwUNfB0OX0iXM/R6pan3OWRusC8ywDWl1W3jmEPxRTBO+LuIqfZofY+fW3g4HlhxHnV4Z1TvTGLrEsd8p6wsBbwgpCMaPerJSipwqybGBCTa1GFspjCePS7Uru0Xf5/KF3Q5COCZCMRDdQoZWiZe2tiyv3sYWZ+TvjoQxgdx6v+nJOYP9V/X79NKz8I5dKgE/QJ0+129H5UXDDRjNzSuDf98kwfsUS62M/9jjU2/0c7BXNrPVxiEodC6M7d7ndn/oGVVQA2t+5B4XbfpT6dNIk3saITT9DmUrU1evgMhzgpLu3ZqePzv24+nCCUj+mHk8BooxO5tuym0KYVW52k7Y+k0VIprT17U4QXZQd+2wuAvk5CwlZbAQ/PbDt0saziBguukasYDpaMTDq5FJwm14GQymAMZc2Vk9CKF2m1COuSSAwkZGOYATVV/kW0I1xyG8wNKmIno9fhUFhxfCNv4+0opqge+5+M5Dkf0DPcUcNR+IR83IIwMaCgzozZZj/3VL08O73AJEymYZWqb5aVhVYtSKcXFJPBLjiN8P14Cg41GIDXHoxliw/Mc3Nqy3F+pOYqB29+KviNDjqT91WxNFMbViW/+fz7Q5qeIulgQwLmgptQDcUJ/AVG+uXDHs6v7v7ZqmKpRiYBlZ8dfTo3Sf4Lo8aueDfhvpF2araoD5/u/AD2IHxSHM/FaEct/X+JlSu3b+LdFVIOZ5ze1HbrMsCCmTycIZBRJoE12WHlVF71xVdNEaWlHJ92WSekXbMl6w7fbnMl213Kx853xyEbn+B103Q+kxv3lKV8wClELAQEyG9f8IPT/NJ44uPYrcBxEkB7mogm9W5+dZqI6KRo/4vCZTfZttZS30iae9HzqHr8Y0/6Q8XvP5Bvo0fPqnFOcCQvcKv5cY9eStWIrRIED7SZ9s6uxGF 61iQ1Jvm sS0LJ61jYMeycqA5oeaS0zTCtRIpVXe0eakS5N+X9UYBkn8IpfxaL4HqyoT3Pwt5VLyjJyl3T45C45UmQUU9lquE2jbfwKs0YP+WbArv136mYZQCN2EUxzsHI5lOQ6LODzhKLPRHZwFwBYw5BiM3hmD6yagH3gq4yIM0kpPajvr9RIVTAGtjOwB0jv/t16sUWbccC4tnsTEauT1H/9G7hJPZoUyxvs4GhE+uzhSUCgQMC5SO0PjvfoKR/d1X4Um8yhPUH1Oj8tamDF3cLNtvIwlbt2OSBLvlmO2GjJboqp7miITA10FWAVWGmDtI2eLZ9sheaqxMwv7UmtjeBSDrT14vHNaZz6QJAGrS//QwgS7bF5NJNlsrxw1QURcZWznKY0BA49zag/8oVDhQLpsyD4SGly7y1X6JzF46eY3XCMyERQ6M= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: A new exception code is defined for GCS specific faults other than standard load/store faults, for example GCS token validation failures, add handling for this. These faults are reported to userspace as segfaults with code SEGV_CPERR (protection error), mirroring the reporting for x86 shadow stack errors. GCS faults due to memory load/store operations generate data aborts with a flag set, these will be handled separately as part of the data abort handling. Since we do not currently enable GCS for EL1 we should not get any faults there but while we're at it we wire things up there, treating any GCS fault as fatal. Signed-off-by: Mark Brown --- arch/arm64/include/asm/esr.h | 26 +++++++++++++++++++++++++- arch/arm64/include/asm/exception.h | 2 ++ arch/arm64/kernel/entry-common.c | 23 +++++++++++++++++++++++ arch/arm64/kernel/traps.c | 11 +++++++++++ 4 files changed, 61 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index ae35939f395b..c5a72172fcf1 100644 --- a/arch/arm64/include/asm/esr.h +++ b/arch/arm64/include/asm/esr.h @@ -51,7 +51,8 @@ #define ESR_ELx_EC_FP_EXC32 (0x28) /* Unallocated EC: 0x29 - 0x2B */ #define ESR_ELx_EC_FP_EXC64 (0x2C) -/* Unallocated EC: 0x2D - 0x2E */ +#define ESR_ELx_EC_GCS (0x2D) +/* Unallocated EC: 0x2E */ #define ESR_ELx_EC_SERROR (0x2F) #define ESR_ELx_EC_BREAKPT_LOW (0x30) #define ESR_ELx_EC_BREAKPT_CUR (0x31) @@ -382,6 +383,29 @@ #define ESR_ELx_MOPS_ISS_SRCREG(esr) (((esr) & (UL(0x1f) << 5)) >> 5) #define ESR_ELx_MOPS_ISS_SIZEREG(esr) (((esr) & (UL(0x1f) << 0)) >> 0) +/* ISS field definitions for GCS */ +#define ESR_ELx_ExType_SHIFT (20) +#define ESR_ELx_ExType_MASK GENMASK(23, 20) +#define ESR_ELx_Raddr_SHIFT (14) +#define ESR_ELx_Raddr_MASK GENMASK(14, 10) +#define ESR_ELx_Rn_SHIFT (5) +#define ESR_ELx_Rn_MASK GENMASK(9, 5) +#define ESR_ELx_IT_SHIFT (0) +#define ESR_ELx_IT_MASK GENMASK(4, 0) + +#define ESR_ELx_ExType_DATA_CHECK 0 +#define ESR_ELx_ExType_EXLOCK 1 +#define ESR_ELx_ExType_STR 2 + +#define ESR_ELx_IT_RET 0 +#define ESR_ELx_IT_GCSPOPM 1 +#define ESR_ELx_IT_RET_KEYA 2 +#define ESR_ELx_IT_RET_KEYB 3 +#define ESR_ELx_IT_GCSSS1 4 +#define ESR_ELx_IT_GCSSS2 5 +#define ESR_ELx_IT_GCSPOPCX 6 +#define ESR_ELx_IT_GCSPOPX 7 + #ifndef __ASSEMBLY__ #include diff --git a/arch/arm64/include/asm/exception.h b/arch/arm64/include/asm/exception.h index ad688e157c9b..99caff458e20 100644 --- a/arch/arm64/include/asm/exception.h +++ b/arch/arm64/include/asm/exception.h @@ -57,6 +57,8 @@ void do_el0_undef(struct pt_regs *regs, unsigned long esr); void do_el1_undef(struct pt_regs *regs, unsigned long esr); void do_el0_bti(struct pt_regs *regs); void do_el1_bti(struct pt_regs *regs, unsigned long esr); +void do_el0_gcs(struct pt_regs *regs, unsigned long esr); +void do_el1_gcs(struct pt_regs *regs, unsigned long esr); void do_debug_exception(unsigned long addr_if_watchpoint, unsigned long esr, struct pt_regs *regs); void do_fpsimd_acc(unsigned long esr, struct pt_regs *regs); diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 6b2e0c367702..4d86216962e5 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -400,6 +400,15 @@ static void noinstr el1_bti(struct pt_regs *regs, unsigned long esr) exit_to_kernel_mode(regs); } +static void noinstr el1_gcs(struct pt_regs *regs, unsigned long esr) +{ + enter_from_kernel_mode(regs); + local_daif_inherit(regs); + do_el1_gcs(regs, esr); + local_daif_mask(); + exit_to_kernel_mode(regs); +} + static void noinstr el1_dbg(struct pt_regs *regs, unsigned long esr) { unsigned long far = read_sysreg(far_el1); @@ -442,6 +451,9 @@ asmlinkage void noinstr el1h_64_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_BTI: el1_bti(regs, esr); break; + case ESR_ELx_EC_GCS: + el1_gcs(regs, esr); + break; case ESR_ELx_EC_BREAKPT_CUR: case ESR_ELx_EC_SOFTSTP_CUR: case ESR_ELx_EC_WATCHPT_CUR: @@ -621,6 +633,14 @@ static void noinstr el0_mops(struct pt_regs *regs, unsigned long esr) exit_to_user_mode(regs); } +static void noinstr el0_gcs(struct pt_regs *regs, unsigned long esr) +{ + enter_from_user_mode(regs); + local_daif_restore(DAIF_PROCCTX); + do_el0_gcs(regs, esr); + exit_to_user_mode(regs); +} + static void noinstr el0_inv(struct pt_regs *regs, unsigned long esr) { enter_from_user_mode(regs); @@ -701,6 +721,9 @@ asmlinkage void noinstr el0t_64_sync_handler(struct pt_regs *regs) case ESR_ELx_EC_MOPS: el0_mops(regs, esr); break; + case ESR_ELx_EC_GCS: + el0_gcs(regs, esr); + break; case ESR_ELx_EC_BREAKPT_LOW: case ESR_ELx_EC_SOFTSTP_LOW: case ESR_ELx_EC_WATCHPT_LOW: diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 8b70759cdbb9..65dab959f620 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -500,6 +500,16 @@ void do_el1_bti(struct pt_regs *regs, unsigned long esr) die("Oops - BTI", regs, esr); } +void do_el0_gcs(struct pt_regs *regs, unsigned long esr) +{ + force_signal_inject(SIGSEGV, SEGV_CPERR, regs->pc, 0); +} + +void do_el1_gcs(struct pt_regs *regs, unsigned long esr) +{ + die("Oops - GCS", regs, esr); +} + void do_el0_fpac(struct pt_regs *regs, unsigned long esr) { force_signal_inject(SIGILL, ILL_ILLOPN, regs->pc, esr); @@ -884,6 +894,7 @@ static const char *esr_class_str[] = { [ESR_ELx_EC_MOPS] = "MOPS", [ESR_ELx_EC_FP_EXC32] = "FP (AArch32)", [ESR_ELx_EC_FP_EXC64] = "FP (AArch64)", + [ESR_ELx_EC_GCS] = "Guarded Control Stack", [ESR_ELx_EC_SERROR] = "SError", [ESR_ELx_EC_BREAKPT_LOW] = "Breakpoint (lower EL)", [ESR_ELx_EC_BREAKPT_CUR] = "Breakpoint (current EL)",