Merge branch 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Nov 2015 01:51:33 +0000 (17:51 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Nov 2015 01:51:33 +0000 (17:51 -0800)
Pull RAS changes from Ingo Molnar:
 "The main system reliability related changes were from x86, but also
  some generic RAS changes:

   - AMD MCE error injection subsystem enhancements.  (Aravind
     Gopalakrishnan)

   - Fix MCE and CPU hotplug interaction bug.  (Ashok Raj)

   - kcrash bootup robustness fix.  (Baoquan He)

   - kcrash cleanups.  (Borislav Petkov)

   - x86 microcode driver rework: simplify it by unmodularizing it and
     other cleanups.  (Borislav Petkov)"

* 'ras-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (23 commits)
  x86/mce: Add a default case to the switch in __mcheck_cpu_ancient_init()
  x86/mce: Add a Scalable MCA vendor flags bit
  MAINTAINERS: Unify the microcode driver section
  x86/microcode/intel: Move #ifdef DEBUG inside the function
  x86/microcode/amd: Remove maintainers from comments
  x86/microcode: Remove modularization leftovers
  x86/microcode: Merge the early microcode loader
  x86/microcode: Unmodularize the microcode driver
  x86/mce: Fix thermal throttling reporting after kexec
  kexec/crash: Say which char is the unrecognized
  x86/setup/crash: Check memblock_reserve() retval
  x86/setup/crash: Cleanup some more
  x86/setup/crash: Remove alignment variable
  x86/setup: Cleanup crashkernel reservation functions
  x86/amd_nb, EDAC: Rename amd_get_node_id()
  x86/setup: Do not reserve crashkernel high memory if low reservation failed
  x86/microcode/amd: Do not overwrite final patch levels
  x86/microcode/amd: Extract current patch level read to a function
  x86/ras/mce_amd_inj: Inject bank 4 errors on the NBC
  x86/ras/mce_amd_inj: Trigger deferred and thresholding errors interrupts
  ...

1  2 
MAINTAINERS
arch/x86/kernel/setup.c
drivers/edac/amd64_edac.c

diff --combined MAINTAINERS
@@@ -240,12 -240,6 +240,12 @@@ L:       lm-sensors@lm-sensors.or
  S:    Maintained
  F:    drivers/hwmon/abituguru3.c
  
 +ACCES 104-IDIO-16 GPIO DRIVER
 +M:    "William Breathitt Gray" <vilhelm.gray@gmail.com>
 +L:    linux-gpio@vger.kernel.org
 +S:    Maintained
 +F:    drivers/gpio/gpio-104-idio-16.c
 +
  ACENIC DRIVER
  M:    Jes Sorensen <jes@trained-monkey.org>
  L:    linux-acenic@sunsite.dk
@@@ -660,11 -654,6 +660,6 @@@ F:        drivers/gpu/drm/radeon/radeon_kfd.
  F:    drivers/gpu/drm/radeon/radeon_kfd.h
  F:    include/uapi/linux/kfd_ioctl.h
  
- AMD MICROCODE UPDATE SUPPORT
- M:    Borislav Petkov <bp@alien8.de>
- S:    Maintained
- F:    arch/x86/kernel/cpu/microcode/amd*
  AMD XGBE DRIVER
  M:    Tom Lendacky <thomas.lendacky@amd.com>
  L:    netdev@vger.kernel.org
@@@ -900,12 -889,11 +895,12 @@@ M:      Lennert Buytenhek <kernel@wantstofly
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
  
 -ARM/Allwinner A1X SoC support
 +ARM/Allwinner sunXi SoC support
  M:    Maxime Ripard <maxime.ripard@free-electrons.com>
 +M:    Chen-Yu Tsai <wens@csie.org>
  L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
  S:    Maintained
 -N:    sun[x4567]i
 +N:    sun[x456789]i
  
  ARM/Allwinner SoC Clock Support
  M:    Emilio López <emilio@elopez.com.ar>
@@@ -1786,14 -1774,6 +1781,14 @@@ S:    Supporte
  F:    Documentation/aoe/
  F:    drivers/block/aoe/
  
 +ATHEROS 71XX/9XXX GPIO DRIVER
 +M:    Alban Bedel <albeu@free.fr>
 +W:    https://github.com/AlbanBedel/linux
 +T:    git git://github.com/AlbanBedel/linux
 +S:    Maintained
 +F:    drivers/gpio/gpio-ath79.c
 +F:    Documentation/devicetree/bindings/gpio/gpio-ath79.txt
 +
  ATHEROS ATH GENERIC UTILITIES
  M:    "Luis R. Rodriguez" <mcgrof@do-not-panic.com>
  L:    linux-wireless@vger.kernel.org
@@@ -3606,13 -3586,6 +3601,13 @@@ F:    drivers/gpu/drm/i915
  F:    include/drm/i915*
  F:    include/uapi/drm/i915*
  
 +DRM DRIVERS FOR ATMEL HLCDC
 +M:    Boris Brezillon <boris.brezillon@free-electrons.com>
 +L:    dri-devel@lists.freedesktop.org
 +S:    Supported
 +F:    drivers/gpu/drm/atmel-hlcdc/
 +F:    Documentation/devicetree/bindings/drm/atmel/
 +
  DRM DRIVERS FOR EXYNOS
  M:    Inki Dae <inki.dae@samsung.com>
  M:    Joonyoung Shim <jy0922.shim@samsung.com>
@@@ -3641,14 -3614,6 +3636,14 @@@ S:    Maintaine
  F:    drivers/gpu/drm/imx/
  F:    Documentation/devicetree/bindings/drm/imx/
  
 +DRM DRIVERS FOR GMA500 (Poulsbo, Moorestown and derivative chipsets)
 +M:    Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
 +L:    dri-devel@lists.freedesktop.org
 +T:    git git://github.com/patjak/drm-gma500
 +S:    Maintained
 +F:    drivers/gpu/drm/gma500
 +F:    include/drm/gma500*
 +
  DRM DRIVERS FOR NVIDIA TEGRA
  M:    Thierry Reding <thierry.reding@gmail.com>
  M:    Terje Bergström <tbergstrom@nvidia.com>
@@@ -4442,14 -4407,6 +4437,14 @@@ L:    linuxppc-dev@lists.ozlabs.or
  S:    Maintained
  F:    drivers/net/ethernet/freescale/ucc_geth*
  
 +FREESCALE eTSEC ETHERNET DRIVER (GIANFAR)
 +M:    Claudiu Manoil <claudiu.manoil@freescale.com>
 +L:    netdev@vger.kernel.org
 +S:    Maintained
 +F:    drivers/net/ethernet/freescale/gianfar*
 +X:    drivers/net/ethernet/freescale/gianfar_ptp.c
 +F:    Documentation/devicetree/bindings/net/fsl-tsec-phy.txt
 +
  FREESCALE QUICC ENGINE UCC UART DRIVER
  M:    Timur Tabi <timur@tabi.org>
  L:    linuxppc-dev@lists.ozlabs.org
@@@ -5468,12 -5425,6 +5463,6 @@@ W:     https://01.org/linux-acp
  S:    Supported
  F:    drivers/platform/x86/intel_menlow.c
  
- INTEL IA32 MICROCODE UPDATE SUPPORT
- M:    Borislav Petkov <bp@alien8.de>
- S:    Maintained
- F:    arch/x86/kernel/cpu/microcode/core*
- F:    arch/x86/kernel/cpu/microcode/intel*
  INTEL I/OAT DMA DRIVER
  M:    Dave Jiang <dave.jiang@intel.com>
  R:    Dan Williams <dan.j.williams@intel.com>
@@@ -6816,6 -6767,7 +6805,6 @@@ F:      drivers/scsi/megaraid
  
  MELLANOX ETHERNET DRIVER (mlx4_en)
  M:    Amir Vadai <amirv@mellanox.com>
 -M:    Ido Shamay <idos@mellanox.com>
  L:    netdev@vger.kernel.org
  S:    Supported
  W:    http://www.mellanox.com
@@@ -8195,13 -8147,6 +8184,13 @@@ L:    linux-arm-kernel@lists.infradead.or
  S:    Maintained
  F:    drivers/pinctrl/pinctrl-at91.*
  
 +PIN CONTROLLER - ATMEL AT91 PIO4
 +M:    Ludovic Desroches <ludovic.desroches@atmel.com>
 +L:    linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 +L:    linux-gpio@vger.kernel.org
 +S:    Supported
 +F:    drivers/pinctrl/pinctrl-at91-pio4.*
 +
  PIN CONTROLLER - INTEL
  M:    Mika Westerberg <mika.westerberg@linux.intel.com>
  M:    Heikki Krogerus <heikki.krogerus@linux.intel.com>
@@@ -9145,15 -9090,6 +9134,15 @@@ S: Supporte
  F: Documentation/devicetree/bindings/net/snps,dwc-qos-ethernet.txt
  F: drivers/net/ethernet/synopsys/dwc_eth_qos.c
  
 +SYNOPSYS DESIGNWARE I2C DRIVER
 +M:    Andy Shevchenko <andriy.shevchenko@linux.intel.com>
 +M:    Jarkko Nikula <jarkko.nikula@linux.intel.com>
 +M:    Mika Westerberg <mika.westerberg@linux.intel.com>
 +L:    linux-i2c@vger.kernel.org
 +S:    Maintained
 +F:    drivers/i2c/busses/i2c-designware-*
 +F:    include/linux/platform_data/i2c-designware.h
 +
  SYNOPSYS DESIGNWARE MMC/SD/SDIO DRIVER
  M:    Seungwon Jeon <tgih.jun@samsung.com>
  M:    Jaehoon Chung <jh80.chung@samsung.com>
@@@ -10121,7 -10057,6 +10110,7 @@@ F:   include/net/switchdev.
  
  SYNOPSYS ARC ARCHITECTURE
  M:    Vineet Gupta <vgupta@synopsys.com>
 +L:    linux-snps-arc@lists.infraded.org
  S:    Supported
  F:    arch/arc/
  F:    Documentation/devicetree/bindings/arc/*
@@@ -11505,6 -11440,11 +11494,11 @@@ L: linux-edac@vger.kernel.or
  S:    Maintained
  F:    arch/x86/kernel/cpu/mcheck/*
  
+ X86 MICROCODE UPDATE SUPPORT
+ M:    Borislav Petkov <bp@alien8.de>
+ S:    Maintained
+ F:    arch/x86/kernel/cpu/microcode/*
  X86 VDSO
  M:    Andy Lutomirski <luto@amacapital.net>
  L:    linux-kernel@vger.kernel.org
@@@ -11705,7 -11645,6 +11699,7 @@@ F:   drivers/tty/serial/zs.
  ZSMALLOC COMPRESSED SLAB MEMORY ALLOCATOR
  M:    Minchan Kim <minchan@kernel.org>
  M:    Nitin Gupta <ngupta@vflare.org>
 +R:    Sergey Senozhatsky <sergey.senozhatsky.work@gmail.com>
  L:    linux-mm@kvack.org
  S:    Maintained
  F:    mm/zsmalloc.c
diff --combined arch/x86/kernel/setup.c
  #include <asm/mce.h>
  #include <asm/alternative.h>
  #include <asm/prom.h>
+ #include <asm/microcode.h>
  
  /*
   * max_low_pfn_mapped: highest direct mapped pfn under 4GB
@@@ -480,34 -481,34 +481,34 @@@ static void __init memblock_x86_reserve
  
  #ifdef CONFIG_KEXEC_CORE
  
+ /* 16M alignment for crash kernel regions */
+ #define CRASH_ALIGN           (16 << 20)
  /*
   * Keep the crash kernel below this limit.  On 32 bits earlier kernels
   * would limit the kernel to the low 512 MiB due to mapping restrictions.
   * On 64bit, old kexec-tools need to under 896MiB.
   */
  #ifdef CONFIG_X86_32
- # define CRASH_KERNEL_ADDR_LOW_MAX    (512 << 20)
- # define CRASH_KERNEL_ADDR_HIGH_MAX   (512 << 20)
+ # define CRASH_ADDR_LOW_MAX   (512 << 20)
+ # define CRASH_ADDR_HIGH_MAX  (512 << 20)
  #else
- # define CRASH_KERNEL_ADDR_LOW_MAX    (896UL<<20)
- # define CRASH_KERNEL_ADDR_HIGH_MAX   MAXMEM
+ # define CRASH_ADDR_LOW_MAX   (896UL << 20)
+ # define CRASH_ADDR_HIGH_MAX  MAXMEM
  #endif
  
- static void __init reserve_crashkernel_low(void)
+ static int __init reserve_crashkernel_low(void)
  {
  #ifdef CONFIG_X86_64
-       const unsigned long long alignment = 16<<20;    /* 16M */
-       unsigned long long low_base = 0, low_size = 0;
+       unsigned long long base, low_base = 0, low_size = 0;
        unsigned long total_low_mem;
-       unsigned long long base;
-       bool auto_set = false;
        int ret;
  
-       total_low_mem = memblock_mem_size(1UL<<(32-PAGE_SHIFT));
+       total_low_mem = memblock_mem_size(1UL << (32 - PAGE_SHIFT));
        /* crashkernel=Y,low */
-       ret = parse_crashkernel_low(boot_command_line, total_low_mem,
-                                               &low_size, &base);
-       if (ret != 0) {
+       ret = parse_crashkernel_low(boot_command_line, total_low_mem, &low_size, &base);
+       if (ret) {
                /*
                 * two parts from lib/swiotlb.c:
                 * -swiotlb size: user-specified with swiotlb= or default.
                 * make sure we allocate enough extra low memory so that we
                 * don't run out of DMA buffers for 32-bit devices.
                 */
-               low_size = max(swiotlb_size_or_default() + (8UL<<20), 256UL<<20);
-               auto_set = true;
+               low_size = max(swiotlb_size_or_default() + (8UL << 20), 256UL << 20);
        } else {
                /* passed with crashkernel=0,low ? */
                if (!low_size)
-                       return;
+                       return 0;
        }
  
-       low_base = memblock_find_in_range(low_size, (1ULL<<32),
-                                       low_size, alignment);
+       low_base = memblock_find_in_range(low_size, 1ULL << 32, low_size, CRASH_ALIGN);
        if (!low_base) {
-               if (!auto_set)
-                       pr_info("crashkernel low reservation failed - No suitable area found.\n");
+               pr_err("Cannot reserve %ldMB crashkernel low memory, please try smaller size.\n",
+                      (unsigned long)(low_size >> 20));
+               return -ENOMEM;
+       }
  
-               return;
+       ret = memblock_reserve(low_base, low_size);
+       if (ret) {
+               pr_err("%s: Error reserving crashkernel low memblock.\n", __func__);
+               return ret;
        }
  
-       memblock_reserve(low_base, low_size);
        pr_info("Reserving %ldMB of low memory at %ldMB for crashkernel (System low RAM: %ldMB)\n",
-                       (unsigned long)(low_size >> 20),
-                       (unsigned long)(low_base >> 20),
-                       (unsigned long)(total_low_mem >> 20));
+               (unsigned long)(low_size >> 20),
+               (unsigned long)(low_base >> 20),
+               (unsigned long)(total_low_mem >> 20));
        crashk_low_res.start = low_base;
        crashk_low_res.end   = low_base + low_size - 1;
        insert_resource(&iomem_resource, &crashk_low_res);
  #endif
+       return 0;
  }
  
  static void __init reserve_crashkernel(void)
  {
-       const unsigned long long alignment = 16<<20;    /* 16M */
-       unsigned long long total_mem;
-       unsigned long long crash_size, crash_base;
+       unsigned long long crash_size, crash_base, total_mem;
        bool high = false;
        int ret;
  
        total_mem = memblock_phys_mem_size();
  
        /* crashkernel=XM */
-       ret = parse_crashkernel(boot_command_line, total_mem,
-                       &crash_size, &crash_base);
+       ret = parse_crashkernel(boot_command_line, total_mem, &crash_size, &crash_base);
        if (ret != 0 || crash_size <= 0) {
                /* crashkernel=X,high */
                ret = parse_crashkernel_high(boot_command_line, total_mem,
-                               &crash_size, &crash_base);
+                                            &crash_size, &crash_base);
                if (ret != 0 || crash_size <= 0)
                        return;
                high = true;
                /*
                 *  kexec want bzImage is below CRASH_KERNEL_ADDR_MAX
                 */
-               crash_base = memblock_find_in_range(alignment,
-                                       high ? CRASH_KERNEL_ADDR_HIGH_MAX :
-                                              CRASH_KERNEL_ADDR_LOW_MAX,
-                                       crash_size, alignment);
+               crash_base = memblock_find_in_range(CRASH_ALIGN,
+                                                   high ? CRASH_ADDR_HIGH_MAX
+                                                        : CRASH_ADDR_LOW_MAX,
+                                                   crash_size, CRASH_ALIGN);
                if (!crash_base) {
                        pr_info("crashkernel reservation failed - No suitable area found.\n");
                        return;
                unsigned long long start;
  
                start = memblock_find_in_range(crash_base,
-                                crash_base + crash_size, crash_size, 1<<20);
+                                              crash_base + crash_size,
+                                              crash_size, 1 << 20);
                if (start != crash_base) {
                        pr_info("crashkernel reservation failed - memory is in use.\n");
                        return;
                }
        }
-       memblock_reserve(crash_base, crash_size);
+       ret = memblock_reserve(crash_base, crash_size);
+       if (ret) {
+               pr_err("%s: Error reserving crashkernel memblock.\n", __func__);
+               return;
+       }
+       if (crash_base >= (1ULL << 32) && reserve_crashkernel_low()) {
+               memblock_free(crash_base, crash_size);
+               return;
+       }
  
-       printk(KERN_INFO "Reserving %ldMB of memory at %ldMB "
-                       "for crashkernel (System RAM: %ldMB)\n",
-                       (unsigned long)(crash_size >> 20),
-                       (unsigned long)(crash_base >> 20),
-                       (unsigned long)(total_mem >> 20));
+       pr_info("Reserving %ldMB of memory at %ldMB for crashkernel (System RAM: %ldMB)\n",
+               (unsigned long)(crash_size >> 20),
+               (unsigned long)(crash_base >> 20),
+               (unsigned long)(total_mem >> 20));
  
        crashk_res.start = crash_base;
        crashk_res.end   = crash_base + crash_size - 1;
        insert_resource(&iomem_resource, &crashk_res);
-       if (crash_base >= (1ULL<<32))
-               reserve_crashkernel_low();
  }
  #else
  static void __init reserve_crashkernel(void)
