From patchwork Thu Aug 2 20:49:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tyler Baicar X-Patchwork-Id: 10554245 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D535C13B4 for ; Thu, 2 Aug 2018 20:50:20 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id C10F92C4A5 for ; Thu, 2 Aug 2018 20:50:20 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id BEAAE2BDFA; Thu, 2 Aug 2018 20:50:20 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id F18A92C49A for ; Thu, 2 Aug 2018 20:50:19 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:Message-Id:Date: Subject:To:From:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To: References:List-Owner; bh=/wkwR7QE8Mj7W4EEgjhjtAEWRvWYaKGyjiE9ju8Yj1E=; b=inc A1Mf1GiKE3l933fNwXb3V5i7CdUjsp8oltnlYpuLUbnMm+vJhSu9CF3yYwVQZDbmJ/tLiYNM7XRNr YhwfIvCjgTTnTpTb7Hu/zm0xyeYZYQXoYnvum+ONJb73tFuUw2xWCMM98BSqxUiV42PvOLl2VXatZ ILImxWQLNhM+beHTsjAdt4IpXoyOm/CGL4LnbniSFEHBCXZXV/KPFH0cW9hOchhXdDOOYklY5hvoW ByWFe4JoTzoszpqjJnjD8tfPYFz/sg6pVHKvbL3iefJWJam1hzDuGFRk56ppOhri7K/JiiXn5fItc A7BdGhl+VLPQpOrTBtrKZtmlNvKGL7A==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1flKY4-0006WY-LS; Thu, 02 Aug 2018 20:50:16 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1flKY0-0005PZ-Ve for linux-arm-kernel@lists.infradead.org; Thu, 02 Aug 2018 20:50:14 +0000 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id F0C976079C; Thu, 2 Aug 2018 20:50:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533243002; bh=jysoMLmh5VudQMHAvYOXpRqvAqQykaw338Qgfmj3J9Y=; h=From:To:Cc:Subject:Date:From; b=b51rjwJ88cnbr4vi62pi/9nkV96zXnc115KjUjKlXOmqkB+/XX5wtSq63KYfB1FtN AvwmH5YIgFzOi33+nuEms+8IpOxYC5VAPVlwhyMSIo4Gbai6nlnxy7cLm3OLI9gQLG MMvp6sJElucJXu3qg2MeM4x9qDOUEZrKtGH9FVzM= Received: from thunderhorn.qualcomm.com (global_nat1_iad_fw.qualcomm.com [129.46.232.65]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: tbaicar@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id C7F2B6063A; Thu, 2 Aug 2018 20:50:00 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1533243001; bh=jysoMLmh5VudQMHAvYOXpRqvAqQykaw338Qgfmj3J9Y=; h=From:To:Cc:Subject:Date:From; b=CyZY/gvPgcCv3EVpJ6SO/BcOLRaoDt3xzkuxUOocgzXJHbe9ximhlqUPF/gHadPLA c+XxqHyaSO/JGoGzzV9g3FqSGSqHGehmXjnOHTSxDLS71YuwfVRgAdUGHgbFPZG26m x9EcMkDNtmG+xoKEwy4itLvgbky6vtt1ghs3jygc= DMARC-Filter: OpenDMARC Filter v1.3.2 smtp.codeaurora.org C7F2B6063A Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none (p=none dis=none) header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=none smtp.mailfrom=tbaicar@codeaurora.org From: Tyler Baicar To: linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org Subject: [RFC PATCH] edac: armv8_edac: Add ARMv8 EDAC driver Date: Thu, 2 Aug 2018 16:49:50 -0400 Message-Id: <1533242990-12828-1-git-send-email-tbaicar@codeaurora.org> X-Mailer: git-send-email 1.9.1 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20180802_135013_060580_88957268 X-CRM114-Status: GOOD ( 21.29 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Tyler Baicar MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Add ARMv8 EDAC driver to detect and report errors that are reported through the ARMv8.2 RAS extensions. This is by no means complete hence the RFC. At minimum, this should also have support to check the SRs of each CPU during boot time to check for anything pending. Also, the SEI code flow could be improved to separate the check for uncontained errors and panic ASAP before doing any of this reporting. This is also limited to SR based RAS extension nodes. There is not currently a way to detect memory mapped RAS extension nodes. The initialization which prints the FR registers only does so for a single CPU, so the assumption is that all CPUs are identical from a RAS extension node perspective. Signed-off-by: Tyler Baicar --- arch/arm64/include/asm/ras.h | 26 +++++++++++++++++++ arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/ras.c | 54 ++++++++++++++++++++++++++++++++++++++++ arch/arm64/kernel/traps.c | 4 +++ arch/arm64/mm/fault.c | 4 +++ drivers/edac/Kconfig | 9 +++++++ drivers/edac/Makefile | 2 ++ drivers/edac/armv8_edac.c | 59 ++++++++++++++++++++++++++++++++++++++++++++ include/linux/armv8_edac.h | 20 +++++++++++++++ 9 files changed, 179 insertions(+) create mode 100644 arch/arm64/include/asm/ras.h create mode 100644 arch/arm64/kernel/ras.c create mode 100644 drivers/edac/armv8_edac.c create mode 100644 include/linux/armv8_edac.h diff --git a/arch/arm64/include/asm/ras.h b/arch/arm64/include/asm/ras.h new file mode 100644 index 0000000..29b30e8 --- /dev/null +++ b/arch/arm64/include/asm/ras.h @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#ifndef ARM64_RAS_H +#define ARM64_RAS_H + +bool arch_cpu_has_ras_extensions(void); + +u64 arch_cpu_num_ras_nodes(void); + +void arch_report_ras_error_on_node(unsigned int cpu_num, unsigned int i); + +void arch_ras_node_setup(unsigned int i); + +#endif diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 0025f869..c7998f4 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -55,6 +55,7 @@ arm64-reloc-test-y := reloc_test_core.o reloc_test_syms.o arm64-obj-$(CONFIG_CRASH_DUMP) += crash_dump.o arm64-obj-$(CONFIG_ARM_SDE_INTERFACE) += sdei.o arm64-obj-$(CONFIG_ARM64_SSBD) += ssbd.o +arm64-obj-$(CONFIG_EDAC_ARMV8) += ras.o obj-y += $(arm64-obj-y) vdso/ probes/ obj-m += $(arm64-obj-m) diff --git a/arch/arm64/kernel/ras.c b/arch/arm64/kernel/ras.c new file mode 100644 index 0000000..2cb0265 --- /dev/null +++ b/arch/arm64/kernel/ras.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#include +#include +#include + +#include + +bool arch_cpu_has_ras_extensions(void) +{ + return this_cpu_has_cap(ARM64_HAS_RAS_EXTN); +} + +u64 arch_cpu_num_ras_nodes(void) +{ + return read_sysreg_s(SYS_ERRIDR_EL1); +} + +void arch_report_ras_error_on_node(unsigned int cpu_num, unsigned int i) +{ + u64 status; + + write_sysreg_s(i, SYS_ERRSELR_EL1); + status = read_sysreg_s(SYS_ERXSTATUS_EL1); + if (status) { + pr_err("cpu #%u: ERR%uSTATUS = 0x%llx\n", cpu_num, i, status); + pr_err("cpu #%u: ERR%uCTLR = 0x%llx\n", + cpu_num, i, read_sysreg_s(SYS_ERXCTLR_EL1)); + pr_err("cpu #%u: ERR%uADDR = 0x%llx\n", + cpu_num, i, read_sysreg_s(SYS_ERXADDR_EL1)); + pr_err("cpu #%u: ERR%uMISC0 = 0x%llx\n", + cpu_num, i, read_sysreg_s(SYS_ERXMISC0_EL1)); + pr_err("cpu #%u: ERR%uMISC1 = 0x%llx\n", + cpu_num, i, read_sysreg_s(SYS_ERXMISC1_EL1)); + } +} + +void arch_ras_node_setup(unsigned int i) +{ + write_sysreg_s(i, SYS_ERRSELR_EL1); + pr_info("ERR%uFR = 0x%llx\n", i, read_sysreg_s(SYS_ERXFR_EL1)); +} diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index d399d45..53ed974 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include @@ -731,6 +732,9 @@ asmlinkage void do_serror(struct pt_regs *regs, unsigned int esr) { nmi_enter(); + if (IS_ENABLED(CONFIG_EDAC_ARMV8)) + armv8_edac_report_error(); + /* non-RAS errors are not containable */ if (!arm64_is_ras_serror(esr) || arm64_is_fatal_ras_serror(regs, esr)) arm64_serror_panic(regs, esr); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index b8eecc7..49debe7 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -641,6 +642,9 @@ static int do_sea(unsigned long addr, unsigned int esr, struct pt_regs *regs) ghes_notify_sea(); + if (IS_ENABLED(CONFIG_EDAC_ARMV8)) + armv8_edac_report_error(); + if (interrupts_enabled(regs)) nmi_exit(); } diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 57304b2..da0281d 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -74,6 +74,15 @@ config EDAC_GHES In doubt, say 'Y'. +config EDAC_ARMV8 + bool "ARMv8 RAS extension based error reporting" + depends on (EDAC=y) && ARM64_RAS_EXTN + default y + help + Support for error reporting through the ARMv8.2 RAS extension. The + ARMv8.2 RAS extension provides an architected way of reporting + hardware errors on ARM systems. + config EDAC_AMD64 tristate "AMD64 (Opteron, Athlon64)" depends on AMD_NB && EDAC_DECODE_MCE diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 02b43a7..001820d 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -50,6 +50,8 @@ amd64_edac_mod-$(CONFIG_EDAC_AMD64_ERROR_INJECTION) += amd64_edac_inj.o obj-$(CONFIG_EDAC_AMD64) += amd64_edac_mod.o +obj-$(CONFIG_EDAC_ARMV8) += armv8_edac.o + obj-$(CONFIG_EDAC_PASEMI) += pasemi_edac.o mpc85xx_edac_mod-y := fsl_ddr_edac.o mpc85xx_edac.o diff --git a/drivers/edac/armv8_edac.c b/drivers/edac/armv8_edac.c new file mode 100644 index 0000000..9df3dd8 --- /dev/null +++ b/drivers/edac/armv8_edac.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#include +#include +#include + +#include + +void armv8_edac_report_error(void) +{ + unsigned int cpu_num, i; + u64 num_nodes; + + cpu_num = get_cpu(); + if (!arch_cpu_has_ras_extensions()) + return; + + num_nodes = arch_cpu_num_ras_nodes(); + + for (i = 0; i < num_nodes; i++) + arch_report_ras_error_on_node(cpu_num, i); + put_cpu(); +} + +static int __init armv8_edac_init(void) +{ + unsigned int i; + u64 num_nodes; + + get_cpu(); + if (!arch_cpu_has_ras_extensions()) { + put_cpu(); + return -ENOTSUPP; + } + + pr_err("CPU has RAS extension\n"); + num_nodes = arch_cpu_num_ras_nodes(); + + for (i = 0; i < num_nodes; i++) { + arch_ras_node_setup(i); + } + + put_cpu(); + return 0; +} + +early_initcall(armv8_edac_init); diff --git a/include/linux/armv8_edac.h b/include/linux/armv8_edac.h new file mode 100644 index 0000000..222f7ea --- /dev/null +++ b/include/linux/armv8_edac.h @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only 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. + */ + +#ifndef LINUX_ARMV8_EDAC_H +#define LINUX_ARMV8_EDAC_H + +void armv8_edac_report_error(void); + +#endif