]> Git Repo - J-linux.git/commitdiff
Merge tag 'edac_updates_for_v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <[email protected]>
Tue, 16 Jul 2024 01:20:24 +0000 (18:20 -0700)
committerLinus Torvalds <[email protected]>
Tue, 16 Jul 2024 01:20:24 +0000 (18:20 -0700)
Pull EDAC updates from Borislav Petkov:

 - The AMD memory controllers data fabric version 4.5 supports
   non-power-of-2 denormalization in the sense that certain bits of the
   system physical address cannot be reconstructed from the normalized
   address reported by the RAS hardware. Add support for handling such
   addresses

 - Switch the EDAC drivers to the new Intel CPU model defines

 - The usual fixes and cleanups all over the place

* tag 'edac_updates_for_v6.11' of git://git.kernel.org/pub/scm/linux/kernel/git/ras/ras:
  EDAC: Add missing MODULE_DESCRIPTION() macros
  EDAC/dmc520: Use devm_platform_ioremap_resource()
  EDAC/igen6: Add Intel Arrow Lake-U/H SoCs support
  RAS/AMD/FMPM: Use atl internal.h for INVALID_SPA
  RAS/AMD/ATL: Implement DF 4.5 NP2 denormalization
  RAS/AMD/ATL: Validate address map when information is gathered
  RAS/AMD/ATL: Expand helpers for adding and removing base and hole
  RAS/AMD/ATL: Read DRAM hole base early
  RAS/AMD/ATL: Add amd_atl pr_fmt() prefix
  RAS/AMD/ATL: Add a missing module description
  EDAC, i10nm: make skx_common.o a separate module
  EDAC/skx: Switch to new Intel CPU model defines
  EDAC/sb_edac: Switch to new Intel CPU model defines
  EDAC, pnd2: Switch to new Intel CPU model defines
  EDAC/i10nm: Switch to new Intel CPU model defines
  EDAC/ghes: Add missing newline to pr_info() statement
  RAS/AMD/ATL: Add missing newline to pr_info() statement
  EDAC/thunderx: Remove unused struct error_syndrome

1  2 
drivers/edac/igen6_edac.c
drivers/ras/amd/atl/internal.h
drivers/ras/amd/atl/system.c

index dbe9fe5f2ca6c35615563834a7e6553e35329f41,c9fc1e64069e33b1b69e26dfc9882c493df01bc8..0fe75eed8973b2a3f1c7de0758d436ff6d290cee
@@@ -258,6 -258,11 +258,11 @@@ static struct work_struct ecclog_work
  #define DID_MTL_P_SKU2        0x7d02
  #define DID_MTL_P_SKU3        0x7d14
  
+ /* Compute die IDs for Arrow Lake-UH with IBECC */
+ #define DID_ARL_UH_SKU1       0x7d06
+ #define DID_ARL_UH_SKU2       0x7d20
+ #define DID_ARL_UH_SKU3       0x7d30
  static int get_mchbar(struct pci_dev *pdev, u64 *mchbar)
  {
        union  {
@@@ -597,6 -602,9 +602,9 @@@ static const struct pci_device_id igen6
        { PCI_VDEVICE(INTEL, DID_MTL_P_SKU1), (kernel_ulong_t)&mtl_p_cfg },
        { PCI_VDEVICE(INTEL, DID_MTL_P_SKU2), (kernel_ulong_t)&mtl_p_cfg },
        { PCI_VDEVICE(INTEL, DID_MTL_P_SKU3), (kernel_ulong_t)&mtl_p_cfg },
+       { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU1), (kernel_ulong_t)&mtl_p_cfg },
+       { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU2), (kernel_ulong_t)&mtl_p_cfg },
+       { PCI_VDEVICE(INTEL, DID_ARL_UH_SKU3), (kernel_ulong_t)&mtl_p_cfg },
        { },
  };
  MODULE_DEVICE_TABLE(pci, igen6_pci_tbl);
@@@ -800,7 -808,7 +808,7 @@@ static int errcmd_enable_error_reportin
  
        rc = pci_read_config_word(imc->pdev, ERRCMD_OFFSET, &errcmd);
        if (rc)
 -              return rc;
 +              return pcibios_err_to_errno(rc);
  
        if (enable)
                errcmd |= ERRCMD_CE | ERRSTS_UE;
  
        rc = pci_write_config_word(imc->pdev, ERRCMD_OFFSET, errcmd);
        if (rc)
 -              return rc;
 +              return pcibios_err_to_errno(rc);
  
        return 0;
  }
index 196c1c8b578cedb1fe230d59cb5963276b1de4b5,c67ba4bfe9cfa2fbad22a4f663dc820a7c57e8b2..9de5d53d05688beba06a0a408a809bdb039ae03c
@@@ -21,6 -21,9 +21,9 @@@
  
  #include "reg_fields.h"
  
+ #undef pr_fmt
+ #define pr_fmt(fmt) "amd_atl: " fmt
  /* Maximum possible number of Coherent Stations within a single Data Fabric. */
  #define MAX_COH_ST_CHANNELS           32
  
@@@ -34,6 -37,8 +37,8 @@@
  #define DF_DRAM_BASE_LIMIT_LSB                28
  #define MI300_DRAM_LIMIT_LSB          20
  