@@@ -1079,10 -1085,8 +1085,10 @@@ void __init setup_arch(char **cmdline_p
        memblock_set_current_limit(ISA_END_ADDRESS);
        memblock_x86_fill();
  
 -      if (efi_enabled(EFI_BOOT))
 +      if (efi_enabled(EFI_BOOT)) {
 +              efi_fake_memmap();
                efi_find_mirror();
 +      }
  
        /*
         * The EFI specification says that boot service code won't be called
        clone_pgd_range(initial_page_table + KERNEL_PGD_BOUNDARY,
                        swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
                        KERNEL_PGD_PTRS);
 +
 +      /*
 +       * sync back low identity map too.  It is used for example
 +       * in the 32-bit EFI stub.
 +       */
 +      clone_pgd_range(initial_page_table,
 +                      swapper_pg_dir     + KERNEL_PGD_BOUNDARY,
 +                      KERNEL_PGD_PTRS);
  #endif
  
        tboot_probe();
        if (efi_enabled(EFI_BOOT))
                efi_apply_memmap_quirks();
  #endif
+       microcode_init();
  }
  
  #ifdef CONFIG_X86_32
@@@ -173,7 -173,7 +173,7 @@@ static inline int amd64_read_dct_pci_cf
   * scan the scrub rate mapping table for a close or matching bandwidth value to
   * issue. If requested is too big, then use last maximum value found.
   */
 -static int __set_scrub_rate(struct pci_dev *ctl, u32 new_bw, u32 min_rate)
 +static int __set_scrub_rate(struct amd64_pvt *pvt, u32 new_bw, u32 min_rate)
  {
        u32 scrubval;
        int i;
  
        scrubval = scrubrates[i].scrubval;
  
 -      pci_write_bits32(ctl, SCRCTRL, scrubval, 0x001F);
 +      if (pvt->fam == 0x15 && pvt->model == 0x60) {
 +              f15h_select_dct(pvt, 0);
 +              pci_write_bits32(pvt->F2, F15H_M60H_SCRCTRL, scrubval, 0x001F);
 +              f15h_select_dct(pvt, 1);
 +              pci_write_bits32(pvt->F2, F15H_M60H_SCRCTRL, scrubval, 0x001F);
 +      } else {
 +              pci_write_bits32(pvt->F3, SCRCTRL, scrubval, 0x001F);
 +      }
  
        if (scrubval)
                return scrubrates[i].bandwidth;
@@@ -224,15 -217,11 +224,15 @@@ static int set_scrub_rate(struct mem_ct
        if (pvt->fam == 0xf)
                min_scrubrate = 0x0;
  
 -      /* Erratum #505 */
 -      if (pvt->fam == 0x15 && pvt->model < 0x10)
 -              f15h_select_dct(pvt, 0);
 +      if (pvt->fam == 0x15) {
 +              /* Erratum #505 */
 +              if (pvt->model < 0x10)
 +                      f15h_select_dct(pvt, 0);
  
 -      return __set_scrub_rate(pvt->F3, bw, min_scrubrate);
 +              if (pvt->model == 0x60)
 +                      min_scrubrate = 0x6;
 +      }
 +      return __set_scrub_rate(pvt, bw, min_scrubrate);
  }
  
  static int get_scrub_rate(struct mem_ctl_info *mci)
        u32 scrubval = 0;
        int i, retval = -EINVAL;
  
 -      /* Erratum #505 */
 -      if (pvt->fam == 0x15 && pvt->model < 0x10)
 -              f15h_select_dct(pvt, 0);
 +      if (pvt->fam == 0x15) {
 +              /* Erratum #505 */
 +              if (pvt->model < 0x10)
 +                      f15h_select_dct(pvt, 0);
  
 -      amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval);
 +              if (pvt->model == 0x60)
 +                      amd64_read_pci_cfg(pvt->F2, F15H_M60H_SCRCTRL, &scrubval);
 +      } else
 +              amd64_read_pci_cfg(pvt->F3, SCRCTRL, &scrubval);
  
        scrubval = scrubval & 0x001F;
  
