LCOV - code coverage report
Current view: top level - drivers/edac - edac_mc.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 498 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 26 0.0 %
Branches: 0 284 0.0 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * edac_mc kernel module
       3                 :            :  * (C) 2005, 2006 Linux Networx (http://lnxi.com)
       4                 :            :  * This file may be distributed under the terms of the
       5                 :            :  * GNU General Public License.
       6                 :            :  *
       7                 :            :  * Written by Thayne Harbaugh
       8                 :            :  * Based on work by Dan Hollis <goemon at anime dot net> and others.
       9                 :            :  *      http://www.anime.net/~goemon/linux-ecc/
      10                 :            :  *
      11                 :            :  * Modified by Dave Peterson and Doug Thompson
      12                 :            :  *
      13                 :            :  */
      14                 :            : 
      15                 :            : #include <linux/module.h>
      16                 :            : #include <linux/proc_fs.h>
      17                 :            : #include <linux/kernel.h>
      18                 :            : #include <linux/types.h>
      19                 :            : #include <linux/smp.h>
      20                 :            : #include <linux/init.h>
      21                 :            : #include <linux/sysctl.h>
      22                 :            : #include <linux/highmem.h>
      23                 :            : #include <linux/timer.h>
      24                 :            : #include <linux/slab.h>
      25                 :            : #include <linux/jiffies.h>
      26                 :            : #include <linux/spinlock.h>
      27                 :            : #include <linux/list.h>
      28                 :            : #include <linux/ctype.h>
      29                 :            : #include <linux/edac.h>
      30                 :            : #include <linux/bitops.h>
      31                 :            : #include <linux/uaccess.h>
      32                 :            : #include <asm/page.h>
      33                 :            : #include "edac_mc.h"
      34                 :            : #include "edac_module.h"
      35                 :            : #include <ras/ras_event.h>
      36                 :            : 
      37                 :            : #ifdef CONFIG_EDAC_ATOMIC_SCRUB
      38                 :            : #include <asm/edac.h>
      39                 :            : #else
      40                 :            : #define edac_atomic_scrub(va, size) do { } while (0)
      41                 :            : #endif
      42                 :            : 
      43                 :            : int edac_op_state = EDAC_OPSTATE_INVAL;
      44                 :            : EXPORT_SYMBOL_GPL(edac_op_state);
      45                 :            : 
      46                 :            : static int edac_report = EDAC_REPORTING_ENABLED;
      47                 :            : 
      48                 :            : /* lock to memory controller's control array */
      49                 :            : static DEFINE_MUTEX(mem_ctls_mutex);
      50                 :            : static LIST_HEAD(mc_devices);
      51                 :            : 
      52                 :            : /*
      53                 :            :  * Used to lock EDAC MC to just one module, avoiding two drivers e. g.
      54                 :            :  *      apei/ghes and i7core_edac to be used at the same time.
      55                 :            :  */
      56                 :            : static const char *edac_mc_owner;
      57                 :            : 
      58                 :          0 : int edac_get_report_status(void)
      59                 :            : {
      60                 :          0 :         return edac_report;
      61                 :            : }
      62                 :            : EXPORT_SYMBOL_GPL(edac_get_report_status);
      63                 :            : 
      64                 :          0 : void edac_set_report_status(int new)
      65                 :            : {
      66                 :          0 :         if (new == EDAC_REPORTING_ENABLED ||
      67         [ #  # ]:          0 :             new == EDAC_REPORTING_DISABLED ||
      68                 :            :             new == EDAC_REPORTING_FORCE)
      69                 :          0 :                 edac_report = new;
      70                 :          0 : }
      71                 :            : EXPORT_SYMBOL_GPL(edac_set_report_status);
      72                 :            : 
      73                 :          0 : static int edac_report_set(const char *str, const struct kernel_param *kp)
      74                 :            : {
      75         [ #  # ]:          0 :         if (!str)
      76                 :            :                 return -EINVAL;
      77                 :            : 
      78         [ #  # ]:          0 :         if (!strncmp(str, "on", 2))
      79                 :          0 :                 edac_report = EDAC_REPORTING_ENABLED;
      80         [ #  # ]:          0 :         else if (!strncmp(str, "off", 3))
      81                 :          0 :                 edac_report = EDAC_REPORTING_DISABLED;
      82         [ #  # ]:          0 :         else if (!strncmp(str, "force", 5))
      83                 :          0 :                 edac_report = EDAC_REPORTING_FORCE;
      84                 :            : 
      85                 :            :         return 0;
      86                 :            : }
      87                 :            : 
      88                 :          0 : static int edac_report_get(char *buffer, const struct kernel_param *kp)
      89                 :            : {
      90                 :          0 :         int ret = 0;
      91                 :            : 
      92   [ #  #  #  # ]:          0 :         switch (edac_report) {
      93                 :          0 :         case EDAC_REPORTING_ENABLED:
      94                 :          0 :                 ret = sprintf(buffer, "on");
      95                 :          0 :                 break;
      96                 :          0 :         case EDAC_REPORTING_DISABLED:
      97                 :          0 :                 ret = sprintf(buffer, "off");
      98                 :          0 :                 break;
      99                 :          0 :         case EDAC_REPORTING_FORCE:
     100                 :          0 :                 ret = sprintf(buffer, "force");
     101                 :          0 :                 break;
     102                 :            :         default:
     103                 :            :                 ret = -EINVAL;
     104                 :            :                 break;
     105                 :            :         }
     106                 :            : 
     107                 :          0 :         return ret;
     108                 :            : }
     109                 :            : 
     110                 :            : static const struct kernel_param_ops edac_report_ops = {
     111                 :            :         .set = edac_report_set,
     112                 :            :         .get = edac_report_get,
     113                 :            : };
     114                 :            : 
     115                 :            : module_param_cb(edac_report, &edac_report_ops, &edac_report, 0644);
     116                 :            : 
     117                 :          0 : unsigned int edac_dimm_info_location(struct dimm_info *dimm, char *buf,
     118                 :            :                                      unsigned int len)
     119                 :            : {
     120                 :          0 :         struct mem_ctl_info *mci = dimm->mci;
     121                 :          0 :         int i, n, count = 0;
     122                 :          0 :         char *p = buf;
     123                 :            : 
     124         [ #  # ]:          0 :         for (i = 0; i < mci->n_layers; i++) {
     125                 :          0 :                 n = snprintf(p, len, "%s %d ",
     126                 :          0 :                               edac_layer_name[mci->layers[i].type],
     127                 :            :                               dimm->location[i]);
     128                 :          0 :                 p += n;
     129                 :          0 :                 len -= n;
     130                 :          0 :                 count += n;
     131         [ #  # ]:          0 :                 if (!len)
     132                 :            :                         break;
     133                 :            :         }
     134                 :            : 
     135                 :          0 :         return count;
     136                 :            : }
     137                 :            : 
     138                 :            : #ifdef CONFIG_EDAC_DEBUG
     139                 :            : 
     140                 :            : static void edac_mc_dump_channel(struct rank_info *chan)
     141                 :            : {
     142                 :            :         edac_dbg(4, "  channel->chan_idx = %d\n", chan->chan_idx);
     143                 :            :         edac_dbg(4, "    channel = %p\n", chan);
     144                 :            :         edac_dbg(4, "    channel->csrow = %p\n", chan->csrow);
     145                 :            :         edac_dbg(4, "    channel->dimm = %p\n", chan->dimm);
     146                 :            : }
     147                 :            : 
     148                 :            : static void edac_mc_dump_dimm(struct dimm_info *dimm)
     149                 :            : {
     150                 :            :         char location[80];
     151                 :            : 
     152                 :            :         if (!dimm->nr_pages)
     153                 :            :                 return;
     154                 :            : 
     155                 :            :         edac_dimm_info_location(dimm, location, sizeof(location));
     156                 :            : 
     157                 :            :         edac_dbg(4, "%s%i: %smapped as virtual row %d, chan %d\n",
     158                 :            :                  dimm->mci->csbased ? "rank" : "dimm",
     159                 :            :                  dimm->idx, location, dimm->csrow, dimm->cschannel);
     160                 :            :         edac_dbg(4, "  dimm = %p\n", dimm);
     161                 :            :         edac_dbg(4, "  dimm->label = '%s'\n", dimm->label);
     162                 :            :         edac_dbg(4, "  dimm->nr_pages = 0x%x\n", dimm->nr_pages);
     163                 :            :         edac_dbg(4, "  dimm->grain = %d\n", dimm->grain);
     164                 :            :         edac_dbg(4, "  dimm->nr_pages = 0x%x\n", dimm->nr_pages);
     165                 :            : }
     166                 :            : 
     167                 :            : static void edac_mc_dump_csrow(struct csrow_info *csrow)
     168                 :            : {
     169                 :            :         edac_dbg(4, "csrow->csrow_idx = %d\n", csrow->csrow_idx);
     170                 :            :         edac_dbg(4, "  csrow = %p\n", csrow);
     171                 :            :         edac_dbg(4, "  csrow->first_page = 0x%lx\n", csrow->first_page);
     172                 :            :         edac_dbg(4, "  csrow->last_page = 0x%lx\n", csrow->last_page);
     173                 :            :         edac_dbg(4, "  csrow->page_mask = 0x%lx\n", csrow->page_mask);
     174                 :            :         edac_dbg(4, "  csrow->nr_channels = %d\n", csrow->nr_channels);
     175                 :            :         edac_dbg(4, "  csrow->channels = %p\n", csrow->channels);
     176                 :            :         edac_dbg(4, "  csrow->mci = %p\n", csrow->mci);
     177                 :            : }
     178                 :            : 
     179                 :            : static void edac_mc_dump_mci(struct mem_ctl_info *mci)
     180                 :            : {
     181                 :            :         edac_dbg(3, "\tmci = %p\n", mci);
     182                 :            :         edac_dbg(3, "\tmci->mtype_cap = %lx\n", mci->mtype_cap);
     183                 :            :         edac_dbg(3, "\tmci->edac_ctl_cap = %lx\n", mci->edac_ctl_cap);
     184                 :            :         edac_dbg(3, "\tmci->edac_cap = %lx\n", mci->edac_cap);
     185                 :            :         edac_dbg(4, "\tmci->edac_check = %p\n", mci->edac_check);
     186                 :            :         edac_dbg(3, "\tmci->nr_csrows = %d, csrows = %p\n",
     187                 :            :                  mci->nr_csrows, mci->csrows);
     188                 :            :         edac_dbg(3, "\tmci->nr_dimms = %d, dimms = %p\n",
     189                 :            :                  mci->tot_dimms, mci->dimms);
     190                 :            :         edac_dbg(3, "\tdev = %p\n", mci->pdev);
     191                 :            :         edac_dbg(3, "\tmod_name:ctl_name = %s:%s\n",
     192                 :            :                  mci->mod_name, mci->ctl_name);
     193                 :            :         edac_dbg(3, "\tpvt_info = %p\n\n", mci->pvt_info);
     194                 :            : }
     195                 :            : 
     196                 :            : #endif                          /* CONFIG_EDAC_DEBUG */
     197                 :            : 
     198                 :            : const char * const edac_mem_types[] = {
     199                 :            :         [MEM_EMPTY]     = "Empty",
     200                 :            :         [MEM_RESERVED]  = "Reserved",
     201                 :            :         [MEM_UNKNOWN]   = "Unknown",
     202                 :            :         [MEM_FPM]       = "FPM",
     203                 :            :         [MEM_EDO]       = "EDO",
     204                 :            :         [MEM_BEDO]      = "BEDO",
     205                 :            :         [MEM_SDR]       = "Unbuffered-SDR",
     206                 :            :         [MEM_RDR]       = "Registered-SDR",
     207                 :            :         [MEM_DDR]       = "Unbuffered-DDR",
     208                 :            :         [MEM_RDDR]      = "Registered-DDR",
     209                 :            :         [MEM_RMBS]      = "RMBS",
     210                 :            :         [MEM_DDR2]      = "Unbuffered-DDR2",
     211                 :            :         [MEM_FB_DDR2]   = "FullyBuffered-DDR2",
     212                 :            :         [MEM_RDDR2]     = "Registered-DDR2",
     213                 :            :         [MEM_XDR]       = "XDR",
     214                 :            :         [MEM_DDR3]      = "Unbuffered-DDR3",
     215                 :            :         [MEM_RDDR3]     = "Registered-DDR3",
     216                 :            :         [MEM_LRDDR3]    = "Load-Reduced-DDR3-RAM",
     217                 :            :         [MEM_DDR4]      = "Unbuffered-DDR4",
     218                 :            :         [MEM_RDDR4]     = "Registered-DDR4",
     219                 :            :         [MEM_LRDDR4]    = "Load-Reduced-DDR4-RAM",
     220                 :            :         [MEM_NVDIMM]    = "Non-volatile-RAM",
     221                 :            : };
     222                 :            : EXPORT_SYMBOL_GPL(edac_mem_types);
     223                 :            : 
     224                 :            : /**
     225                 :            :  * edac_align_ptr - Prepares the pointer offsets for a single-shot allocation
     226                 :            :  * @p:          pointer to a pointer with the memory offset to be used. At
     227                 :            :  *              return, this will be incremented to point to the next offset
     228                 :            :  * @size:       Size of the data structure to be reserved
     229                 :            :  * @n_elems:    Number of elements that should be reserved
     230                 :            :  *
     231                 :            :  * If 'size' is a constant, the compiler will optimize this whole function
     232                 :            :  * down to either a no-op or the addition of a constant to the value of '*p'.
     233                 :            :  *
     234                 :            :  * The 'p' pointer is absolutely needed to keep the proper advancing
     235                 :            :  * further in memory to the proper offsets when allocating the struct along
     236                 :            :  * with its embedded structs, as edac_device_alloc_ctl_info() does it
     237                 :            :  * above, for example.
     238                 :            :  *
     239                 :            :  * At return, the pointer 'p' will be incremented to be used on a next call
     240                 :            :  * to this function.
     241                 :            :  */
     242                 :          0 : void *edac_align_ptr(void **p, unsigned int size, int n_elems)
     243                 :            : {
     244                 :          0 :         unsigned int align, r;
     245                 :          0 :         void *ptr = *p;
     246                 :            : 
     247                 :          0 :         *p += size * n_elems;
     248                 :            : 
     249                 :            :         /*
     250                 :            :          * 'p' can possibly be an unaligned item X such that sizeof(X) is
     251                 :            :          * 'size'.  Adjust 'p' so that its alignment is at least as
     252                 :            :          * stringent as what the compiler would provide for X and return
     253                 :            :          * the aligned result.
     254                 :            :          * Here we assume that the alignment of a "long long" is the most
     255                 :            :          * stringent alignment that the compiler will ever provide by default.
     256                 :            :          * As far as I know, this is a reasonable assumption.
     257                 :            :          */
     258         [ #  # ]:          0 :         if (size > sizeof(long))
     259                 :            :                 align = sizeof(long long);
     260   [ #  #  #  # ]:          0 :         else if (size > sizeof(int))
     261                 :            :                 align = sizeof(long);
     262   [ #  #  #  # ]:          0 :         else if (size > sizeof(short))
     263                 :            :                 align = sizeof(int);
     264   [ #  #  #  # ]:          0 :         else if (size > sizeof(char))
     265                 :            :                 align = sizeof(short);
     266                 :            :         else
     267                 :            :                 return (char *)ptr;
     268                 :            : 
     269                 :          0 :         r = (unsigned long)p % align;
     270                 :            : 
     271   [ #  #  #  # ]:          0 :         if (r == 0)
     272                 :            :                 return (char *)ptr;
     273                 :            : 
     274                 :          0 :         *p += align - r;
     275                 :            : 
     276                 :          0 :         return (void *)(((unsigned long)ptr) + align - r);
     277                 :            : }
     278                 :            : 
     279                 :          0 : static void _edac_mc_free(struct mem_ctl_info *mci)
     280                 :            : {
     281                 :          0 :         struct csrow_info *csr;
     282                 :          0 :         int i, chn, row;
     283                 :            : 
     284         [ #  # ]:          0 :         if (mci->dimms) {
     285         [ #  # ]:          0 :                 for (i = 0; i < mci->tot_dimms; i++)
     286                 :          0 :                         kfree(mci->dimms[i]);
     287                 :          0 :                 kfree(mci->dimms);
     288                 :            :         }
     289                 :            : 
     290         [ #  # ]:          0 :         if (mci->csrows) {
     291         [ #  # ]:          0 :                 for (row = 0; row < mci->nr_csrows; row++) {
     292                 :          0 :                         csr = mci->csrows[row];
     293         [ #  # ]:          0 :                         if (!csr)
     294                 :          0 :                                 continue;
     295                 :            : 
     296         [ #  # ]:          0 :                         if (csr->channels) {
     297         [ #  # ]:          0 :                                 for (chn = 0; chn < mci->num_cschannel; chn++)
     298                 :          0 :                                         kfree(csr->channels[chn]);
     299                 :          0 :                                 kfree(csr->channels);
     300                 :            :                         }
     301                 :          0 :                         kfree(csr);
     302                 :            :                 }
     303                 :          0 :                 kfree(mci->csrows);
     304                 :            :         }
     305                 :          0 :         kfree(mci);
     306                 :          0 : }
     307                 :            : 
     308                 :          0 : struct mem_ctl_info *edac_mc_alloc(unsigned int mc_num,
     309                 :            :                                    unsigned int n_layers,
     310                 :            :                                    struct edac_mc_layer *layers,
     311                 :            :                                    unsigned int sz_pvt)
     312                 :            : {
     313                 :          0 :         struct mem_ctl_info *mci;
     314                 :          0 :         struct edac_mc_layer *layer;
     315                 :          0 :         struct csrow_info *csr;
     316                 :          0 :         struct rank_info *chan;
     317                 :          0 :         struct dimm_info *dimm;
     318                 :          0 :         u32 *ce_per_layer[EDAC_MAX_LAYERS], *ue_per_layer[EDAC_MAX_LAYERS];
     319                 :          0 :         unsigned int pos[EDAC_MAX_LAYERS];
     320                 :          0 :         unsigned int idx, size, tot_dimms = 1, count = 1;
     321                 :          0 :         unsigned int tot_csrows = 1, tot_channels = 1, tot_errcount = 0;
     322                 :          0 :         void *pvt, *p, *ptr = NULL;
     323                 :          0 :         int i, j, row, chn, n, len;
     324                 :          0 :         bool per_rank = false;
     325                 :            : 
     326   [ #  #  #  # ]:          0 :         if (WARN_ON(n_layers > EDAC_MAX_LAYERS || n_layers == 0))
     327                 :            :                 return NULL;
     328                 :            : 
     329                 :            :         /*
     330                 :            :          * Calculate the total amount of dimms and csrows/cschannels while
     331                 :            :          * in the old API emulation mode
     332                 :            :          */
     333         [ #  # ]:          0 :         for (idx = 0; idx < n_layers; idx++) {
     334                 :          0 :                 tot_dimms *= layers[idx].size;
     335                 :            : 
     336         [ #  # ]:          0 :                 if (layers[idx].is_virt_csrow)
     337                 :          0 :                         tot_csrows *= layers[idx].size;
     338                 :            :                 else
     339                 :          0 :                         tot_channels *= layers[idx].size;
     340                 :            : 
     341         [ #  # ]:          0 :                 if (layers[idx].type == EDAC_MC_LAYER_CHIP_SELECT)
     342                 :          0 :                         per_rank = true;
     343                 :            :         }
     344                 :            : 
     345                 :            :         /* Figure out the offsets of the various items from the start of an mc
     346                 :            :          * structure.  We want the alignment of each item to be at least as
     347                 :            :          * stringent as what the compiler would provide if we could simply
     348                 :            :          * hardcode everything into a single struct.
     349                 :            :          */
     350                 :          0 :         mci = edac_align_ptr(&ptr, sizeof(*mci), 1);
     351                 :          0 :         layer = edac_align_ptr(&ptr, sizeof(*layer), n_layers);
     352         [ #  # ]:          0 :         for (i = 0; i < n_layers; i++) {
     353                 :          0 :                 count *= layers[i].size;
     354                 :          0 :                 edac_dbg(4, "errcount layer %d size %d\n", i, count);
     355                 :          0 :                 ce_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
     356                 :          0 :                 ue_per_layer[i] = edac_align_ptr(&ptr, sizeof(u32), count);
     357                 :          0 :                 tot_errcount += 2 * count;
     358                 :            :         }
     359                 :            : 
     360                 :          0 :         edac_dbg(4, "allocating %d error counters\n", tot_errcount);
     361         [ #  # ]:          0 :         pvt = edac_align_ptr(&ptr, sz_pvt, 1);
     362                 :          0 :         size = ((unsigned long)pvt) + sz_pvt;
     363                 :            : 
     364                 :          0 :         edac_dbg(1, "allocating %u bytes for mci data (%d %s, %d csrows/channels)\n",
     365                 :            :                  size,
     366                 :            :                  tot_dimms,
     367                 :            :                  per_rank ? "ranks" : "dimms",
     368                 :            :                  tot_csrows * tot_channels);
     369                 :            : 
     370                 :          0 :         mci = kzalloc(size, GFP_KERNEL);
     371         [ #  # ]:          0 :         if (mci == NULL)
     372                 :            :                 return NULL;
     373                 :            : 
     374                 :            :         /* Adjust pointers so they point within the memory we just allocated
     375                 :            :          * rather than an imaginary chunk of memory located at address 0.
     376                 :            :          */
     377                 :          0 :         layer = (struct edac_mc_layer *)(((char *)mci) + ((unsigned long)layer));
     378         [ #  # ]:          0 :         for (i = 0; i < n_layers; i++) {
     379                 :          0 :                 mci->ce_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ce_per_layer[i]));
     380                 :          0 :                 mci->ue_per_layer[i] = (u32 *)((char *)mci + ((unsigned long)ue_per_layer[i]));
     381                 :            :         }
     382         [ #  # ]:          0 :         pvt = sz_pvt ? (((char *)mci) + ((unsigned long)pvt)) : NULL;
     383                 :            : 
     384                 :            :         /* setup index and various internal pointers */
     385                 :          0 :         mci->mc_idx = mc_num;
     386                 :          0 :         mci->tot_dimms = tot_dimms;
     387                 :          0 :         mci->pvt_info = pvt;
     388                 :          0 :         mci->n_layers = n_layers;
     389                 :          0 :         mci->layers = layer;
     390                 :          0 :         memcpy(mci->layers, layers, sizeof(*layer) * n_layers);
     391                 :          0 :         mci->nr_csrows = tot_csrows;
     392                 :          0 :         mci->num_cschannel = tot_channels;
     393                 :          0 :         mci->csbased = per_rank;
     394                 :            : 
     395                 :            :         /*
     396                 :            :          * Alocate and fill the csrow/channels structs
     397                 :            :          */
     398                 :          0 :         mci->csrows = kcalloc(tot_csrows, sizeof(*mci->csrows), GFP_KERNEL);
     399         [ #  # ]:          0 :         if (!mci->csrows)
     400                 :          0 :                 goto error;
     401         [ #  # ]:          0 :         for (row = 0; row < tot_csrows; row++) {
     402                 :          0 :                 csr = kzalloc(sizeof(**mci->csrows), GFP_KERNEL);
     403         [ #  # ]:          0 :                 if (!csr)
     404                 :          0 :                         goto error;
     405                 :          0 :                 mci->csrows[row] = csr;
     406                 :          0 :                 csr->csrow_idx = row;
     407                 :          0 :                 csr->mci = mci;
     408                 :          0 :                 csr->nr_channels = tot_channels;
     409                 :          0 :                 csr->channels = kcalloc(tot_channels, sizeof(*csr->channels),
     410                 :            :                                         GFP_KERNEL);
     411         [ #  # ]:          0 :                 if (!csr->channels)
     412                 :          0 :                         goto error;
     413                 :            : 
     414         [ #  # ]:          0 :                 for (chn = 0; chn < tot_channels; chn++) {
     415                 :          0 :                         chan = kzalloc(sizeof(**csr->channels), GFP_KERNEL);
     416         [ #  # ]:          0 :                         if (!chan)
     417                 :          0 :                                 goto error;
     418                 :          0 :                         csr->channels[chn] = chan;
     419                 :          0 :                         chan->chan_idx = chn;
     420                 :          0 :                         chan->csrow = csr;
     421                 :            :                 }
     422                 :            :         }
     423                 :            : 
     424                 :            :         /*
     425                 :            :          * Allocate and fill the dimm structs
     426                 :            :          */
     427                 :          0 :         mci->dimms  = kcalloc(tot_dimms, sizeof(*mci->dimms), GFP_KERNEL);
     428         [ #  # ]:          0 :         if (!mci->dimms)
     429                 :          0 :                 goto error;
     430                 :            : 
     431                 :          0 :         memset(&pos, 0, sizeof(pos));
     432                 :          0 :         row = 0;
     433                 :          0 :         chn = 0;
     434         [ #  # ]:          0 :         for (idx = 0; idx < tot_dimms; idx++) {
     435                 :          0 :                 chan = mci->csrows[row]->channels[chn];
     436                 :            : 
     437                 :          0 :                 dimm = kzalloc(sizeof(**mci->dimms), GFP_KERNEL);
     438         [ #  # ]:          0 :                 if (!dimm)
     439                 :          0 :                         goto error;
     440                 :          0 :                 mci->dimms[idx] = dimm;
     441                 :          0 :                 dimm->mci = mci;
     442                 :          0 :                 dimm->idx = idx;
     443                 :            : 
     444                 :            :                 /*
     445                 :            :                  * Copy DIMM location and initialize it.
     446                 :            :                  */
     447                 :          0 :                 len = sizeof(dimm->label);
     448                 :          0 :                 p = dimm->label;
     449                 :          0 :                 n = snprintf(p, len, "mc#%u", mc_num);
     450                 :          0 :                 p += n;
     451                 :          0 :                 len -= n;
     452         [ #  # ]:          0 :                 for (j = 0; j < n_layers; j++) {
     453                 :          0 :                         n = snprintf(p, len, "%s#%u",
     454                 :          0 :                                      edac_layer_name[layers[j].type],
     455                 :            :                                      pos[j]);
     456                 :          0 :                         p += n;
     457                 :          0 :                         len -= n;
     458                 :          0 :                         dimm->location[j] = pos[j];
     459                 :            : 
     460         [ #  # ]:          0 :                         if (len <= 0)
     461                 :            :                                 break;
     462                 :            :                 }
     463                 :            : 
     464                 :            :                 /* Link it to the csrows old API data */
     465                 :          0 :                 chan->dimm = dimm;
     466                 :          0 :                 dimm->csrow = row;
     467                 :          0 :                 dimm->cschannel = chn;
     468                 :            : 
     469                 :            :                 /* Increment csrow location */
     470         [ #  # ]:          0 :                 if (layers[0].is_virt_csrow) {
     471                 :          0 :                         chn++;
     472         [ #  # ]:          0 :                         if (chn == tot_channels) {
     473                 :          0 :                                 chn = 0;
     474                 :          0 :                                 row++;
     475                 :            :                         }
     476                 :            :                 } else {
     477                 :          0 :                         row++;
     478         [ #  # ]:          0 :                         if (row == tot_csrows) {
     479                 :          0 :                                 row = 0;
     480                 :          0 :                                 chn++;
     481                 :            :                         }
     482                 :            :                 }
     483                 :            : 
     484                 :            :                 /* Increment dimm location */
     485         [ #  # ]:          0 :                 for (j = n_layers - 1; j >= 0; j--) {
     486                 :          0 :                         pos[j]++;
     487         [ #  # ]:          0 :                         if (pos[j] < layers[j].size)
     488                 :            :                                 break;
     489                 :          0 :                         pos[j] = 0;
     490                 :            :                 }
     491                 :            :         }
     492                 :            : 
     493                 :          0 :         mci->op_state = OP_ALLOC;
     494                 :            : 
     495                 :          0 :         return mci;
     496                 :            : 
     497                 :          0 : error:
     498                 :          0 :         _edac_mc_free(mci);
     499                 :            : 
     500                 :          0 :         return NULL;
     501                 :            : }
     502                 :            : EXPORT_SYMBOL_GPL(edac_mc_alloc);
     503                 :            : 
     504                 :          0 : void edac_mc_free(struct mem_ctl_info *mci)
     505                 :            : {
     506                 :          0 :         edac_dbg(1, "\n");
     507                 :            : 
     508         [ #  # ]:          0 :         if (device_is_registered(&mci->dev))
     509                 :          0 :                 edac_unregister_sysfs(mci);
     510                 :            : 
     511                 :          0 :         _edac_mc_free(mci);
     512                 :          0 : }
     513                 :            : EXPORT_SYMBOL_GPL(edac_mc_free);
     514                 :            : 
     515                 :          0 : bool edac_has_mcs(void)
     516                 :            : {
     517                 :          0 :         bool ret;
     518                 :            : 
     519                 :          0 :         mutex_lock(&mem_ctls_mutex);
     520                 :            : 
     521                 :          0 :         ret = list_empty(&mc_devices);
     522                 :            : 
     523                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     524                 :            : 
     525                 :          0 :         return !ret;
     526                 :            : }
     527                 :            : EXPORT_SYMBOL_GPL(edac_has_mcs);
     528                 :            : 
     529                 :            : /* Caller must hold mem_ctls_mutex */
     530                 :          0 : static struct mem_ctl_info *__find_mci_by_dev(struct device *dev)
     531                 :            : {
     532                 :          0 :         struct mem_ctl_info *mci;
     533                 :          0 :         struct list_head *item;
     534                 :            : 
     535                 :          0 :         edac_dbg(3, "\n");
     536                 :            : 
     537   [ #  #  #  #  :          0 :         list_for_each(item, &mc_devices) {
                   #  # ]
     538                 :          0 :                 mci = list_entry(item, struct mem_ctl_info, link);
     539                 :            : 
     540   [ #  #  #  #  :          0 :                 if (mci->pdev == dev)
                   #  # ]
     541                 :            :                         return mci;
     542                 :            :         }
     543                 :            : 
     544                 :            :         return NULL;
     545                 :            : }
     546                 :            : 
     547                 :            : /**
     548                 :            :  * find_mci_by_dev
     549                 :            :  *
     550                 :            :  *      scan list of controllers looking for the one that manages
     551                 :            :  *      the 'dev' device
     552                 :            :  * @dev: pointer to a struct device related with the MCI
     553                 :            :  */
     554                 :          0 : struct mem_ctl_info *find_mci_by_dev(struct device *dev)
     555                 :            : {
     556                 :          0 :         struct mem_ctl_info *ret;
     557                 :            : 
     558                 :          0 :         mutex_lock(&mem_ctls_mutex);
     559                 :          0 :         ret = __find_mci_by_dev(dev);
     560                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     561                 :            : 
     562                 :          0 :         return ret;
     563                 :            : }
     564                 :            : EXPORT_SYMBOL_GPL(find_mci_by_dev);
     565                 :            : 
     566                 :            : /*
     567                 :            :  * edac_mc_workq_function
     568                 :            :  *      performs the operation scheduled by a workq request
     569                 :            :  */
     570                 :          0 : static void edac_mc_workq_function(struct work_struct *work_req)
     571                 :            : {
     572                 :          0 :         struct delayed_work *d_work = to_delayed_work(work_req);
     573                 :          0 :         struct mem_ctl_info *mci = to_edac_mem_ctl_work(d_work);
     574                 :            : 
     575                 :          0 :         mutex_lock(&mem_ctls_mutex);
     576                 :            : 
     577         [ #  # ]:          0 :         if (mci->op_state != OP_RUNNING_POLL) {
     578                 :          0 :                 mutex_unlock(&mem_ctls_mutex);
     579                 :          0 :                 return;
     580                 :            :         }
     581                 :            : 
     582         [ #  # ]:          0 :         if (edac_op_state == EDAC_OPSTATE_POLL)
     583                 :          0 :                 mci->edac_check(mci);
     584                 :            : 
     585                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     586                 :            : 
     587                 :            :         /* Queue ourselves again. */
     588                 :          0 :         edac_queue_work(&mci->work, msecs_to_jiffies(edac_mc_get_poll_msec()));
     589                 :            : }
     590                 :            : 
     591                 :            : /*
     592                 :            :  * edac_mc_reset_delay_period(unsigned long value)
     593                 :            :  *
     594                 :            :  *      user space has updated our poll period value, need to
     595                 :            :  *      reset our workq delays
     596                 :            :  */
     597                 :          0 : void edac_mc_reset_delay_period(unsigned long value)
     598                 :            : {
     599                 :          0 :         struct mem_ctl_info *mci;
     600                 :          0 :         struct list_head *item;
     601                 :            : 
     602                 :          0 :         mutex_lock(&mem_ctls_mutex);
     603                 :            : 
     604         [ #  # ]:          0 :         list_for_each(item, &mc_devices) {
     605                 :          0 :                 mci = list_entry(item, struct mem_ctl_info, link);
     606                 :            : 
     607         [ #  # ]:          0 :                 if (mci->op_state == OP_RUNNING_POLL)
     608                 :          0 :                         edac_mod_work(&mci->work, value);
     609                 :            :         }
     610                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     611                 :          0 : }
     612                 :            : 
     613                 :            : 
     614                 :            : 
     615                 :            : /* Return 0 on success, 1 on failure.
     616                 :            :  * Before calling this function, caller must
     617                 :            :  * assign a unique value to mci->mc_idx.
     618                 :            :  *
     619                 :            :  *      locking model:
     620                 :            :  *
     621                 :            :  *              called with the mem_ctls_mutex lock held
     622                 :            :  */
     623                 :          0 : static int add_mc_to_global_list(struct mem_ctl_info *mci)
     624                 :            : {
     625                 :          0 :         struct list_head *item, *insert_before;
     626                 :          0 :         struct mem_ctl_info *p;
     627                 :            : 
     628                 :          0 :         insert_before = &mc_devices;
     629                 :            : 
     630                 :          0 :         p = __find_mci_by_dev(mci->pdev);
     631         [ #  # ]:          0 :         if (unlikely(p != NULL))
     632                 :          0 :                 goto fail0;
     633                 :            : 
     634         [ #  # ]:          0 :         list_for_each(item, &mc_devices) {
     635                 :          0 :                 p = list_entry(item, struct mem_ctl_info, link);
     636                 :            : 
     637         [ #  # ]:          0 :                 if (p->mc_idx >= mci->mc_idx) {
     638         [ #  # ]:          0 :                         if (unlikely(p->mc_idx == mci->mc_idx))
     639                 :          0 :                                 goto fail1;
     640                 :            : 
     641                 :            :                         insert_before = item;
     642                 :            :                         break;
     643                 :            :                 }
     644                 :            :         }
     645                 :            : 
     646                 :          0 :         list_add_tail_rcu(&mci->link, insert_before);
     647                 :          0 :         return 0;
     648                 :            : 
     649                 :            : fail0:
     650         [ #  # ]:          0 :         edac_printk(KERN_WARNING, EDAC_MC,
     651                 :            :                 "%s (%s) %s %s already assigned %d\n", dev_name(p->pdev),
     652                 :            :                 edac_dev_name(mci), p->mod_name, p->ctl_name, p->mc_idx);
     653                 :          0 :         return 1;
     654                 :            : 
     655                 :            : fail1:
     656                 :          0 :         edac_printk(KERN_WARNING, EDAC_MC,
     657                 :            :                 "bug in low-level driver: attempt to assign\n"
     658                 :            :                 "    duplicate mc_idx %d in %s()\n", p->mc_idx, __func__);
     659                 :          0 :         return 1;
     660                 :            : }
     661                 :            : 
     662                 :          0 : static int del_mc_from_global_list(struct mem_ctl_info *mci)
     663                 :            : {
     664                 :          0 :         list_del_rcu(&mci->link);
     665                 :            : 
     666                 :            :         /* these are for safe removal of devices from global list while
     667                 :            :          * NMI handlers may be traversing list
     668                 :            :          */
     669                 :          0 :         synchronize_rcu();
     670         [ #  # ]:          0 :         INIT_LIST_HEAD(&mci->link);
     671                 :            : 
     672         [ #  # ]:          0 :         return list_empty(&mc_devices);
     673                 :            : }
     674                 :            : 
     675                 :          0 : struct mem_ctl_info *edac_mc_find(int idx)
     676                 :            : {
     677                 :          0 :         struct mem_ctl_info *mci;
     678                 :          0 :         struct list_head *item;
     679                 :            : 
     680                 :          0 :         mutex_lock(&mem_ctls_mutex);
     681                 :            : 
     682         [ #  # ]:          0 :         list_for_each(item, &mc_devices) {
     683                 :          0 :                 mci = list_entry(item, struct mem_ctl_info, link);
     684         [ #  # ]:          0 :                 if (mci->mc_idx == idx)
     685                 :          0 :                         goto unlock;
     686                 :            :         }
     687                 :            : 
     688                 :            :         mci = NULL;
     689                 :          0 : unlock:
     690                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     691                 :          0 :         return mci;
     692                 :            : }
     693                 :            : EXPORT_SYMBOL(edac_mc_find);
     694                 :            : 
     695                 :          0 : const char *edac_get_owner(void)
     696                 :            : {
     697                 :          0 :         return edac_mc_owner;
     698                 :            : }
     699                 :            : EXPORT_SYMBOL_GPL(edac_get_owner);
     700                 :            : 
     701                 :            : /* FIXME - should a warning be printed if no error detection? correction? */
     702                 :          0 : int edac_mc_add_mc_with_groups(struct mem_ctl_info *mci,
     703                 :            :                                const struct attribute_group **groups)
     704                 :            : {
     705                 :          0 :         int ret = -EINVAL;
     706                 :          0 :         edac_dbg(0, "\n");
     707                 :            : 
     708                 :            : #ifdef CONFIG_EDAC_DEBUG
     709                 :            :         if (edac_debug_level >= 3)
     710                 :            :                 edac_mc_dump_mci(mci);
     711                 :            : 
     712                 :            :         if (edac_debug_level >= 4) {
     713                 :            :                 struct dimm_info *dimm;
     714                 :            :                 int i;
     715                 :            : 
     716                 :            :                 for (i = 0; i < mci->nr_csrows; i++) {
     717                 :            :                         struct csrow_info *csrow = mci->csrows[i];
     718                 :            :                         u32 nr_pages = 0;
     719                 :            :                         int j;
     720                 :            : 
     721                 :            :                         for (j = 0; j < csrow->nr_channels; j++)
     722                 :            :                                 nr_pages += csrow->channels[j]->dimm->nr_pages;
     723                 :            :                         if (!nr_pages)
     724                 :            :                                 continue;
     725                 :            :                         edac_mc_dump_csrow(csrow);
     726                 :            :                         for (j = 0; j < csrow->nr_channels; j++)
     727                 :            :                                 if (csrow->channels[j]->dimm->nr_pages)
     728                 :            :                                         edac_mc_dump_channel(csrow->channels[j]);
     729                 :            :                 }
     730                 :            : 
     731                 :            :                 mci_for_each_dimm(mci, dimm)
     732                 :            :                         edac_mc_dump_dimm(dimm);
     733                 :            :         }
     734                 :            : #endif
     735                 :          0 :         mutex_lock(&mem_ctls_mutex);
     736                 :            : 
     737   [ #  #  #  # ]:          0 :         if (edac_mc_owner && edac_mc_owner != mci->mod_name) {
     738                 :          0 :                 ret = -EPERM;
     739                 :          0 :                 goto fail0;
     740                 :            :         }
     741                 :            : 
     742         [ #  # ]:          0 :         if (add_mc_to_global_list(mci))
     743                 :          0 :                 goto fail0;
     744                 :            : 
     745                 :            :         /* set load time so that error rate can be tracked */
     746                 :          0 :         mci->start_time = jiffies;
     747                 :            : 
     748                 :          0 :         mci->bus = edac_get_sysfs_subsys();
     749                 :            : 
     750         [ #  # ]:          0 :         if (edac_create_sysfs_mci_device(mci, groups)) {
     751                 :          0 :                 edac_mc_printk(mci, KERN_WARNING,
     752                 :            :                         "failed to create sysfs device\n");
     753                 :          0 :                 goto fail1;
     754                 :            :         }
     755                 :            : 
     756         [ #  # ]:          0 :         if (mci->edac_check) {
     757                 :          0 :                 mci->op_state = OP_RUNNING_POLL;
     758                 :            : 
     759                 :          0 :                 INIT_DELAYED_WORK(&mci->work, edac_mc_workq_function);
     760                 :          0 :                 edac_queue_work(&mci->work, msecs_to_jiffies(edac_mc_get_poll_msec()));
     761                 :            : 
     762                 :            :         } else {
     763                 :          0 :                 mci->op_state = OP_RUNNING_INTERRUPT;
     764                 :            :         }
     765                 :            : 
     766                 :            :         /* Report action taken */
     767                 :          0 :         edac_mc_printk(mci, KERN_INFO,
     768                 :            :                 "Giving out device to module %s controller %s: DEV %s (%s)\n",
     769                 :            :                 mci->mod_name, mci->ctl_name, mci->dev_name,
     770                 :            :                 edac_op_state_to_string(mci->op_state));
     771                 :            : 
     772                 :          0 :         edac_mc_owner = mci->mod_name;
     773                 :            : 
     774                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     775                 :          0 :         return 0;
     776                 :            : 
     777                 :            : fail1:
     778                 :          0 :         del_mc_from_global_list(mci);
     779                 :            : 
     780                 :          0 : fail0:
     781                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     782                 :          0 :         return ret;
     783                 :            : }
     784                 :            : EXPORT_SYMBOL_GPL(edac_mc_add_mc_with_groups);
     785                 :            : 
     786                 :          0 : struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
     787                 :            : {
     788                 :          0 :         struct mem_ctl_info *mci;
     789                 :            : 
     790                 :          0 :         edac_dbg(0, "\n");
     791                 :            : 
     792                 :          0 :         mutex_lock(&mem_ctls_mutex);
     793                 :            : 
     794                 :            :         /* find the requested mci struct in the global list */
     795                 :          0 :         mci = __find_mci_by_dev(dev);
     796         [ #  # ]:          0 :         if (mci == NULL) {
     797                 :          0 :                 mutex_unlock(&mem_ctls_mutex);
     798                 :          0 :                 return NULL;
     799                 :            :         }
     800                 :            : 
     801                 :            :         /* mark MCI offline: */
     802                 :          0 :         mci->op_state = OP_OFFLINE;
     803                 :            : 
     804         [ #  # ]:          0 :         if (del_mc_from_global_list(mci))
     805                 :          0 :                 edac_mc_owner = NULL;
     806                 :            : 
     807                 :          0 :         mutex_unlock(&mem_ctls_mutex);
     808                 :            : 
     809         [ #  # ]:          0 :         if (mci->edac_check)
     810                 :          0 :                 edac_stop_work(&mci->work);
     811                 :            : 
     812                 :            :         /* remove from sysfs */
     813                 :          0 :         edac_remove_sysfs_mci_device(mci);
     814                 :            : 
     815                 :          0 :         edac_printk(KERN_INFO, EDAC_MC,
     816                 :            :                 "Removed device %d for %s %s: DEV %s\n", mci->mc_idx,
     817                 :            :                 mci->mod_name, mci->ctl_name, edac_dev_name(mci));
     818                 :            : 
     819                 :          0 :         return mci;
     820                 :            : }
     821                 :            : EXPORT_SYMBOL_GPL(edac_mc_del_mc);
     822                 :            : 
     823                 :          0 : static void edac_mc_scrub_block(unsigned long page, unsigned long offset,
     824                 :            :                                 u32 size)
     825                 :            : {
     826                 :          0 :         struct page *pg;
     827                 :          0 :         void *virt_addr;
     828                 :          0 :         unsigned long flags = 0;
     829                 :            : 
     830                 :          0 :         edac_dbg(3, "\n");
     831                 :            : 
     832                 :            :         /* ECC error page was not in our memory. Ignore it. */
     833         [ #  # ]:          0 :         if (!pfn_valid(page))
     834                 :            :                 return;
     835                 :            : 
     836                 :            :         /* Find the actual page structure then map it and fix */
     837                 :          0 :         pg = pfn_to_page(page);
     838                 :            : 
     839                 :          0 :         if (PageHighMem(pg))
     840                 :          0 :                 local_irq_save(flags);
     841                 :            : 
     842                 :          0 :         virt_addr = kmap_atomic(pg);
     843                 :            : 
     844                 :            :         /* Perform architecture specific atomic scrub operation */
     845                 :          0 :         edac_atomic_scrub(virt_addr + offset, size);
     846                 :            : 
     847                 :            :         /* Unmap and complete */
     848                 :          0 :         kunmap_atomic(virt_addr);
     849                 :            : 
     850                 :          0 :         if (PageHighMem(pg))
     851                 :          0 :                 local_irq_restore(flags);
     852                 :            : }
     853                 :            : 
     854                 :            : /* FIXME - should return -1 */
     855                 :          0 : int edac_mc_find_csrow_by_page(struct mem_ctl_info *mci, unsigned long page)
     856                 :            : {
     857                 :          0 :         struct csrow_info **csrows = mci->csrows;
     858                 :          0 :         int row, i, j, n;
     859                 :            : 
     860                 :          0 :         edac_dbg(1, "MC%d: 0x%lx\n", mci->mc_idx, page);
     861                 :          0 :         row = -1;
     862                 :            : 
     863         [ #  # ]:          0 :         for (i = 0; i < mci->nr_csrows; i++) {
     864                 :          0 :                 struct csrow_info *csrow = csrows[i];
     865                 :          0 :                 n = 0;
     866         [ #  # ]:          0 :                 for (j = 0; j < csrow->nr_channels; j++) {
     867                 :          0 :                         struct dimm_info *dimm = csrow->channels[j]->dimm;
     868                 :          0 :                         n += dimm->nr_pages;
     869                 :            :                 }
     870         [ #  # ]:          0 :                 if (n == 0)
     871                 :          0 :                         continue;
     872                 :            : 
     873                 :          0 :                 edac_dbg(3, "MC%d: first(0x%lx) page(0x%lx) last(0x%lx) mask(0x%lx)\n",
     874                 :            :                          mci->mc_idx,
     875                 :            :                          csrow->first_page, page, csrow->last_page,
     876                 :            :                          csrow->page_mask);
     877                 :            : 
     878         [ #  # ]:          0 :                 if ((page >= csrow->first_page) &&
     879         [ #  # ]:          0 :                     (page <= csrow->last_page) &&
     880         [ #  # ]:          0 :                     ((page & csrow->page_mask) ==
     881                 :            :                      (csrow->first_page & csrow->page_mask))) {
     882                 :            :                         row = i;
     883                 :            :                         break;
     884                 :            :                 }
     885                 :            :         }
     886                 :            : 
     887         [ #  # ]:          0 :         if (row == -1)
     888                 :          0 :                 edac_mc_printk(mci, KERN_ERR,
     889                 :            :                         "could not look up page error address %lx\n",
     890                 :            :                         (unsigned long)page);
     891                 :            : 
     892                 :          0 :         return row;
     893                 :            : }
     894                 :            : EXPORT_SYMBOL_GPL(edac_mc_find_csrow_by_page);
     895                 :            : 
     896                 :            : const char *edac_layer_name[] = {
     897                 :            :         [EDAC_MC_LAYER_BRANCH] = "branch",
     898                 :            :         [EDAC_MC_LAYER_CHANNEL] = "channel",
     899                 :            :         [EDAC_MC_LAYER_SLOT] = "slot",
     900                 :            :         [EDAC_MC_LAYER_CHIP_SELECT] = "csrow",
     901                 :            :         [EDAC_MC_LAYER_ALL_MEM] = "memory",
     902                 :            : };
     903                 :            : EXPORT_SYMBOL_GPL(edac_layer_name);
     904                 :            : 
     905                 :          0 : static void edac_inc_ce_error(struct mem_ctl_info *mci,
     906                 :            :                               bool enable_per_layer_report,
     907                 :            :                               const int pos[EDAC_MAX_LAYERS],
     908                 :            :                               const u16 count)
     909                 :            : {
     910                 :          0 :         int i, index = 0;
     911                 :            : 
     912                 :          0 :         mci->ce_mc += count;
     913                 :            : 
     914         [ #  # ]:          0 :         if (!enable_per_layer_report) {
     915                 :          0 :                 mci->ce_noinfo_count += count;
     916                 :          0 :                 return;
     917                 :            :         }
     918                 :            : 
     919         [ #  # ]:          0 :         for (i = 0; i < mci->n_layers; i++) {
     920         [ #  # ]:          0 :                 if (pos[i] < 0)
     921                 :            :                         break;
     922                 :          0 :                 index += pos[i];
     923                 :          0 :                 mci->ce_per_layer[i][index] += count;
     924                 :            : 
     925         [ #  # ]:          0 :                 if (i < mci->n_layers - 1)
     926                 :          0 :                         index *= mci->layers[i + 1].size;
     927                 :            :         }
     928                 :            : }
     929                 :            : 
     930                 :          0 : static void edac_inc_ue_error(struct mem_ctl_info *mci,
     931                 :            :                                     bool enable_per_layer_report,
     932                 :            :                                     const int pos[EDAC_MAX_LAYERS],
     933                 :            :                                     const u16 count)
     934                 :            : {
     935                 :          0 :         int i, index = 0;
     936                 :            : 
     937                 :          0 :         mci->ue_mc += count;
     938                 :            : 
     939         [ #  # ]:          0 :         if (!enable_per_layer_report) {
     940                 :          0 :                 mci->ue_noinfo_count += count;
     941                 :          0 :                 return;
     942                 :            :         }
     943                 :            : 
     944         [ #  # ]:          0 :         for (i = 0; i < mci->n_layers; i++) {
     945         [ #  # ]:          0 :                 if (pos[i] < 0)
     946                 :            :                         break;
     947                 :          0 :                 index += pos[i];
     948                 :          0 :                 mci->ue_per_layer[i][index] += count;
     949                 :            : 
     950         [ #  # ]:          0 :                 if (i < mci->n_layers - 1)
     951                 :          0 :                         index *= mci->layers[i + 1].size;
     952                 :            :         }
     953                 :            : }
     954                 :            : 
     955                 :          0 : static void edac_ce_error(struct mem_ctl_info *mci,
     956                 :            :                           const u16 error_count,
     957                 :            :                           const int pos[EDAC_MAX_LAYERS],
     958                 :            :                           const char *msg,
     959                 :            :                           const char *location,
     960                 :            :                           const char *label,
     961                 :            :                           const char *detail,
     962                 :            :                           const char *other_detail,
     963                 :            :                           const bool enable_per_layer_report,
     964                 :            :                           const unsigned long page_frame_number,
     965                 :            :                           const unsigned long offset_in_page,
     966                 :            :                           long grain)
     967                 :            : {
     968                 :          0 :         unsigned long remapped_page;
     969                 :          0 :         char *msg_aux = "";
     970                 :            : 
     971         [ #  # ]:          0 :         if (*msg)
     972                 :          0 :                 msg_aux = " ";
     973                 :            : 
     974         [ #  # ]:          0 :         if (edac_mc_get_log_ce()) {
     975   [ #  #  #  # ]:          0 :                 if (other_detail && *other_detail)
     976                 :          0 :                         edac_mc_printk(mci, KERN_WARNING,
     977                 :            :                                        "%d CE %s%son %s (%s %s - %s)\n",
     978                 :            :                                        error_count, msg, msg_aux, label,
     979                 :            :                                        location, detail, other_detail);
     980                 :            :                 else
     981                 :          0 :                         edac_mc_printk(mci, KERN_WARNING,
     982                 :            :                                        "%d CE %s%son %s (%s %s)\n",
     983                 :            :                                        error_count, msg, msg_aux, label,
     984                 :            :                                        location, detail);
     985                 :            :         }
     986                 :          0 :         edac_inc_ce_error(mci, enable_per_layer_report, pos, error_count);
     987                 :            : 
     988         [ #  # ]:          0 :         if (mci->scrub_mode == SCRUB_SW_SRC) {
     989                 :            :                 /*
     990                 :            :                         * Some memory controllers (called MCs below) can remap
     991                 :            :                         * memory so that it is still available at a different
     992                 :            :                         * address when PCI devices map into memory.
     993                 :            :                         * MC's that can't do this, lose the memory where PCI
     994                 :            :                         * devices are mapped. This mapping is MC-dependent
     995                 :            :                         * and so we call back into the MC driver for it to
     996                 :            :                         * map the MC page to a physical (CPU) page which can
     997                 :            :                         * then be mapped to a virtual page - which can then
     998                 :            :                         * be scrubbed.
     999                 :            :                         */
    1000                 :          0 :                 remapped_page = mci->ctl_page_to_phys ?
    1001         [ #  # ]:          0 :                         mci->ctl_page_to_phys(mci, page_frame_number) :
    1002                 :            :                         page_frame_number;
    1003                 :            : 
    1004                 :          0 :                 edac_mc_scrub_block(remapped_page,
    1005                 :            :                                         offset_in_page, grain);
    1006                 :            :         }
    1007                 :          0 : }
    1008                 :            : 
    1009                 :          0 : static void edac_ue_error(struct mem_ctl_info *mci,
    1010                 :            :                           const u16 error_count,
    1011                 :            :                           const int pos[EDAC_MAX_LAYERS],
    1012                 :            :                           const char *msg,
    1013                 :            :                           const char *location,
    1014                 :            :                           const char *label,
    1015                 :            :                           const char *detail,
    1016                 :            :                           const char *other_detail,
    1017                 :            :                           const bool enable_per_layer_report)
    1018                 :            : {
    1019                 :          0 :         char *msg_aux = "";
    1020                 :            : 
    1021         [ #  # ]:          0 :         if (*msg)
    1022                 :          0 :                 msg_aux = " ";
    1023                 :            : 
    1024         [ #  # ]:          0 :         if (edac_mc_get_log_ue()) {
    1025   [ #  #  #  # ]:          0 :                 if (other_detail && *other_detail)
    1026                 :          0 :                         edac_mc_printk(mci, KERN_WARNING,
    1027                 :            :                                        "%d UE %s%son %s (%s %s - %s)\n",
    1028                 :            :                                        error_count, msg, msg_aux, label,
    1029                 :            :                                        location, detail, other_detail);
    1030                 :            :                 else
    1031                 :          0 :                         edac_mc_printk(mci, KERN_WARNING,
    1032                 :            :                                        "%d UE %s%son %s (%s %s)\n",
    1033                 :            :                                        error_count, msg, msg_aux, label,
    1034                 :            :                                        location, detail);
    1035                 :            :         }
    1036                 :            : 
    1037         [ #  # ]:          0 :         if (edac_mc_get_panic_on_ue()) {
    1038   [ #  #  #  # ]:          0 :                 if (other_detail && *other_detail)
    1039                 :          0 :                         panic("UE %s%son %s (%s%s - %s)\n",
    1040                 :            :                               msg, msg_aux, label, location, detail, other_detail);
    1041                 :            :                 else
    1042                 :          0 :                         panic("UE %s%son %s (%s%s)\n",
    1043                 :            :                               msg, msg_aux, label, location, detail);
    1044                 :            :         }
    1045                 :            : 
    1046                 :          0 :         edac_inc_ue_error(mci, enable_per_layer_report, pos, error_count);
    1047                 :          0 : }
    1048                 :            : 
    1049                 :          0 : void edac_raw_mc_handle_error(const enum hw_event_mc_err_type type,
    1050                 :            :                               struct mem_ctl_info *mci,
    1051                 :            :                               struct edac_raw_error_desc *e)
    1052                 :            : {
    1053                 :          0 :         char detail[80];
    1054                 :          0 :         int pos[EDAC_MAX_LAYERS] = { e->top_layer, e->mid_layer, e->low_layer };
    1055                 :          0 :         u8 grain_bits;
    1056                 :            : 
    1057                 :            :         /* Sanity-check driver-supplied grain value. */
    1058   [ #  #  #  # ]:          0 :         if (WARN_ON_ONCE(!e->grain))
    1059                 :          0 :                 e->grain = 1;
    1060                 :            : 
    1061                 :          0 :         grain_bits = fls_long(e->grain - 1);
    1062                 :            : 
    1063                 :            :         /* Report the error via the trace interface */
    1064                 :          0 :         if (IS_ENABLED(CONFIG_RAS))
    1065                 :          0 :                 trace_mc_event(type, e->msg, e->label, e->error_count,
    1066                 :          0 :                                mci->mc_idx, e->top_layer, e->mid_layer,
    1067                 :            :                                e->low_layer,
    1068                 :          0 :                                (e->page_frame_number << PAGE_SHIFT) | e->offset_in_page,
    1069                 :            :                                grain_bits, e->syndrome, e->other_detail);
    1070                 :            : 
    1071                 :            :         /* Memory type dependent details about the error */
    1072         [ #  # ]:          0 :         if (type == HW_EVENT_ERR_CORRECTED) {
    1073                 :          0 :                 snprintf(detail, sizeof(detail),
    1074                 :            :                         "page:0x%lx offset:0x%lx grain:%ld syndrome:0x%lx",
    1075                 :            :                         e->page_frame_number, e->offset_in_page,
    1076                 :            :                         e->grain, e->syndrome);
    1077                 :          0 :                 edac_ce_error(mci, e->error_count, pos, e->msg, e->location, e->label,
    1078                 :          0 :                               detail, e->other_detail, e->enable_per_layer_report,
    1079                 :            :                               e->page_frame_number, e->offset_in_page, e->grain);
    1080                 :            :         } else {
    1081                 :          0 :                 snprintf(detail, sizeof(detail),
    1082                 :            :                         "page:0x%lx offset:0x%lx grain:%ld",
    1083                 :            :                         e->page_frame_number, e->offset_in_page, e->grain);
    1084                 :            : 
    1085                 :          0 :                 edac_ue_error(mci, e->error_count, pos, e->msg, e->location, e->label,
    1086                 :          0 :                               detail, e->other_detail, e->enable_per_layer_report);
    1087                 :            :         }
    1088                 :            : 
    1089                 :            : 
    1090                 :          0 : }
    1091                 :            : EXPORT_SYMBOL_GPL(edac_raw_mc_handle_error);
    1092                 :            : 
    1093                 :          0 : void edac_mc_handle_error(const enum hw_event_mc_err_type type,
    1094                 :            :                           struct mem_ctl_info *mci,
    1095                 :            :                           const u16 error_count,
    1096                 :            :                           const unsigned long page_frame_number,
    1097                 :            :                           const unsigned long offset_in_page,
    1098                 :            :                           const unsigned long syndrome,
    1099                 :            :                           const int top_layer,
    1100                 :            :                           const int mid_layer,
    1101                 :            :                           const int low_layer,
    1102                 :            :                           const char *msg,
    1103                 :            :                           const char *other_detail)
    1104                 :            : {
    1105                 :          0 :         struct dimm_info *dimm;
    1106                 :          0 :         char *p;
    1107                 :          0 :         int row = -1, chan = -1;
    1108                 :          0 :         int pos[EDAC_MAX_LAYERS] = { top_layer, mid_layer, low_layer };
    1109                 :          0 :         int i, n_labels = 0;
    1110                 :          0 :         struct edac_raw_error_desc *e = &mci->error_desc;
    1111                 :            : 
    1112                 :          0 :         edac_dbg(3, "MC%d\n", mci->mc_idx);
    1113                 :            : 
    1114                 :            :         /* Fills the error report buffer */
    1115                 :          0 :         memset(e, 0, sizeof (*e));
    1116                 :          0 :         e->error_count = error_count;
    1117                 :          0 :         e->top_layer = top_layer;
    1118                 :          0 :         e->mid_layer = mid_layer;
    1119                 :          0 :         e->low_layer = low_layer;
    1120                 :          0 :         e->page_frame_number = page_frame_number;
    1121                 :          0 :         e->offset_in_page = offset_in_page;
    1122                 :          0 :         e->syndrome = syndrome;
    1123                 :          0 :         e->msg = msg;
    1124                 :          0 :         e->other_detail = other_detail;
    1125                 :            : 
    1126                 :            :         /*
    1127                 :            :          * Check if the event report is consistent and if the memory
    1128                 :            :          * location is known. If it is known, enable_per_layer_report will be
    1129                 :            :          * true, the DIMM(s) label info will be filled and the per-layer
    1130                 :            :          * error counters will be incremented.
    1131                 :            :          */
    1132         [ #  # ]:          0 :         for (i = 0; i < mci->n_layers; i++) {
    1133         [ #  # ]:          0 :                 if (pos[i] >= (int)mci->layers[i].size) {
    1134                 :            : 
    1135                 :          0 :                         edac_mc_printk(mci, KERN_ERR,
    1136                 :            :                                        "INTERNAL ERROR: %s value is out of range (%d >= %d)\n",
    1137                 :            :                                        edac_layer_name[mci->layers[i].type],
    1138                 :            :                                        pos[i], mci->layers[i].size);
    1139                 :            :                         /*
    1140                 :            :                          * Instead of just returning it, let's use what's
    1141                 :            :                          * known about the error. The increment routines and
    1142                 :            :                          * the DIMM filter logic will do the right thing by
    1143                 :            :                          * pointing the likely damaged DIMMs.
    1144                 :            :                          */
    1145                 :          0 :                         pos[i] = -1;
    1146                 :            :                 }
    1147         [ #  # ]:          0 :                 if (pos[i] >= 0)
    1148                 :          0 :                         e->enable_per_layer_report = true;
    1149                 :            :         }
    1150                 :            : 
    1151                 :            :         /*
    1152                 :            :          * Get the dimm label/grain that applies to the match criteria.
    1153                 :            :          * As the error algorithm may not be able to point to just one memory
    1154                 :            :          * stick, the logic here will get all possible labels that could
    1155                 :            :          * pottentially be affected by the error.
    1156                 :            :          * On FB-DIMM memory controllers, for uncorrected errors, it is common
    1157                 :            :          * to have only the MC channel and the MC dimm (also called "branch")
    1158                 :            :          * but the channel is not known, as the memory is arranged in pairs,
    1159                 :            :          * where each memory belongs to a separate channel within the same
    1160                 :            :          * branch.
    1161                 :            :          */
    1162                 :          0 :         p = e->label;
    1163                 :          0 :         *p = '\0';
    1164                 :            : 
    1165   [ #  #  #  # ]:          0 :         mci_for_each_dimm(mci, dimm) {
    1166   [ #  #  #  # ]:          0 :                 if (top_layer >= 0 && top_layer != dimm->location[0])
    1167                 :          0 :                         continue;
    1168   [ #  #  #  # ]:          0 :                 if (mid_layer >= 0 && mid_layer != dimm->location[1])
    1169                 :          0 :                         continue;
    1170   [ #  #  #  # ]:          0 :                 if (low_layer >= 0 && low_layer != dimm->location[2])
    1171                 :          0 :                         continue;
    1172                 :            : 
    1173                 :            :                 /* get the max grain, over the error match range */
    1174         [ #  # ]:          0 :                 if (dimm->grain > e->grain)
    1175                 :          0 :                         e->grain = dimm->grain;
    1176                 :            : 
    1177                 :            :                 /*
    1178                 :            :                  * If the error is memory-controller wide, there's no need to
    1179                 :            :                  * seek for the affected DIMMs because the whole
    1180                 :            :                  * channel/memory controller/...  may be affected.
    1181                 :            :                  * Also, don't show errors for empty DIMM slots.
    1182                 :            :                  */
    1183   [ #  #  #  # ]:          0 :                 if (!e->enable_per_layer_report || !dimm->nr_pages)
    1184                 :          0 :                         continue;
    1185                 :            : 
    1186         [ #  # ]:          0 :                 if (n_labels >= EDAC_MAX_LABELS) {
    1187                 :          0 :                         e->enable_per_layer_report = false;
    1188                 :          0 :                         break;
    1189                 :            :                 }
    1190                 :          0 :                 n_labels++;
    1191         [ #  # ]:          0 :                 if (p != e->label) {
    1192                 :          0 :                         strcpy(p, OTHER_LABEL);
    1193                 :          0 :                         p += strlen(OTHER_LABEL);
    1194                 :            :                 }
    1195                 :          0 :                 strcpy(p, dimm->label);
    1196                 :          0 :                 p += strlen(p);
    1197                 :            : 
    1198                 :            :                 /*
    1199                 :            :                  * get csrow/channel of the DIMM, in order to allow
    1200                 :            :                  * incrementing the compat API counters
    1201                 :            :                  */
    1202                 :          0 :                 edac_dbg(4, "%s csrows map: (%d,%d)\n",
    1203                 :            :                         mci->csbased ? "rank" : "dimm",
    1204                 :            :                         dimm->csrow, dimm->cschannel);
    1205         [ #  # ]:          0 :                 if (row == -1)
    1206                 :          0 :                         row = dimm->csrow;
    1207   [ #  #  #  # ]:          0 :                 else if (row >= 0 && row != dimm->csrow)
    1208                 :          0 :                         row = -2;
    1209                 :            : 
    1210         [ #  # ]:          0 :                 if (chan == -1)
    1211                 :          0 :                         chan = dimm->cschannel;
    1212   [ #  #  #  # ]:          0 :                 else if (chan >= 0 && chan != dimm->cschannel)
    1213                 :          0 :                         chan = -2;
    1214                 :            :         }
    1215                 :            : 
    1216         [ #  # ]:          0 :         if (!e->enable_per_layer_report) {
    1217                 :          0 :                 strcpy(e->label, "any memory");
    1218                 :            :         } else {
    1219                 :          0 :                 edac_dbg(4, "csrow/channel to increment: (%d,%d)\n", row, chan);
    1220         [ #  # ]:          0 :                 if (p == e->label)
    1221                 :          0 :                         strcpy(e->label, "unknown memory");
    1222         [ #  # ]:          0 :                 if (type == HW_EVENT_ERR_CORRECTED) {
    1223         [ #  # ]:          0 :                         if (row >= 0) {
    1224                 :          0 :                                 mci->csrows[row]->ce_count += error_count;
    1225         [ #  # ]:          0 :                                 if (chan >= 0)
    1226                 :          0 :                                         mci->csrows[row]->channels[chan]->ce_count += error_count;
    1227                 :            :                         }
    1228                 :            :                 } else
    1229         [ #  # ]:          0 :                         if (row >= 0)
    1230                 :          0 :                                 mci->csrows[row]->ue_count += error_count;
    1231                 :            :         }
    1232                 :            : 
    1233                 :            :         /* Fill the RAM location data */
    1234                 :          0 :         p = e->location;
    1235                 :            : 
    1236         [ #  # ]:          0 :         for (i = 0; i < mci->n_layers; i++) {
    1237         [ #  # ]:          0 :                 if (pos[i] < 0)
    1238                 :          0 :                         continue;
    1239                 :            : 
    1240                 :          0 :                 p += sprintf(p, "%s:%d ",
    1241                 :          0 :                              edac_layer_name[mci->layers[i].type],
    1242                 :            :                              pos[i]);
    1243                 :            :         }
    1244         [ #  # ]:          0 :         if (p > e->location)
    1245                 :          0 :                 *(p - 1) = '\0';
    1246                 :            : 
    1247                 :          0 :         edac_raw_mc_handle_error(type, mci, e);
    1248                 :          0 : }
    1249                 :            : EXPORT_SYMBOL_GPL(edac_mc_handle_error);

Generated by: LCOV version 1.14