From 585fb3d93d32dbe89e718b85009f9c322cc554cd Mon Sep 17 00:00:00 2001 From: Pan Bian Date: Thu, 18 Apr 2019 10:27:18 +0800 Subject: [PATCH 01/16] EDAC/sysfs: Fix memory leak when creating a csrow object In edac_create_csrow_object(), the reference to the object is not released when adding the device to the device hierarchy fails (device_add()). This may result in a memory leak. Signed-off-by: Pan Bian Signed-off-by: Borislav Petkov Reviewed-by: Greg Kroah-Hartman Cc: James Morse Cc: Mauro Carvalho Chehab Cc: linux-edac Link: https://lkml.kernel.org/r/1555554438-103953-1-git-send-email-bianpan2016@163.com --- drivers/edac/edac_mc_sysfs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 464174685589..9b7d396f26e9 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -404,6 +404,8 @@ static inline int nr_pages_per_csrow(struct csrow_info *csrow) static int edac_create_csrow_object(struct mem_ctl_info *mci, struct csrow_info *csrow, int index) { + int err; + csrow->dev.type = &csrow_attr_type; csrow->dev.groups = csrow_dev_groups; device_initialize(&csrow->dev); @@ -415,7 +417,11 @@ static int edac_create_csrow_object(struct mem_ctl_info *mci, edac_dbg(0, "creating (virtual) csrow node %s\n", dev_name(&csrow->dev)); - return device_add(&csrow->dev); + err = device_add(&csrow->dev); + if (err) + put_device(&csrow->dev); + + return err; } /* Create a CSROW object under specifed edac_mc_device */ From 7adc05d2dc3af95e4e1534841d58f736262142cd Mon Sep 17 00:00:00 2001 From: Greg KH Date: Wed, 8 May 2019 12:40:42 +0200 Subject: [PATCH 02/16] EDAC/sysfs: Drop device references properly Do put_device() if device_add() fails. [ bp: do device_del() for the successfully created devices in edac_create_csrow_objects(), on the unwind path. ] Signed-off-by: Greg KH Signed-off-by: Borislav Petkov Link: https://lkml.kernel.org/r/20190427214925.GE16338@kroah.com --- drivers/edac/edac_mc_sysfs.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 9b7d396f26e9..7c01e1cc030c 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -449,7 +449,8 @@ error: csrow = mci->csrows[i]; if (!nr_pages_per_csrow(csrow)) continue; - put_device(&mci->csrows[i]->dev); + + device_del(&mci->csrows[i]->dev); } return err; @@ -651,9 +652,11 @@ static int edac_create_dimm_object(struct mem_ctl_info *mci, dev_set_drvdata(&dimm->dev, dimm); pm_runtime_forbid(&mci->dev); - err = device_add(&dimm->dev); + err = device_add(&dimm->dev); + if (err) + put_device(&dimm->dev); - edac_dbg(0, "creating rank/dimm device %s\n", dev_name(&dimm->dev)); + edac_dbg(0, "created rank/dimm device %s\n", dev_name(&dimm->dev)); return err; } @@ -934,6 +937,7 @@ int edac_create_sysfs_mci_device(struct mem_ctl_info *mci, err = device_add(&mci->dev); if (err < 0) { edac_dbg(1, "failure: create device %s\n", dev_name(&mci->dev)); + put_device(&mci->dev); goto out; } From 17e47dc6db4fa6114f031365a81fda1b2d9b8e3f Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Tue, 23 Apr 2019 09:36:34 -0500 Subject: [PATCH 03/16] EDAC/altera: Add Stratix10 OCRAM ECC support Use the newer ECC error injection method for Arria10 and Stratix10 OCRAM. If OCRAM has already been initialized during boot and OCRAM ECC is enabled, ensure the Single Bit Error IRQ is enabled. Signed-off-by: Thor Thayer Signed-off-by: Borislav Petkov Cc: devicetree@vger.kernel.org Cc: dinguyen@kernel.org Cc: James Morse Cc: linux-edac Cc: mark.rutland@arm.com Cc: Mauro Carvalho Chehab Cc: robh+dt@kernel.org Link: https://lkml.kernel.org/r/1556030197-24534-2-git-send-email-thor.thayer@linux.intel.com --- drivers/edac/altera_edac.c | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index 8816f74a22b4..b7bc8f020df8 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1223,8 +1223,31 @@ static const struct edac_device_prv_data ocramecc_data = { .inject_fops = &altr_edac_device_inject_fops, }; +static int __maybe_unused +altr_check_ocram_deps_init(struct altr_edac_device_dev *device) +{ + void __iomem *base = device->base; + int ret; + + ret = altr_check_ecc_deps(device); + if (ret) + return ret; + + /* Verify OCRAM has been initialized */ + if (!ecc_test_bits(ALTR_A10_ECC_INITCOMPLETEA, + (base + ALTR_A10_ECC_INITSTAT_OFST))) + return -ENODEV; + + /* Enable IRQ on Single Bit Error */ + writel(ALTR_A10_ECC_SERRINTEN, (base + ALTR_A10_ECC_ERRINTENS_OFST)); + /* Ensure all writes complete */ + wmb(); + + return 0; +} + static const struct edac_device_prv_data a10_ocramecc_data = { - .setup = altr_check_ecc_deps, + .setup = altr_check_ocram_deps_init, .ce_clear_mask = ALTR_A10_ECC_SERRPENA, .ue_clear_mask = ALTR_A10_ECC_DERRPENA, .irq_status_mask = A10_SYSMGR_ECC_INTSTAT_OCRAM, @@ -1234,7 +1257,7 @@ static const struct edac_device_prv_data a10_ocramecc_data = { .ue_set_mask = ALTR_A10_ECC_TDERRA, .set_err_ofst = ALTR_A10_ECC_INTTEST_OFST, .ecc_irq_handler = altr_edac_a10_ecc_irq, - .inject_fops = &altr_edac_a10_device_inject_fops, + .inject_fops = &altr_edac_a10_device_inject2_fops, /* * OCRAM panic on uncorrectable error because sleep/resume * functions and FPGA contents are stored in OCRAM. Prefer From 3c4fcb89db2c01b220477318659a31b3dd22dfba Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Tue, 23 Apr 2019 09:36:35 -0500 Subject: [PATCH 04/16] arm64: dts: stratix10: Add OCRAM EDAC node Add the OCRAM ECC node with Stratix10 compatible string. Signed-off-by: Thor Thayer Signed-off-by: Borislav Petkov Acked-by: Dinh Nguyen Cc: devicetree@vger.kernel.org Cc: James Morse Cc: linux-edac Cc: Mark Rutland Cc: mchehab@kernel.org Cc: Rob Herring Link: https://lkml.kernel.org/r/1556030197-24534-3-git-send-email-thor.thayer@linux.intel.com --- arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi index 470dcfd9de91..4b0f674df849 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10.dtsi @@ -539,6 +539,14 @@ interrupts = <16 4>; }; + ocram-ecc@ff8cc000 { + compatible = "altr,socfpga-s10-ocram-ecc", + "altr,socfpga-a10-ocram-ecc"; + reg = <0xff8cc000 0x100>; + altr,ecc-parent = <&ocram>; + interrupts = <1 4>; + }; + usb0-ecc@ff8c4000 { compatible = "altr,socfpga-s10-usb-ecc", "altr,socfpga-usb-ecc"; From a428b4d348c40584342ad0f7733f546b707e4a65 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Tue, 23 Apr 2019 09:36:36 -0500 Subject: [PATCH 05/16] EDAC/altera: Add Stratix10 SDMMC support Add SDMMC support for Stratix10 which has IRQ differences from Arria10. Update comment accordingly. Signed-off-by: Thor Thayer Signed-off-by: Borislav Petkov Cc: devicetree@vger.kernel.org Cc: dinguyen@kernel.org Cc: James Morse Cc: linux-edac Cc: mark.rutland@arm.com Cc: Mauro Carvalho Chehab Cc: robh+dt@kernel.org Link: https://lkml.kernel.org/r/1556030197-24534-4-git-send-email-thor.thayer@linux.intel.com --- drivers/edac/altera_edac.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/edac/altera_edac.c b/drivers/edac/altera_edac.c index b7bc8f020df8..c2e693e34d43 100644 --- a/drivers/edac/altera_edac.c +++ b/drivers/edac/altera_edac.c @@ -1583,8 +1583,12 @@ static int altr_portb_setup(struct altr_edac_device_dev *device) dci->mod_name = ecc_name; dci->dev_name = ecc_name; - /* Update the IRQs for PortB */ + /* Update the PortB IRQs - A10 has 4, S10 has 2, Index accordingly */ +#ifdef CONFIG_ARCH_STRATIX10 + altdev->sb_irq = irq_of_parse_and_map(np, 1); +#else altdev->sb_irq = irq_of_parse_and_map(np, 2); +#endif if (!altdev->sb_irq) { edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB SBIRQ alloc\n"); rc = -ENODEV; @@ -1599,6 +1603,15 @@ static int altr_portb_setup(struct altr_edac_device_dev *device) goto err_release_group_1; } +#ifdef CONFIG_ARCH_STRATIX10 + /* Use IRQ to determine SError origin instead of assigning IRQ */ + rc = of_property_read_u32_index(np, "interrupts", 1, &altdev->db_irq); + if (rc) { + edac_printk(KERN_ERR, EDAC_DEVICE, + "Error PortB DBIRQ alloc\n"); + goto err_release_group_1; + } +#else altdev->db_irq = irq_of_parse_and_map(np, 3); if (!altdev->db_irq) { edac_printk(KERN_ERR, EDAC_DEVICE, "Error PortB DBIRQ alloc\n"); @@ -1613,6 +1626,7 @@ static int altr_portb_setup(struct altr_edac_device_dev *device) edac_printk(KERN_ERR, EDAC_DEVICE, "PortB DBERR IRQ error\n"); goto err_release_group_1; } +#endif rc = edac_device_add_device(dci); if (rc) { From 109d789922f157a569f5e56cbf4a717187567543 Mon Sep 17 00:00:00 2001 From: Thor Thayer Date: Tue, 23 Apr 2019 09:36:37 -0500 Subject: [PATCH 06/16] arm64: dts: stratix10: Add SDMMC EDAC node Add the Stratix10 SDMMC EDAC node. Signed-off-by: Thor Thayer Signed-off-by: Borislav Petkov Acked-by: Dinh Nguyen Cc: devicetree@vger.kernel.org Cc: James Morse Cc: linux-edac Cc: Mark Rutland Cc: mchehab@kernel.org Cc: Rob Herring Link: https://lkml.kernel.org/r/1556030197-24534-5-git-send-email-thor.thayer@linux.intel.com --- .../arm64/boot/dts/altera/socfpga_stratix10_socdk.dts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts index 84f9f5902e74..66e4ffb4e929 100644 --- a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts +++ b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk.dts @@ -56,6 +56,17 @@ clock-frequency = <25000000>; }; }; + + eccmgr { + sdmmca-ecc@ff8c8c00 { + compatible = "altr,socfpga-s10-sdmmc-ecc", + "altr,socfpga-sdmmc-ecc"; + reg = <0xff8c8c00 0x100>; + altr,ecc-parent = <&mmc>; + interrupts = <14 4>, + <15 4>; + }; + }; }; }; From 0042e9e7a5f662d7b8226316369d02c3553d6400 Mon Sep 17 00:00:00 2001 From: Colin Ian King Date: Wed, 8 May 2019 23:42:01 +0100 Subject: [PATCH 07/16] EDAC/sb_edac: Remove redundant update of tad_base The variable tad_base is being set to a value that is never read and is being over-written on the next iteration of a for-loop. This assignment is therefore redundant and can be removed. Signed-off-by: Colin Ian King Signed-off-by: Borislav Petkov Acked-by: Tony Luck Cc: James Morse Cc: kernel-janitors@vger.kernel.org Cc: linux-edac Cc: Mauro Carvalho Chehab Cc: Qiuxu Zhuo Link: https://lkml.kernel.org/r/20190508224201.27120-1-colin.king@canonical.com --- drivers/edac/sb_edac.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/edac/sb_edac.c b/drivers/edac/sb_edac.c index fa700a170380..37746b045e18 100644 --- a/drivers/edac/sb_edac.c +++ b/drivers/edac/sb_edac.c @@ -1511,7 +1511,6 @@ static int knl_get_dimm_capacity(struct sbridge_pvt *pvt, u64 *mc_sizes) sad_actual_size[mc] += tad_size; } } - tad_base = tad_limit+1; } } From 91abaeaaff35d97e88d2249f69f19db749a19a68 Mon Sep 17 00:00:00 2001 From: Yash Shah Date: Mon, 6 May 2019 16:57:06 +0530 Subject: [PATCH 08/16] EDAC/sifive: Add EDAC platform driver for SiFive SoCs Add an EDAC driver for SiFive SoCs. The initial version supports ECC event monitoring and reporting through the EDAC framework for the SiFive L2 cache controller. It registers for notifier events from the L2 cache controller driver (arch/riscv/mm/sifive_l2_cache.c) for L2 ECC events. [ bp: Massage commit message. ] Signed-off-by: Yash Shah Signed-off-by: Borislav Petkov Reviewed-by: James Morse Cc: Albert Ou Cc: "David S. Miller" Cc: Greg Kroah-Hartman Cc: Jonathan Cameron Cc: Linus Walleij Cc: linux-edac Cc: linux-riscv@lists.infradead.org Cc: Mauro Carvalho Chehab Cc: Nicolas Ferre Cc: Palmer Dabbelt Cc: "Paul E. McKenney" Cc: Paul Walmsley Cc: sachin.ghadi@sifive.com Link: https://lkml.kernel.org/r/1557142026-15949-2-git-send-email-yash.shah@sifive.com --- MAINTAINERS | 6 ++ arch/riscv/Kconfig | 1 + drivers/edac/Kconfig | 6 ++ drivers/edac/Makefile | 1 + drivers/edac/sifive_edac.c | 119 +++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+) create mode 100644 drivers/edac/sifive_edac.c diff --git a/MAINTAINERS b/MAINTAINERS index 57f496cff999..046596f6d490 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5809,6 +5809,12 @@ L: linux-edac@vger.kernel.org S: Maintained F: drivers/edac/sb_edac.c +EDAC-SIFIVE +M: Yash Shah +L: linux-edac@vger.kernel.org +S: Supported +F: drivers/edac/sifive_edac.c + EDAC-SKYLAKE M: Tony Luck L: linux-edac@vger.kernel.org diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 0c4b12205632..4961deaa3b1d 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -50,6 +50,7 @@ config RISCV select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MMIOWB select HAVE_EBPF_JIT if 64BIT + select EDAC_SUPPORT config MMU def_bool y diff --git a/drivers/edac/Kconfig b/drivers/edac/Kconfig index 5e2e0348d460..200c04ce5b0e 100644 --- a/drivers/edac/Kconfig +++ b/drivers/edac/Kconfig @@ -460,6 +460,12 @@ config EDAC_ALTERA_SDMMC Support for error detection and correction on the Altera SDMMC FIFO Memory for Altera SoCs. +config EDAC_SIFIVE + bool "Sifive platform EDAC driver" + depends on EDAC=y && RISCV + help + Support for error detection and correction on the SiFive SoCs. + config EDAC_SYNOPSYS tristate "Synopsys DDR Memory Controller" depends on ARCH_ZYNQ || ARCH_ZYNQMP diff --git a/drivers/edac/Makefile b/drivers/edac/Makefile index 89ad4a84a0f6..165ca65e1a3a 100644 --- a/drivers/edac/Makefile +++ b/drivers/edac/Makefile @@ -79,6 +79,7 @@ obj-$(CONFIG_EDAC_OCTEON_PCI) += octeon_edac-pci.o obj-$(CONFIG_EDAC_THUNDERX) += thunderx_edac.o obj-$(CONFIG_EDAC_ALTERA) += altera_edac.o +obj-$(CONFIG_EDAC_SIFIVE) += sifive_edac.o obj-$(CONFIG_EDAC_SYNOPSYS) += synopsys_edac.o obj-$(CONFIG_EDAC_XGENE) += xgene_edac.o obj-$(CONFIG_EDAC_TI) += ti_edac.o diff --git a/drivers/edac/sifive_edac.c b/drivers/edac/sifive_edac.c new file mode 100644 index 000000000000..413cdb4a591d --- /dev/null +++ b/drivers/edac/sifive_edac.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * SiFive Platform EDAC Driver + * + * Copyright (C) 2018-2019 SiFive, Inc. + * + * This driver is partially based on octeon_edac-pc.c + * + */ +#include +#include +#include "edac_module.h" +#include + +#define DRVNAME "sifive_edac" + +struct sifive_edac_priv { + struct notifier_block notifier; + struct edac_device_ctl_info *dci; +}; + +/** + * EDAC error callback + * + * @event: non-zero if unrecoverable. + */ +static +int ecc_err_event(struct notifier_block *this, unsigned long event, void *ptr) +{ + const char *msg = (char *)ptr; + struct sifive_edac_priv *p; + + p = container_of(this, struct sifive_edac_priv, notifier); + + if (event == SIFIVE_L2_ERR_TYPE_UE) + edac_device_handle_ue(p->dci, 0, 0, msg); + else if (event == SIFIVE_L2_ERR_TYPE_CE) + edac_device_handle_ce(p->dci, 0, 0, msg); + + return NOTIFY_OK; +} + +static int ecc_register(struct platform_device *pdev) +{ + struct sifive_edac_priv *p; + + p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->notifier.notifier_call = ecc_err_event; + platform_set_drvdata(pdev, p); + + p->dci = edac_device_alloc_ctl_info(0, "sifive_ecc", 1, "sifive_ecc", + 1, 1, NULL, 0, + edac_device_alloc_index()); + if (IS_ERR(p->dci)) + return PTR_ERR(p->dci); + + p->dci->dev = &pdev->dev; + p->dci->mod_name = "Sifive ECC Manager"; + p->dci->ctl_name = dev_name(&pdev->dev); + p->dci->dev_name = dev_name(&pdev->dev); + + if (edac_device_add_device(p->dci)) { + dev_err(p->dci->dev, "failed to register with EDAC core\n"); + goto err; + } + + register_sifive_l2_error_notifier(&p->notifier); + + return 0; + +err: + edac_device_free_ctl_info(p->dci); + + return -ENXIO; +} + +static int ecc_unregister(struct platform_device *pdev) +{ + struct sifive_edac_priv *p = platform_get_drvdata(pdev); + + unregister_sifive_l2_error_notifier(&p->notifier); + edac_device_del_device(&pdev->dev); + edac_device_free_ctl_info(p->dci); + + return 0; +} + +static struct platform_device *sifive_pdev; + +static int __init sifive_edac_init(void) +{ + int ret; + + sifive_pdev = platform_device_register_simple(DRVNAME, 0, NULL, 0); + if (IS_ERR(sifive_pdev)) + return PTR_ERR(sifive_pdev); + + ret = ecc_register(sifive_pdev); + if (ret) + platform_device_unregister(sifive_pdev); + + return ret; +} + +static void __exit sifive_edac_exit(void) +{ + ecc_unregister(sifive_pdev); + platform_device_unregister(sifive_pdev); +} + +module_init(sifive_edac_init); +module_exit(sifive_edac_exit); + +MODULE_AUTHOR("SiFive Inc."); +MODULE_DESCRIPTION("SiFive platform EDAC driver"); +MODULE_LICENSE("GPL v2"); From c452a9d30feb79787ada829d7d7c99574c77049f Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 10 Jun 2019 21:14:21 +0200 Subject: [PATCH 09/16] EDAC/ie31200: Add Intel Coffee Lake CPU support Coffee Lake seems to work like Skylake and Kaby Lake. Add all device IDs for Coffee Lake-S CPUs according to datasheet. [ bp: Massage. ] Signed-off-by: Marco Elver Signed-off-by: Borislav Petkov Acked-by: Tony Luck Cc: James Morse Cc: Jason Baron Cc: linux-edac Cc: Mauro Carvalho Chehab Link: https://lkml.kernel.org/r/20190610191422.177931-1-elver@google.com --- drivers/edac/ie31200_edac.c | 58 +++++++++++++++++++++++++++++++++++-- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c index adf60eb45bd4..50c31bede69b 100644 --- a/drivers/edac/ie31200_edac.c +++ b/drivers/edac/ie31200_edac.c @@ -20,11 +20,13 @@ * 0c08: Xeon E3-1200 v3 Processor DRAM Controller * 1918: Xeon E3-1200 v5 Skylake Host Bridge/DRAM Registers * 5918: Xeon E3-1200 Xeon E3-1200 v6/7th Gen Core Processor Host Bridge/DRAM Registers + * 3e..: 8th/9th Gen Core Processor Host Bridge/DRAM Registers * * Based on Intel specification: * http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/xeon-e3-1200v3-vol-2-datasheet.pdf * http://www.intel.com/content/www/us/en/processors/xeon/xeon-e3-1200-family-vol-2-datasheet.html * http://www.intel.com/content/www/us/en/processors/core/7th-gen-core-family-mobile-h-processor-lines-datasheet-vol-2.html + * https://www.intel.com/content/www/us/en/products/docs/processors/core/8th-gen-core-family-datasheet-vol-2.html * * According to the above datasheet (p.16): * " @@ -61,6 +63,26 @@ #define PCI_DEVICE_ID_INTEL_IE31200_HB_8 0x1918 #define PCI_DEVICE_ID_INTEL_IE31200_HB_9 0x5918 +/* Coffee Lake-S */ +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK 0x3e00 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_1 0x3e0f +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_2 0x3e18 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_3 0x3e1f +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_4 0x3e30 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_5 0x3e31 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_6 0x3e32 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_7 0x3e33 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_8 0x3ec2 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_9 0x3ec6 +#define PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_10 0x3eca + +/* Test if HB is for Skylake or later. */ +#define DEVICE_ID_SKYLAKE_OR_LATER(did) \ + (((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_8) || \ + ((did) == PCI_DEVICE_ID_INTEL_IE31200_HB_9) || \ + (((did) & PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK) == \ + PCI_DEVICE_ID_INTEL_IE31200_HB_CFL_MASK)) + #define IE31200_DIMMS 4 #define IE31200_RANKS 8 #define IE31200_RANKS_PER_CHANNEL 4 @@ -381,10 +403,10 @@ static int ie31200_probe1(struct pci_dev *pdev, int dev_idx) u32 addr_decode, mad_offset; /* - * Kaby Lake seems to work like Skylake. Please re-visit this logic - * when adding new CPU support. + * Kaby Lake, Coffee Lake seem to work like Skylake. Please re-visit + * this logic when adding new CPU support. */ - bool skl = (pdev->device >= PCI_DEVICE_ID_INTEL_IE31200_HB_8); + bool skl = DEVICE_ID_SKYLAKE_OR_LATER(pdev->device); edac_dbg(0, "MC:\n"); @@ -569,6 +591,36 @@ static const struct pci_device_id ie31200_pci_tbl[] = { { PCI_VEND_DEV(INTEL, IE31200_HB_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_1), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_2), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_3), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_4), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_5), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_6), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_7), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_8), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_9), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, + { + PCI_VEND_DEV(INTEL, IE31200_HB_CFL_10), PCI_ANY_ID, PCI_ANY_ID, + 0, 0, IE31200}, { 0, } /* 0 terminated list. */ From 4d91fde8d570ffe82e6aa0eec39935b5eed18b45 Mon Sep 17 00:00:00 2001 From: Marco Elver Date: Mon, 10 Jun 2019 21:14:22 +0200 Subject: [PATCH 10/16] EDAC/ie31200: Reformat PCI device table Reformat device table after Coffee Lake additions to be more readable. No functional change. Signed-off-by: Marco Elver Signed-off-by: Borislav Petkov Acked-by: Tony Luck Cc: James Morse Cc: Jason Baron Cc: linux-edac Cc: Mauro Carvalho Chehab Link: https://lkml.kernel.org/r/20190610191422.177931-2-elver@google.com --- drivers/edac/ie31200_edac.c | 80 ++++++++++--------------------------- 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/drivers/edac/ie31200_edac.c b/drivers/edac/ie31200_edac.c index 50c31bede69b..d26300f9cb07 100644 --- a/drivers/edac/ie31200_edac.c +++ b/drivers/edac/ie31200_edac.c @@ -564,66 +564,26 @@ static void ie31200_remove_one(struct pci_dev *pdev) } static const struct pci_device_id ie31200_pci_tbl[] = { - { - PCI_VEND_DEV(INTEL, IE31200_HB_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_4), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_5), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_6), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_8), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0, - IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_1), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_2), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_3), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_4), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_5), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_6), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_7), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_8), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_9), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - PCI_VEND_DEV(INTEL, IE31200_HB_CFL_10), PCI_ANY_ID, PCI_ANY_ID, - 0, 0, IE31200}, - { - 0, - } /* 0 terminated list. */ + { PCI_VEND_DEV(INTEL, IE31200_HB_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_4), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_5), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_6), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_8), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_1), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_2), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_3), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_4), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_5), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_6), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_7), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_8), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_9), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { PCI_VEND_DEV(INTEL, IE31200_HB_CFL_10), PCI_ANY_ID, PCI_ANY_ID, 0, 0, IE31200 }, + { 0, } /* 0 terminated list. */ }; MODULE_DEVICE_TABLE(pci, ie31200_pci_tbl); From ff70cacc967f9455e4b6f62b9a57b5962d9fb725 Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 25 May 2019 22:41:53 +0800 Subject: [PATCH 11/16] EDAC/aspeed: Remove set but not used variable 'np' Fix the following -Wunused-but-set-variable warning: drivers/edac/aspeed_edac.c: In function aspeed_probe: drivers/edac/aspeed_edac.c:284:22: warning: variable np set but not used [-Wunused-but-set-variable] It is never used and can be removed. Signed-off-by: YueHaibing Signed-off-by: Borislav Petkov Reviewed-by: Andrew Jeffery Reviewed-by: Stefan Schaeckeler Cc: James Morse Cc: Joel Stanley Cc: linux-arm-kernel@lists.infradead.org Cc: linux-aspeed@lists.ozlabs.org Cc: linux-edac Cc: Mauro Carvalho Chehab Link: https://lkml.kernel.org/r/20190525144153.2028-1-yuehaibing@huawei.com --- drivers/edac/aspeed_edac.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/edac/aspeed_edac.c b/drivers/edac/aspeed_edac.c index 11833c0a5d07..5634437bb39d 100644 --- a/drivers/edac/aspeed_edac.c +++ b/drivers/edac/aspeed_edac.c @@ -281,15 +281,11 @@ static int aspeed_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct edac_mc_layer layers[2]; struct mem_ctl_info *mci; - struct device_node *np; struct resource *res; void __iomem *regs; u32 reg04; int rc; - /* setup regmap */ - np = dev->of_node; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENOENT; From 40d796243478e0d072a7e637e7558c3c8216b60a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jun 2019 19:54:33 +0200 Subject: [PATCH 12/16] EDAC: Make edac_debugfs_create_x*() return void The return values of edac_debugfs_create_x16() and edac_debugfs_create_x8() are never checked (as they don't need to be), so no need to have them return anything, just make the functions return void instead. This is done with the goal of being able to change the debugfs_create_x* functions to also not return a value. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Borislav Petkov Cc: James Morse Cc: linux-edac Cc: Mauro Carvalho Chehab Link: https://lkml.kernel.org/r/20190611175433.GA5108@kroah.com --- drivers/edac/debugfs.c | 12 ++++++------ drivers/edac/edac_module.h | 18 ++++++++---------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/drivers/edac/debugfs.c b/drivers/edac/debugfs.c index 6b8e484db851..1f943599a8ac 100644 --- a/drivers/edac/debugfs.c +++ b/drivers/edac/debugfs.c @@ -118,23 +118,23 @@ edac_debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, EXPORT_SYMBOL_GPL(edac_debugfs_create_file); /* Wrapper for debugfs_create_x8() */ -struct dentry *edac_debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, u8 *value) +void edac_debugfs_create_x8(const char *name, umode_t mode, + struct dentry *parent, u8 *value) { if (!parent) parent = edac_debugfs; - return debugfs_create_x8(name, mode, parent, value); + debugfs_create_x8(name, mode, parent, value); } EXPORT_SYMBOL_GPL(edac_debugfs_create_x8); /* Wrapper for debugfs_create_x16() */ -struct dentry *edac_debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, u16 *value) +void edac_debugfs_create_x16(const char *name, umode_t mode, + struct dentry *parent, u16 *value) { if (!parent) parent = edac_debugfs; - return debugfs_create_x16(name, mode, parent, value); + debugfs_create_x16(name, mode, parent, value); } EXPORT_SYMBOL_GPL(edac_debugfs_create_x16); diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h index dd7d0b509aa3..bc4b806dc9cc 100644 --- a/drivers/edac/edac_module.h +++ b/drivers/edac/edac_module.h @@ -78,10 +78,10 @@ edac_debugfs_create_dir_at(const char *dirname, struct dentry *parent); struct dentry * edac_debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); -struct dentry * -edac_debugfs_create_x8(const char *name, umode_t mode, struct dentry *parent, u8 *value); -struct dentry * -edac_debugfs_create_x16(const char *name, umode_t mode, struct dentry *parent, u16 *value); +void edac_debugfs_create_x8(const char *name, umode_t mode, + struct dentry *parent, u8 *value); +void edac_debugfs_create_x16(const char *name, umode_t mode, + struct dentry *parent, u16 *value); #else static inline void edac_debugfs_init(void) { } static inline void edac_debugfs_exit(void) { } @@ -92,12 +92,10 @@ edac_debugfs_create_dir_at(const char *dirname, struct dentry *parent) { return static inline struct dentry * edac_debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops) { return NULL; } -static inline struct dentry * -edac_debugfs_create_x8(const char *name, umode_t mode, - struct dentry *parent, u8 *value) { return NULL; } -static inline struct dentry * -edac_debugfs_create_x16(const char *name, umode_t mode, - struct dentry *parent, u16 *value) { return NULL; } +static inline void edac_debugfs_create_x8(const char *name, umode_t mode, + struct dentry *parent, u8 *value) { } +static inline void edac_debugfs_create_x16(const char *name, umode_t mode, + struct dentry *parent, u16 *value) { } #endif /* From 5c5d3ac2064ae2466c81d40186bcc09b2d5b7892 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Thu, 13 Jun 2019 16:40:27 +0800 Subject: [PATCH 13/16] EDAC, i10nm: Add Intel additional Ice-Lake support Two new CPU models share the same memory controller architecture with Jacobsville/Tremont, so can use the same i10nm EDAC driver. Add ICX and ICX-D CPU model numbers for EDAC support. Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck --- drivers/edac/i10nm_base.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 6f06aec4877c..48c6cecc9683 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -124,6 +124,8 @@ static int i10nm_get_all_munits(void) static const struct x86_cpu_id i10nm_cpuids[] = { { X86_VENDOR_INTEL, 6, INTEL_FAM6_ATOM_TREMONT_X, 0, 0 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_X, 0, 0 }, + { X86_VENDOR_INTEL, 6, INTEL_FAM6_ICELAKE_XEON_D, 0, 0 }, { } }; MODULE_DEVICE_TABLE(x86cpu, i10nm_cpuids); From c4a1dd9e83ceceef6ffba82b8b274ab9b929ea14 Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Wed, 26 Jun 2019 14:16:38 +0800 Subject: [PATCH 14/16] EDAC, i10nm: Check ECC enabling status per channel The i10nm_edac only checks the ECC enabling status for the first channel of the memory controller. If there aren't memory DIMMs populated on the first channel, but at least one DIMM populated on the second channel, it will wrongly report that the ECC for the memory controller is disabled that fails to load the i10nm_edac driver. Fix it by checking ECC enabling status per channel. [Tony: Also report which channel has ECC disabled] Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck --- drivers/edac/i10nm_base.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 48c6cecc9683..72cc20a90ac1 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -168,9 +168,9 @@ static int i10nm_get_dimm_config(struct mem_ctl_info *mci) ndimms += skx_get_nvdimm_info(dimm, imc, i, j, EDAC_MOD_STR); } - if (ndimms && !i10nm_check_ecc(imc, 0)) { - i10nm_printk(KERN_ERR, "ECC is disabled on imc %d\n", - imc->mc); + if (ndimms && !i10nm_check_ecc(imc, i)) { + i10nm_printk(KERN_ERR, "ECC is disabled on imc %d channel %d\n", + imc->mc, i); return -ENODEV; } } From 1dc78f1ffa3a386b986b659884952d816021f38f Mon Sep 17 00:00:00 2001 From: Qiuxu Zhuo Date: Wed, 26 Jun 2019 14:16:55 +0800 Subject: [PATCH 15/16] EDAC, skx, i10nm: Fix source ID register offset The source ID register offset for Skylake server is 0xf0, while for Icelake server is 0xf8. Pass the correct offset to get the source ID. Signed-off-by: Qiuxu Zhuo Signed-off-by: Tony Luck --- drivers/edac/i10nm_base.c | 2 +- drivers/edac/skx_base.c | 2 +- drivers/edac/skx_common.c | 4 ++-- drivers/edac/skx_common.h | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/edac/i10nm_base.c b/drivers/edac/i10nm_base.c index 72cc20a90ac1..83392f2841de 100644 --- a/drivers/edac/i10nm_base.c +++ b/drivers/edac/i10nm_base.c @@ -267,7 +267,7 @@ static int __init i10nm_init(void) goto fail; list_for_each_entry(d, i10nm_edac_list, list) { - rc = skx_get_src_id(d, &src_id); + rc = skx_get_src_id(d, 0xf8, &src_id); if (rc < 0) goto fail; diff --git a/drivers/edac/skx_base.c b/drivers/edac/skx_base.c index a5c8fa3a249a..0fcf3785e8f3 100644 --- a/drivers/edac/skx_base.c +++ b/drivers/edac/skx_base.c @@ -639,7 +639,7 @@ static int __init skx_init(void) } list_for_each_entry(d, skx_edac_list, list) { - rc = skx_get_src_id(d, &src_id); + rc = skx_get_src_id(d, 0xf0, &src_id); if (rc < 0) goto fail; rc = skx_get_node_id(d, &node_id); diff --git a/drivers/edac/skx_common.c b/drivers/edac/skx_common.c index b0dddcfa9baa..d8ff63d91b86 100644 --- a/drivers/edac/skx_common.c +++ b/drivers/edac/skx_common.c @@ -136,11 +136,11 @@ void skx_set_decode(skx_decode_f decode) skx_decode = decode; } -int skx_get_src_id(struct skx_dev *d, u8 *id) +int skx_get_src_id(struct skx_dev *d, int off, u8 *id) { u32 reg; - if (pci_read_config_dword(d->util_all, 0xf0, ®)) { + if (pci_read_config_dword(d->util_all, off, ®)) { skx_printk(KERN_ERR, "Failed to read src id\n"); return -ENODEV; } diff --git a/drivers/edac/skx_common.h b/drivers/edac/skx_common.h index d18fa98669af..08cc971a50ea 100644 --- a/drivers/edac/skx_common.h +++ b/drivers/edac/skx_common.h @@ -118,7 +118,7 @@ int __init skx_adxl_get(void); void __exit skx_adxl_put(void); void skx_set_decode(skx_decode_f decode); -int skx_get_src_id(struct skx_dev *d, u8 *id); +int skx_get_src_id(struct skx_dev *d, int off, u8 *id); int skx_get_node_id(struct skx_dev *d, u8 *id); int skx_get_all_bus_mappings(unsigned int did, int off, enum type, From d8655e7630dafa88bc37f101640e39c736399771 Mon Sep 17 00:00:00 2001 From: Eiichi Tsukata Date: Wed, 26 Jun 2019 14:40:11 +0900 Subject: [PATCH 16/16] EDAC: Fix global-out-of-bounds write when setting edac_mc_poll_msec Commit 9da21b1509d8 ("EDAC: Poll timeout cannot be zero, p2") assumes edac_mc_poll_msec to be unsigned long, but the type of the variable still remained as int. Setting edac_mc_poll_msec can trigger out-of-bounds write. Reproducer: # echo 1001 > /sys/module/edac_core/parameters/edac_mc_poll_msec KASAN report: BUG: KASAN: global-out-of-bounds in edac_set_poll_msec+0x140/0x150 Write of size 8 at addr ffffffffb91b2d00 by task bash/1996 CPU: 1 PID: 1996 Comm: bash Not tainted 5.2.0-rc6+ #23 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.12.0-2.fc30 04/01/2014 Call Trace: dump_stack+0xca/0x13e print_address_description.cold+0x5/0x246 __kasan_report.cold+0x75/0x9a ? edac_set_poll_msec+0x140/0x150 kasan_report+0xe/0x20 edac_set_poll_msec+0x140/0x150 ? dimmdev_location_show+0x30/0x30 ? vfs_lock_file+0xe0/0xe0 ? _raw_spin_lock+0x87/0xe0 param_attr_store+0x1b5/0x310 ? param_array_set+0x4f0/0x4f0 module_attr_store+0x58/0x80 ? module_attr_show+0x80/0x80 sysfs_kf_write+0x13d/0x1a0 kernfs_fop_write+0x2bc/0x460 ? sysfs_kf_bin_read+0x270/0x270 ? kernfs_notify+0x1f0/0x1f0 __vfs_write+0x81/0x100 vfs_write+0x1e1/0x560 ksys_write+0x126/0x250 ? __ia32_sys_read+0xb0/0xb0 ? do_syscall_64+0x1f/0x390 do_syscall_64+0xc1/0x390 entry_SYSCALL_64_after_hwframe+0x49/0xbe RIP: 0033:0x7fa7caa5e970 Code: 73 01 c3 48 8b 0d 28 d5 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 0f 1f 44 00 00 83 3d 99 2d 2c 00 00 75 10 b8 01 00 00 00 04 RSP: 002b:00007fff6acfdfe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 0000000000000005 RCX: 00007fa7caa5e970 RDX: 0000000000000005 RSI: 0000000000e95c08 RDI: 0000000000000001 RBP: 0000000000e95c08 R08: 00007fa7cad1e760 R09: 00007fa7cb36a700 R10: 0000000000000073 R11: 0000000000000246 R12: 0000000000000005 R13: 0000000000000001 R14: 00007fa7cad1d600 R15: 0000000000000005 The buggy address belongs to the variable: edac_mc_poll_msec+0x0/0x40 Memory state around the buggy address: ffffffffb91b2c00: 00 00 00 00 fa fa fa fa 00 00 00 00 fa fa fa fa ffffffffb91b2c80: 00 00 00 00 fa fa fa fa 00 00 00 00 fa fa fa fa >ffffffffb91b2d00: 04 fa fa fa fa fa fa fa 04 fa fa fa fa fa fa fa ^ ffffffffb91b2d80: 04 fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00 ffffffffb91b2e00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Fix it by changing the type of edac_mc_poll_msec to unsigned int. The reason why this patch adopts unsigned int rather than unsigned long is msecs_to_jiffies() assumes arg to be unsigned int. We can avoid integer conversion bugs and unsigned int will be large enough for edac_mc_poll_msec. Reviewed-by: James Morse Fixes: 9da21b1509d8 ("EDAC: Poll timeout cannot be zero, p2") Signed-off-by: Eiichi Tsukata Signed-off-by: Tony Luck --- drivers/edac/edac_mc_sysfs.c | 16 ++++++++-------- drivers/edac/edac_module.h | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/edac/edac_mc_sysfs.c b/drivers/edac/edac_mc_sysfs.c index 7c01e1cc030c..4386ea4b9b5a 100644 --- a/drivers/edac/edac_mc_sysfs.c +++ b/drivers/edac/edac_mc_sysfs.c @@ -26,7 +26,7 @@ static int edac_mc_log_ue = 1; static int edac_mc_log_ce = 1; static int edac_mc_panic_on_ue; -static int edac_mc_poll_msec = 1000; +static unsigned int edac_mc_poll_msec = 1000; /* Getter functions for above */ int edac_mc_get_log_ue(void) @@ -45,30 +45,30 @@ int edac_mc_get_panic_on_ue(void) } /* this is temporary */ -int edac_mc_get_poll_msec(void) +unsigned int edac_mc_get_poll_msec(void) { return edac_mc_poll_msec; } static int edac_set_poll_msec(const char *val, const struct kernel_param *kp) { - unsigned long l; + unsigned int i; int ret; if (!val) return -EINVAL; - ret = kstrtoul(val, 0, &l); + ret = kstrtouint(val, 0, &i); if (ret) return ret; - if (l < 1000) + if (i < 1000) return -EINVAL; - *((unsigned long *)kp->arg) = l; + *((unsigned int *)kp->arg) = i; /* notify edac_mc engine to reset the poll period */ - edac_mc_reset_delay_period(l); + edac_mc_reset_delay_period(i); return 0; } @@ -82,7 +82,7 @@ MODULE_PARM_DESC(edac_mc_log_ue, module_param(edac_mc_log_ce, int, 0644); MODULE_PARM_DESC(edac_mc_log_ce, "Log correctable error to console: 0=off 1=on"); -module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_int, +module_param_call(edac_mc_poll_msec, edac_set_poll_msec, param_get_uint, &edac_mc_poll_msec, 0644); MODULE_PARM_DESC(edac_mc_poll_msec, "Polling period in milliseconds"); diff --git a/drivers/edac/edac_module.h b/drivers/edac/edac_module.h index bc4b806dc9cc..b2f59ee76c22 100644 --- a/drivers/edac/edac_module.h +++ b/drivers/edac/edac_module.h @@ -36,7 +36,7 @@ extern int edac_mc_get_log_ue(void); extern int edac_mc_get_log_ce(void); extern int edac_mc_get_panic_on_ue(void); extern int edac_get_poll_msec(void); -extern int edac_mc_get_poll_msec(void); +extern unsigned int edac_mc_get_poll_msec(void); unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf, unsigned len);