@@@ -2785,7 -2770,7 +2785,7 @@@ static int init_one_instance(struct pci
        struct mem_ctl_info *mci = NULL;
        struct edac_mc_layer layers[2];
        int err = 0, ret;
-       u16 nid = amd_get_node_id(F2);
+       u16 nid = amd_pci_dev_to_node_id(F2);
  
        ret = -ENOMEM;
        pvt = kzalloc(sizeof(struct amd64_pvt), GFP_KERNEL);
@@@ -2875,7 -2860,7 +2875,7 @@@ err_ret
  static int probe_one_instance(struct pci_dev *pdev,
                              const struct pci_device_id *mc_type)
  {
-       u16 nid = amd_get_node_id(pdev);
+       u16 nid = amd_pci_dev_to_node_id(pdev);
        struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
        struct ecc_settings *s;
        int ret = 0;
@@@ -2925,7 -2910,7 +2925,7 @@@ static void remove_one_instance(struct 
  {
        struct mem_ctl_info *mci;
        struct amd64_pvt *pvt;
-       u16 nid = amd_get_node_id(pdev);
+       u16 nid = amd_pci_dev_to_node_id(pdev);
        struct pci_dev *F3 = node_to_amd_nb(nid)->misc;
        struct ecc_settings *s = ecc_stngs[nid];