Received: by 2002:a05:6359:6284:b0:131:369:b2a3 with SMTP id se4csp3528368rwb; Mon, 7 Aug 2023 15:22:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEsbTsdqGOCnxDLlh4eH6/WVa5IdNQ6R5LE1n/KmAM3lGrWbyfb6qHmKuRXZBTMFyptxYXE X-Received: by 2002:a17:906:8a6b:b0:993:d7c4:1a78 with SMTP id hy11-20020a1709068a6b00b00993d7c41a78mr9219912ejc.10.1691446931100; Mon, 07 Aug 2023 15:22:11 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1691446931; cv=none; d=google.com; s=arc-20160816; b=tc07hlsijpoUuo6Uca0vfbwlQw2As2I1wE3MMaelUBma9BMWzoiKitXa1ZUdxi9xtt ZxRDzhiKYMhQmwJKLYp/TTUb+CIDoVFQmSBJenPmeLptX2u/AWgpUzLhNsjxaH1slid3 U9pidNPOC514B8NLBR7wBBcJqon1T7yuSCJ9cNDIgSq6seK2cORHWa7knWXodBG+ZX1+ gbRr2Gv7IWGxyg/kskZbAtmDxrW479RQTY5C334l7WEnq5j3FqkxPmApBtjVeTvSyxlD viN3qB/I/72l95KYiuBgKgUBxQSIhpy/9GEAtwQXoREuEZIuv5/7znz454cp/71cvhxu gE6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:in-reply-to:references:message-id :content-transfer-encoding:mime-version:subject:date:from :dkim-signature; bh=GVW/Wb+UQgRbZFsiBWrQq9WDN9Jw1tFXrIhcblQEjIs=; fh=EdAFSmIgUzZTC6WCy4Jg1wBZ0/m6m2d/OjiRUJ3BsTI=; b=01MGT33xTc5g7BsSrfLZkszLLktKbGYDPsTdIeuND223HtUKn+MBS252fG3iO58sMW op5pxGvLT1Vd08n8KelG4KPY0s1Q1mcUMV5DPsyEFr4OmovNnhaTmyZBWIgAhoOSx3MG uBrIi5oYOOzcw/RrJcFlpGs1XioCYfjk9xxt2QY2il1wFg6wPPfI6nqVWJknlIDiB9C4 L8fHnCGJdmsMHPIkekaGwy1jW8ARbVIqGPVpjHa7JgawpPeSJs9Vg4rKv9IjVC7HpXSl 00xCgXsjGOxvBd2Dkj0rQt5H69YFTCk8fX53xQ+39MmMS5Ex9fGq5OyAWVjPrLeZtYEJ BZEA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ss774Umf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id w3-20020a1709067c8300b00992ee6da4b2si6661949ejo.683.2023.08.07.15.21.46; Mon, 07 Aug 2023 15:22:11 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=ss774Umf; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230517AbjHGWFA (ORCPT + 99 others); Mon, 7 Aug 2023 18:05:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41890 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229645AbjHGWEC (ORCPT ); Mon, 7 Aug 2023 18:04:02 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 281751FFA; Mon, 7 Aug 2023 15:03:13 -0700 (PDT) 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 70A05622AA; Mon, 7 Aug 2023 22:03:12 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id F21EFC433C8; Mon, 7 Aug 2023 22:03:04 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1691445791; bh=sSLA8c9zD81mYMEEIJgpRALMzE62vMXK9V14WuQWjaE=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ss774UmfREQ/zk8Pe5HgZ3JOA5vxrOqcV0K5BqOOF/3S2zRV+sMVmiJY0L/tzujxX R/euriyTbGd0Onu9fD4RpbmltMzhz5oG8hGNCFSLR5aDD7TS/0Y4a2XAFsWaLvDSDS GuqEeJkPcsTbZQ/f7clH9zlAcG4m50fArTE6C7/rcavgOh3d65XbfFvxoIoiiOrGwn /NNCUaflA7joAGATo3yCQM7G6I/gK0eQiv2f382qJztOl3LCrmvuIjpWUFP75skXkL TMjdyQtC4y14ptGn77lIlJbRFpkVozhz/P56xUwS91AOJLE0fcLk4SEUnGPoSCIe7E IZ8l210RHt7Jg== From: Mark Brown Date: Mon, 07 Aug 2023 23:00:21 +0100 Subject: [PATCH v4 16/36] arm64/traps: Handle GCS exceptions MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20230807-arm64-gcs-v4-16-68cfa37f9069@kernel.org> References: <20230807-arm64-gcs-v4-0-68cfa37f9069@kernel.org> In-Reply-To: <20230807-arm64-gcs-v4-0-68cfa37f9069@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-034f2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6026; i=broonie@kernel.org; h=from:subject:message-id; bh=sSLA8c9zD81mYMEEIJgpRALMzE62vMXK9V14WuQWjaE=; b=owEBbQGS/pANAwAKASTWi3JdVIfQAcsmYgBk0WmktK/PjNdqpqKADA4B0lzy9ao2R6anB+nWsRJR J63y1TqJATMEAAEKAB0WIQSt5miqZ1cYtZ/in+ok1otyXVSH0AUCZNFppAAKCRAk1otyXVSH0DXYB/ 9PlmYt2rLwTxyD9hhwtemGtFxKsapPrvPwvbnu4dR5x9CenYUw1BfmSXBDNtucurTotIcZux2j8AIN uIpbMJf6cXCsBxb9B3lTzNPm+6q3DlRzk2ZU/mc+HQ5Vecuc2z0hIPkSyC9gCmYHZOdTdj/VGe4+gY BfJQtm5HXYXc6//gdb97qdrGqJtHis3ro/6Z+Ks4mZVAKL/uIMR2IgmSpCYOqVGZw57ZIKbsJspdcX C0v7/+q7+mgZF2BSivj/uGyWjZWPpg8XXRAvlS+L7+2qb+9GkH3qhbAa2TW7D59PFVBQjB1idFHWj4 rWju22LOPHzd6W7UercRHb7G7MJH9z X-Developer-Key: i=broonie@kernel.org; a=openpgp; fpr=3F2568AAC26998F9E813A1C5C3F436CA30F5D8EB X-Spam-Status: No, score=-7.1 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 | 28 +++++++++++++++++++++++++++- arch/arm64/include/asm/exception.h | 2 ++ arch/arm64/kernel/entry-common.c | 23 +++++++++++++++++++++++ arch/arm64/kernel/traps.c | 11 +++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/arch/arm64/include/asm/esr.h b/arch/arm64/include/asm/esr.h index ae35939f395b..a87a8305051f 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,31 @@ #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 (10) +#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_Rvalue_SHIFT 5 +#define ESR_ELx_Rvalue_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)", -- 2.30.2