+ #define INVALID_SPA ~0ULL
  enum df_revisions {
        UNKNOWN,
        DF2,
@@@ -90,6 -95,44 +95,44 @@@ enum intlv_modes 
        DF4p5_NPS1_10CHAN_2K_HASH       = 0x49,
  };
  
+ struct df4p5_denorm_ctx {
+       /* Indicates the number of "lost" bits. This will be 1, 2, or 3. */
+       u8 perm_shift;
+       /* A mask indicating the bits that need to be rehashed. */
+       u16 rehash_vector;
+       /*
+        * Represents the value that the high bits of the normalized address
+        * are divided by during normalization. This value will be 3 for
+        * interleave modes with a number of channels divisible by 3 or the
+        * value will be 5 for interleave modes with a number of channels
+        * divisible by 5. Power-of-two interleave modes are handled
+        * separately.
+        */
+       u8 mod_value;
+       /*
+        * Represents the bits that can be directly pulled from the normalized
+        * address. In each case, pass through bits [7:0] of the normalized
+        * address. The other bits depend on the interleave bit position which
+        * will be bit 10 for 1K interleave stripe cases and bit 11 for 2K
+        * interleave stripe cases.
+        */
+       u64 base_denorm_addr;
+       /*
+        * Represents the high bits of the physical address that have been
+        * divided by the mod_value.
+        */
+       u64 div_addr;
+       u64 current_spa;
+       u64 resolved_spa;
+       u16 coh_st_fabric_id;
+ };
  struct df_flags {
        __u8    legacy_ficaa            : 1,
                socket_id_shift_quirk   : 1,
@@@ -132,6 -175,8 +175,8 @@@ struct df_config 
        /* Number of DRAM Address maps visible in a Coherent Station. */
        u8 num_coh_st_maps;
  
+       u32 dram_hole_base;
        /* Global flags to handle special cases. */
        struct df_flags flags;
  };
@@@ -224,7 -269,7 +269,7 @@@ int df_indirect_read_broadcast(u16 node
  
  int get_df_system_info(void);
  int determine_node_id(struct addr_ctx *ctx, u8 socket_num, u8 die_num);
 -int get_addr_hash_mi300(void);
 +int get_umc_info_mi300(void);
  
  int get_address_map(struct addr_ctx *ctx);
  
@@@ -234,6 -279,9 +279,9 @@@ int dehash_address(struct addr_ctx *ctx
  unsigned long norm_to_sys_addr(u8 socket_id, u8 die_id, u8 coh_st_inst_id, unsigned long addr);
  unsigned long convert_umc_mca_addr_to_sys_addr(struct atl_err *err);
  
+ u64 add_base_and_hole(struct addr_ctx *ctx, u64 addr);
+ u64 remove_base_and_hole(struct addr_ctx *ctx, u64 addr);
  /*
   * Make a gap in @data that is @num_bits long starting at @bit_num.
   * e.g. data          = 11111111'b
index 6979fa3d4fe25cf2562f44dbb5ba2e6861a4c18a,8423c9f3a8d264d0d9514e0b41f2e182fa19ff41..e18d916d5e8b9af4ef00de4c65001d621d91428c
@@@ -127,7 -127,7 +127,7 @@@ static int df4_determine_df_rev(u32 reg
        if (reg == DF_FUNC0_ID_MI300) {
                df_cfg.flags.heterogeneous = 1;
  
 -              if (get_addr_hash_mi300())
 +              if (get_umc_info_mi300())
                        return -EINVAL;
        }
  
@@@ -223,6 -223,21 +223,21 @@@ static int determine_df_rev(void
        return -EINVAL;
  }
  
+ static int get_dram_hole_base(void)
+ {
+       u8 func = 0;
+       if (df_cfg.rev >= DF4)
+               func = 7;
+       if (df_indirect_read_broadcast(0, func, 0x104, &df_cfg.dram_hole_base))
+               return -EINVAL;
+       df_cfg.dram_hole_base &= DF_DRAM_HOLE_BASE_MASK;
+       return 0;
+ }
  static void get_num_maps(void)
  {
        switch (df_cfg.rev) {
@@@ -266,6 -281,7 +281,7 @@@ static void dump_df_cfg(void
  
        pr_debug("num_coh_st_maps=%u",                  df_cfg.num_coh_st_maps);
  
+       pr_debug("dram_hole_base=0x%x",                 df_cfg.dram_hole_base);
        pr_debug("flags.legacy_ficaa=%u",               df_cfg.flags.legacy_ficaa);
        pr_debug("flags.socket_id_shift_quirk=%u",      df_cfg.flags.socket_id_shift_quirk);
  }
  int get_df_system_info(void)
  {
        if (determine_df_rev()) {
-               pr_warn("amd_atl: Failed to determine DF Revision");
+               pr_warn("Failed to determine DF Revision");
                df_cfg.rev = UNKNOWN;
                return -EINVAL;
        }
  
        get_num_maps();
  
+       if (get_dram_hole_base())
+               pr_warn("Failed to read DRAM hole base");
        dump_df_cfg();
  
        return 0;
This page took 0.090713 seconds and 4 git commands to generate.