Print this page
    
10082 intel_nhm is checking for NULL arrays
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/intel/io/intel_nhm/dimm_topo.c
          +++ new/usr/src/uts/intel/io/intel_nhm/dimm_topo.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  
    | 
      ↓ open down ↓ | 
    16 lines elided | 
    
      ↑ open up ↑ | 
  
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
       27 +/*
       28 + * Copyright (c) 2018, Joyent, Inc.
       29 + */
       30 +
  27   31  #include <sys/types.h>
  28   32  #include <sys/time.h>
  29   33  #include <sys/nvpair.h>
  30   34  #include <sys/cmn_err.h>
  31   35  #include <sys/cred.h>
  32   36  #include <sys/open.h>
  33   37  #include <sys/ddi.h>
  34   38  #include <sys/sunddi.h>
  35   39  #include <sys/conf.h>
  36   40  #include <sys/modctl.h>
  37   41  #include <sys/cyclic.h>
  38   42  #include <sys/errorq.h>
  39   43  #include <sys/stat.h>
  40   44  #include <sys/cpuvar.h>
  41   45  #include <sys/mc_intel.h>
  42   46  #include <sys/mc.h>
  43   47  #include <sys/fm/protocol.h>
  44   48  #include "nhm_log.h"
  45   49  #include "intel_nhm.h"
  46   50  
  47   51  extern nvlist_t *inhm_mc_nvl[MAX_CPU_NODES];
  48   52  extern char closed_page;
  49   53  extern char ecc_enabled;
  50   54  extern char lockstep[MAX_CPU_NODES];
  51   55  extern char mirror_mode[MAX_CPU_NODES];
  52   56  extern char spare_channel[MAX_CPU_NODES];
  53   57  
  54   58  static void
  55   59  inhm_vrank(nvlist_t *vrank, int num, uint64_t dimm_base, uint64_t limit,
  56   60      uint32_t sinterleave, uint32_t cinterleave, uint32_t rinterleave,
  57   61      uint32_t sway, uint32_t cway, uint32_t rway)
  58   62  {
  59   63          char buf[128];
  60   64  
  61   65          (void) snprintf(buf, sizeof (buf), "dimm-rank-base-%d", num);
  62   66          (void) nvlist_add_uint64(vrank, buf, dimm_base);
  63   67          (void) snprintf(buf, sizeof (buf), "dimm-rank-limit-%d", num);
  64   68          (void) nvlist_add_uint64(vrank, buf, dimm_base + limit);
  65   69          if (sinterleave > 1) {
  66   70                  (void) snprintf(buf, sizeof (buf), "dimm-socket-interleave-%d",
  67   71                      num);
  68   72                  (void) nvlist_add_uint32(vrank, buf, sinterleave);
  69   73                  (void) snprintf(buf, sizeof (buf),
  70   74                      "dimm-socket-interleave-way-%d", num);
  71   75                  (void) nvlist_add_uint32(vrank, buf, sway);
  72   76          }
  73   77          if (cinterleave > 1) {
  74   78                  (void) snprintf(buf, sizeof (buf), "dimm-channel-interleave-%d",
  75   79                      num);
  76   80                  (void) nvlist_add_uint32(vrank, buf, cinterleave);
  77   81                  (void) snprintf(buf, sizeof (buf),
  78   82                      "dimm-channel-interleave-way-%d", num);
  79   83                  (void) nvlist_add_uint32(vrank, buf, cway);
  80   84          }
  81   85          if (rinterleave > 1) {
  82   86                  (void) snprintf(buf, sizeof (buf), "dimm-rank-interleave-%d",
  83   87                      num);
  84   88                  (void) nvlist_add_uint32(vrank, buf, rinterleave);
  85   89                  (void) snprintf(buf, sizeof (buf),
  86   90                      "dimm-rank-interleave-way-%d", num);
  87   91                  (void) nvlist_add_uint32(vrank, buf, rway);
  88   92          }
  89   93  }
  90   94  
  91   95  static void
  92   96  inhm_rank(nvlist_t *newdimm, nhm_dimm_t *nhm_dimm, uint32_t node,
  93   97      uint8_t channel, uint32_t dimm, uint64_t rank_size)
  94   98  {
  95   99          nvlist_t **newrank;
  96  100          int num;
  97  101          int i;
  98  102          uint64_t dimm_base;
  99  103          uint64_t vrank_sz;
 100  104          uint64_t rank_addr;
 101  105          uint64_t pa;
 102  106          uint32_t sinterleave, cinterleave, rinterleave;
 103  107          uint32_t sway, cway, rway;
 104  108  
 105  109          newrank = kmem_zalloc(sizeof (nvlist_t *) * nhm_dimm->nranks, KM_SLEEP);
 106  110          for (i = 0; i < nhm_dimm->nranks; i++) {
 107  111                  (void) nvlist_alloc(&newrank[i], NV_UNIQUE_NAME, KM_SLEEP);
 108  112                  rank_addr = 0;
 109  113                  num = 0;
 110  114                  while (rank_addr < rank_size) {
 111  115                          pa = dimm_to_addr(node, channel, dimm * 4 + i,
 112  116                              rank_addr, &dimm_base, &vrank_sz, &sinterleave,
 113  117                              &cinterleave, &rinterleave, &sway, &cway, &rway);
 114  118                          if (pa == -1 || vrank_sz == 0)
 115  119                                  break;
 116  120                          inhm_vrank(newrank[i], num, dimm_base,
 117  121                              vrank_sz * sinterleave * cinterleave * rinterleave,
 118  122                              sinterleave, cinterleave, rinterleave, sway, cway,
 119  123                              rway);
 120  124                          rank_addr += vrank_sz;
 121  125                          num++;
 122  126                  }
 123  127  
 124  128          }
 125  129          (void) nvlist_add_nvlist_array(newdimm, MCINTEL_NVLIST_RANKS, newrank,
 126  130              nhm_dimm->nranks);
 127  131          for (i = 0; i < nhm_dimm->nranks; i++)
 128  132                  nvlist_free(newrank[i]);
 129  133          kmem_free(newrank, sizeof (nvlist_t *) * nhm_dimm->nranks);
 130  134  }
 131  135  
 132  136  static nvlist_t *
 133  137  inhm_dimm(nhm_dimm_t *nhm_dimm, uint32_t node, uint8_t channel, uint32_t dimm)
 134  138  {
 135  139          nvlist_t *newdimm;
 136  140          uint8_t t;
 137  141          char sbuf[65];
 138  142  
 139  143          (void) nvlist_alloc(&newdimm, NV_UNIQUE_NAME, KM_SLEEP);
 140  144          (void) nvlist_add_uint32(newdimm, "dimm-number", dimm);
 141  145  
 142  146          if (nhm_dimm->dimm_size >= 1024*1024*1024) {
 143  147                  (void) snprintf(sbuf, sizeof (sbuf), "%dG",
 144  148                      (int)(nhm_dimm->dimm_size / (1024*1024*1024)));
 145  149          } else {
 146  150                  (void) snprintf(sbuf, sizeof (sbuf), "%dM",
 147  151                      (int)(nhm_dimm->dimm_size / (1024*1024)));
 148  152          }
  
    | 
      ↓ open down ↓ | 
    112 lines elided | 
    
      ↑ open up ↑ | 
  
 149  153          (void) nvlist_add_string(newdimm, "dimm-size", sbuf);
 150  154          (void) nvlist_add_uint64(newdimm, "size", nhm_dimm->dimm_size);
 151  155          (void) nvlist_add_uint32(newdimm, "nbanks", (uint32_t)nhm_dimm->nbanks);
 152  156          (void) nvlist_add_uint32(newdimm, "ncolumn",
 153  157              (uint32_t)nhm_dimm->ncolumn);
 154  158          (void) nvlist_add_uint32(newdimm, "nrow", (uint32_t)nhm_dimm->nrow);
 155  159          (void) nvlist_add_uint32(newdimm, "width", (uint32_t)nhm_dimm->width);
 156  160          (void) nvlist_add_uint32(newdimm, "ranks", (uint32_t)nhm_dimm->nranks);
 157  161          inhm_rank(newdimm, nhm_dimm, node, channel, dimm,
 158  162              nhm_dimm->dimm_size / nhm_dimm->nranks);
 159      -        if (nhm_dimm->manufacturer && nhm_dimm->manufacturer[0]) {
      163 +        if (nhm_dimm->manufacturer[0]) {
 160  164                  t = sizeof (nhm_dimm->manufacturer);
 161  165                  (void) strncpy(sbuf, nhm_dimm->manufacturer, t);
 162  166                  sbuf[t] = 0;
 163  167                  (void) nvlist_add_string(newdimm, "manufacturer", sbuf);
 164  168          }
 165      -        if (nhm_dimm->serial_number && nhm_dimm->serial_number[0]) {
      169 +        if (nhm_dimm->serial_number[0]) {
 166  170                  t = sizeof (nhm_dimm->serial_number);
 167  171                  (void) strncpy(sbuf, nhm_dimm->serial_number, t);
 168  172                  sbuf[t] = 0;
 169  173                  (void) nvlist_add_string(newdimm, FM_FMRI_HC_SERIAL_ID, sbuf);
 170  174          }
 171      -        if (nhm_dimm->part_number && nhm_dimm->part_number[0]) {
      175 +        if (nhm_dimm->part_number[0]) {
 172  176                  t = sizeof (nhm_dimm->part_number);
 173  177                  (void) strncpy(sbuf, nhm_dimm->part_number, t);
 174  178                  sbuf[t] = 0;
 175  179                  (void) nvlist_add_string(newdimm, FM_FMRI_HC_PART, sbuf);
 176  180          }
 177      -        if (nhm_dimm->revision && nhm_dimm->revision[0]) {
      181 +        if (nhm_dimm->revision[0]) {
 178  182                  t = sizeof (nhm_dimm->revision);
 179  183                  (void) strncpy(sbuf, nhm_dimm->revision, t);
 180  184                  sbuf[t] = 0;
 181  185                  (void) nvlist_add_string(newdimm, FM_FMRI_HC_REVISION, sbuf);
 182  186          }
 183  187          t = sizeof (nhm_dimm->label);
 184  188          (void) strncpy(sbuf, nhm_dimm->label, t);
 185  189          sbuf[t] = 0;
 186  190          (void) nvlist_add_string(newdimm, FM_FAULT_FRU_LABEL, sbuf);
 187  191          return (newdimm);
 188  192  }
 189  193  
 190  194  static void
 191  195  inhm_dimmlist(uint32_t node, nvlist_t *nvl)
 192  196  {
 193  197          nvlist_t **dimmlist;
 194  198          nvlist_t **newchannel;
 195  199          int nchannels = CHANNELS_PER_MEMORY_CONTROLLER;
 196  200          int nd;
 197  201          uint8_t i, j;
 198  202          nhm_dimm_t **dimmpp;
 199  203          nhm_dimm_t *dimmp;
 200  204  
 201  205          dimmlist =  kmem_zalloc(sizeof (nvlist_t *) * MAX_DIMMS_PER_CHANNEL,
 202  206              KM_SLEEP);
 203  207          newchannel = kmem_zalloc(sizeof (nvlist_t *) * nchannels, KM_SLEEP);
 204  208          dimmpp = &nhm_dimms[node * CHANNELS_PER_MEMORY_CONTROLLER *
 205  209              MAX_DIMMS_PER_CHANNEL];
 206  210          (void) nvlist_add_string(nvl, "memory-policy",
 207  211              closed_page ? "closed-page" : "open-page");
 208  212          (void) nvlist_add_string(nvl, "memory-ecc",
 209  213              ecc_enabled ? lockstep[node] ? "x8" : "x4" : "no");
 210  214          for (i = 0; i < nchannels; i++) {
 211  215                  (void) nvlist_alloc(&newchannel[i], NV_UNIQUE_NAME, KM_SLEEP);
 212  216                  (void) nvlist_add_string(newchannel[i], "channel-mode",
 213  217                      CHANNEL_DISABLED(MC_STATUS_RD(node), i) ? "disabled" :
 214  218                      i != 2 && lockstep[node] ? "lockstep" :
 215  219                      i != 2 && mirror_mode[node] ?
 216  220                      REDUNDANCY_LOSS(MC_RAS_STATUS_RD(node)) ?
 217  221                      "redundancy-loss" : "mirror" :
 218  222                      i == 2 && spare_channel[node] &&
 219  223                      !REDUNDANCY_LOSS(MC_RAS_STATUS_RD(node)) ? "spare" :
 220  224                      "independent");
 221  225                  nd = 0;
 222  226                  for (j = 0; j < MAX_DIMMS_PER_CHANNEL; j++) {
 223  227                          dimmp = *dimmpp;
 224  228                          if (dimmp != NULL) {
 225  229                                  dimmlist[nd] = inhm_dimm(dimmp, node, i,
 226  230                                      (uint32_t)j);
 227  231                                  nd++;
 228  232                          }
 229  233                          dimmpp++;
 230  234                  }
 231  235                  if (nd) {
 232  236                          (void) nvlist_add_nvlist_array(newchannel[i],
 233  237                              "memory-dimms", dimmlist, nd);
 234  238                          for (j = 0; j < nd; j++)
 235  239                                  nvlist_free(dimmlist[j]);
 236  240                  }
 237  241          }
 238  242          (void) nvlist_add_nvlist_array(nvl, MCINTEL_NVLIST_MC, newchannel,
 239  243              nchannels);
 240  244          for (i = 0; i < nchannels; i++)
 241  245                  nvlist_free(newchannel[i]);
 242  246          kmem_free(dimmlist, sizeof (nvlist_t *) * MAX_DIMMS_PER_CHANNEL);
 243  247          kmem_free(newchannel, sizeof (nvlist_t *) * nchannels);
 244  248  }
 245  249  
 246  250  char *
 247  251  inhm_mc_name()
 248  252  {
 249  253          return (NHM_INTERCONNECT);
 250  254  }
 251  255  
 252  256  void
 253  257  inhm_create_nvl(int chip)
 254  258  {
 255  259          nvlist_t *nvl;
 256  260  
 257  261          (void) nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
 258  262          (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_VERSTR,
 259  263              MCINTEL_NVLIST_VERS);
 260  264          (void) nvlist_add_string(nvl, MCINTEL_NVLIST_MEM, inhm_mc_name());
 261  265          (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NMEM, 1);
 262  266          (void) nvlist_add_uint8(nvl, MCINTEL_NVLIST_NRANKS, 4);
 263  267          inhm_dimmlist(chip, nvl);
 264  268  
 265  269          nvlist_free(inhm_mc_nvl[chip]);
 266  270          inhm_mc_nvl[chip] = nvl;
 267  271  }
  
    | 
      ↓ open down ↓ | 
    80 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX