Print this page
    
13026 SMB and NFS use the global zone's IDMAP when they shouldn't
Change-Id: I3b5f7bc68bb77764aa7cb59a48dd1740a8387ccf
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c
          +++ new/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.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 2007 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   */
  26   26  
       27 +/*
       28 + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved.
       29 + */
       30 +
  27   31  #include <sys/file.h>
  28   32  #include <sys/sunndi.h>
  29   33  #include <sys/sunddi.h>
  30   34  #include <sys/sunldi.h>
  31   35  #include <io/px/px_regs.h>
  32   36  #include <sys/pci_tools.h>
  33   37  #include <fpc.h>
  34   38  #include <fpc-impl.h>
  35   39  
  36   40  #define CHIP_COMPATIBLE_NAME    "pciex108e,80f0"
  37   41  #define BANK_ADDR_MASK          0x7FFFFF
  38   42  
  39   43  #define OPEN_FLAGS (FREAD | FWRITE)
  40   44  
  41   45  #define PCIE_BANK       0
  42   46  #define JBUS_BANK       1
  43   47  
  44   48  typedef struct px_regs {
  45   49          uint32_t addr_hi;
  46   50          uint32_t addr_lo;
  47   51          uint32_t size_hi;
  48   52          uint32_t size_lo;
  49   53  } px_regs_t;
  50   54  
  51   55  /* There is one of these for every root nexus device found */
  52   56  typedef struct fire4u_specific {
  53   57          char *nodename;
  54   58          uintptr_t jbus_bank_base;
  55   59  } fire4u_specific_t;
  56   60  
  57   61  typedef struct fire_counter_handle_impl {
  58   62          ldi_handle_t devhandle;
  59   63          fire4u_specific_t *devspec; /* Points to proper one for specific dev. */
  60   64  } fire_counter_handle_impl_t;
  61   65  
  62   66  static uint64_t counter_select_offsets[] = {
  63   67          JBC_PERFORMANCE_COUNTER_SELECT,
  64   68          IMU_PERFORMANCE_COUNTER_SELECT,
  65   69          MMU_PERFORMANCE_COUNTER_SELECT,
  66   70          TLU_PERFORMANCE_COUNTER_SELECT,
  67   71          LPU_LINK_PERFORMANCE_COUNTER_SELECT
  68   72  };
  69   73  
  70   74  /*
  71   75   * The following event and offset arrays is organized by grouping in major
  72   76   * order the fire_perfcnt_t register types, and in minor order the register
  73   77   * numbers within that type.
  74   78   */
  75   79  
  76   80  static uint64_t counter_reg_offsets[] = {
  77   81          JBC_PERFORMANCE_COUNTER_ZERO,
  78   82          JBC_PERFORMANCE_COUNTER_ONE,
  79   83          IMU_PERFORMANCE_COUNTER_ZERO,
  80   84          IMU_PERFORMANCE_COUNTER_ONE,
  81   85          MMU_PERFORMANCE_COUNTER_ZERO,
  82   86          MMU_PERFORMANCE_COUNTER_ONE,
  83   87          TLU_PERFORMANCE_COUNTER_ZERO,
  84   88          TLU_PERFORMANCE_COUNTER_ONE,
  85   89          TLU_PERFORMANCE_COUNTER_TWO,
  86   90          LPU_LINK_PERFORMANCE_COUNTER1,
  87   91          LPU_LINK_PERFORMANCE_COUNTER2
  88   92  };
  89   93  
  90   94  /*
  91   95   * Add the following to one of the LPU_LINK_PERFORMANCE_COUNTERx offsets to
  92   96   * write a value to that counter.
  93   97   */
  
    | 
      ↓ open down ↓ | 
    57 lines elided | 
    
      ↑ open up ↑ | 
  
  94   98  #define LPU_LINK_PERFCTR_WRITE_OFFSET   0x8
  95   99  
  96  100  /*
  97  101   * Note that LPU_LINK_PERFORMANCE_COUNTER_CONTROL register is hard-reset to
  98  102   * zeros and this is the value we want.  This register isn't touched by this
  99  103   * module, and as long as it remains untouched by other modules we're OK.
 100  104   */
 101  105  
 102  106  static ldi_ident_t ldi_identifier;
 103  107  static boolean_t ldi_identifier_valid = B_FALSE;
 104      -static cred_t *credentials = NULL;
 105  108  
 106  109  /* Called by _init to determine if it is OK to install driver. */
 107  110  int
 108  111  fpc_platform_check()
 109  112  {
 110  113          return (SUCCESS);
 111  114  }
 112  115  
 113  116  /* Called during attach to do module-wide initialization. */
 114  117  int
 115  118  fpc_platform_module_init(dev_info_t *dip)
 116  119  {
 117  120          int status;
 118  121  
 119      -        credentials = crget();
 120  122          status = ldi_ident_from_dip(dip, &ldi_identifier);
 121  123          if (status == 0)
 122  124                  ldi_identifier_valid = B_TRUE;
 123  125          return ((status == 0) ? DDI_SUCCESS : DDI_FAILURE);
 124  126  }
 125  127  
 126  128  int
 127  129  fpc_platform_node_init(dev_info_t *dip, int *avail)
 128  130  {
 129  131          int index;
 130  132          char *name;
 131  133          int nodename_size;
 132  134          char *nodename = NULL;
 133  135          fire4u_specific_t *platform_specific_data = NULL;
 134  136          char *compatible = NULL;
 135  137          px_regs_t *regs_p = NULL;
 136  138          int regs_length = 0;
 137  139  
 138  140          if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 139  141              "compatible", &compatible) != DDI_PROP_SUCCESS)
 140  142                  return (DDI_SUCCESS);
 141  143  
 142  144          if (strcmp(compatible, CHIP_COMPATIBLE_NAME) != 0) {
 143  145                  ddi_prop_free(compatible);
 144  146                  return (DDI_SUCCESS);
 145  147          }
 146  148          ddi_prop_free(compatible);
 147  149  
 148  150          fpc_common_node_setup(dip, &index);
 149  151  
 150  152          name = fpc_get_dev_name_by_number(index);
 151  153          nodename_size = strlen(name) + strlen(PCI_MINOR_REG) + 2;
 152  154          nodename = kmem_zalloc(nodename_size, KM_SLEEP);
 153  155  
 154  156          platform_specific_data =
 155  157              kmem_zalloc(sizeof (fire4u_specific_t), KM_SLEEP);
 156  158  
 157  159          (void) strcpy(nodename, name);
 158  160          (void) strcat(nodename, ":");
 159  161          (void) strcat(nodename, PCI_MINOR_REG);
 160  162          platform_specific_data->nodename = nodename;
 161  163  
 162  164          /* Get register banks. */
 163  165          if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 164  166              "reg", (caddr_t)®s_p, ®s_length) != DDI_SUCCESS) {
 165  167                  goto bad_regs_p;
 166  168          }
 167  169  
 168  170          if ((regs_length / sizeof (px_regs_t)) < 2) {
 169  171                  goto bad_regs_length;
 170  172          }
 171  173  
 172  174          platform_specific_data->jbus_bank_base =
 173  175              regs_p[JBUS_BANK].addr_lo & BANK_ADDR_MASK;
 174  176  
 175  177          kmem_free(regs_p, regs_length);
 176  178  
 177  179          if (index == 0)
 178  180                  *avail |= (PCIE_A_REGS_AVAIL | JBUS_REGS_AVAIL);
 179  181          else
 180  182                  *avail |= PCIE_B_REGS_AVAIL;
 181  183  
 182  184          (void) fpc_set_platform_data_by_number(index, platform_specific_data);
 183  185  
 184  186          return (DDI_SUCCESS);
 185  187  
 186  188  bad_regs_length:
 187  189          if (regs_p)
 188  190                  kmem_free(regs_p, regs_length);
 189  191  bad_regs_p:
 190  192          kmem_free(platform_specific_data, sizeof (fire4u_specific_t));
 191  193          if (nodename)
 192  194                  kmem_free(nodename, nodename_size);
 193  195  
 194  196          return (DDI_FAILURE);
 195  197  }
 196  198  
 197  199  void
 198  200  fpc_platform_node_fini(void *arg)
 199  201  {
 200  202          fire4u_specific_t *plat_arg = (fire4u_specific_t *)arg;
 201  203          if (plat_arg == NULL)
 202  204                  return;
 203  205          if (plat_arg->nodename)
  
    | 
      ↓ open down ↓ | 
    74 lines elided | 
    
      ↑ open up ↑ | 
  
 204  206                  kmem_free(plat_arg->nodename, strlen(plat_arg->nodename)+1);
 205  207          kmem_free(plat_arg, sizeof (fire4u_specific_t));
 206  208  }
 207  209  
 208  210  /*ARGSUSED*/
 209  211  void
 210  212  fpc_platform_module_fini(dev_info_t *dip)
 211  213  {
 212  214          if (ldi_identifier_valid)
 213  215                  ldi_ident_release(ldi_identifier);
 214      -        if (credentials)
 215      -                crfree(credentials);
 216  216  }
 217  217  
 218  218  fire_perfreg_handle_t
 219  219  fpc_get_perfreg_handle(int devnum)
 220  220  {
 221  221          int rval = EINVAL;
 222  222  
 223  223          fire_counter_handle_impl_t *handle_impl =
 224  224              kmem_zalloc(sizeof (fire_counter_handle_impl_t), KM_SLEEP);
 225  225  
 226  226          if ((handle_impl->devspec =
 227  227              fpc_get_platform_data_by_number(devnum)) != NULL) {
 228  228                  rval = ldi_open_by_name(handle_impl->devspec->nodename,
 229      -                    OPEN_FLAGS, credentials, &handle_impl->devhandle,
      229 +                    OPEN_FLAGS, kcred, &handle_impl->devhandle,
 230  230                      ldi_identifier);
 231  231          }
 232  232  
 233  233          if (rval != SUCCESS) {
 234  234                  kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 235  235                  return ((fire_perfreg_handle_t)-1);
 236  236          } else {
 237  237                  return ((fire_perfreg_handle_t)handle_impl);
 238  238          }
 239  239  }
 240  240  
 241  241  int
 242  242  fpc_free_counter_handle(fire_perfreg_handle_t handle)
 243  243  {
 244  244          fire_counter_handle_impl_t *handle_impl =
 245  245              (fire_counter_handle_impl_t *)handle;
 246      -        (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, credentials);
      246 +        (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, kcred);
 247  247          kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t));
 248  248          return (SUCCESS);
 249  249  }
 250  250  
 251  251  int
 252  252  fpc_event_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 253  253      uint64_t *reg_data, boolean_t is_write)
 254  254  {
 255  255          int rval;
 256  256          int ioctl_rval;
 257  257          pcitool_reg_t prg;
 258  258          fire_counter_handle_impl_t *handle_impl =
 259  259              (fire_counter_handle_impl_t *)handle;
 260  260          int cmd = is_write ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 261  261  
 262  262          prg.user_version = PCITOOL_VERSION;
 263  263  
 264  264          if (group == jbc) {
 265  265                  prg.barnum = JBUS_BANK;
 266  266                  prg.offset = counter_select_offsets[group] -
 267  267                      handle_impl->devspec->jbus_bank_base;
 268  268          } else {
 269  269                  prg.barnum = PCIE_BANK;
 270  270  
 271  271                  /*
 272  272                   * Note that a pcie_bank_base isn't needed.  Pcie register
 273  273                   * offsets are already relative to the start of their bank.  No
  
    | 
      ↓ open down ↓ | 
    17 lines elided | 
    
      ↑ open up ↑ | 
  
 274  274                   * base needs to be subtracted to get the relative offset that
 275  275                   * pcitool ioctls want.
 276  276                   */
 277  277                  prg.offset = counter_select_offsets[group];
 278  278          }
 279  279          prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 280  280          prg.data = *reg_data;
 281  281  
 282  282          /* Read original value. */
 283  283          if (((rval = ldi_ioctl(handle_impl->devhandle, cmd, (intptr_t)&prg,
 284      -            FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
      284 +            FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 285  285                  *reg_data = prg.data;
 286  286          }
 287  287  
 288  288          return (rval);
 289  289  }
 290  290  
 291  291  int
 292  292  fpc_counter_io(fire_perfreg_handle_t handle, fire_perfcnt_t group,
 293  293      int counter_index, uint64_t *value, boolean_t is_write)
 294  294  {
 295  295          int rval;
 296  296          int ioctl_rval;
 297  297          pcitool_reg_t prg;
 298  298          fire_counter_handle_impl_t *handle_impl =
 299  299              (fire_counter_handle_impl_t *)handle;
 300  300          int command =
 301  301              (is_write) ? PCITOOL_NEXUS_SET_REG : PCITOOL_NEXUS_GET_REG;
 302  302  
 303  303          prg.user_version = PCITOOL_VERSION;
 304  304          /*
 305  305           * Note that stated PCIE offsets are relative to the beginning of their
 306  306           * register bank, while JBUS offsets are absolute.
 307  307           */
 308  308          if (group == jbc) {
 309  309                  prg.barnum = JBUS_BANK;
 310  310                  prg.offset = counter_reg_offsets[counter_index] -
 311  311                      handle_impl->devspec->jbus_bank_base;
 312  312          } else {
 313  313                  prg.barnum = PCIE_BANK;
 314  314                  prg.offset = counter_reg_offsets[counter_index];
  
    | 
      ↓ open down ↓ | 
    20 lines elided | 
    
      ↑ open up ↑ | 
  
 315  315          }
 316  316  
 317  317          if ((group == lpu) && (is_write)) {
 318  318                  prg.offset += LPU_LINK_PERFCTR_WRITE_OFFSET;
 319  319          }
 320  320  
 321  321          prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 | PCITOOL_ACC_ATTR_ENDN_BIG;
 322  322          prg.data = *value;
 323  323  
 324  324          if (((rval = ldi_ioctl(handle_impl->devhandle, command, (intptr_t)&prg,
 325      -            FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) {
      325 +            FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) {
 326  326                  *value = prg.data;
 327  327          }
 328  328  
 329  329          return (rval);
 330  330  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX