Print this page
11844 add rdmsr utility
Reviewed by: Dan McDonald <danmcd@joyent.com>


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 /*
  25  * Copyright (c) 2012, Joyent, Inc.  All rights reserved.
  26  */
  27 
  28 
  29 #include <sys/types.h>
  30 #include <sys/file.h>
  31 #include <sys/errno.h>
  32 #include <sys/open.h>
  33 #include <sys/cred.h>
  34 #include <sys/conf.h>
  35 #include <sys/stat.h>
  36 #include <sys/processor.h>
  37 #include <sys/cpuvar.h>
  38 #include <sys/kmem.h>
  39 #include <sys/modctl.h>
  40 #include <sys/ddi.h>
  41 #include <sys/sunddi.h>

  42 
  43 #include <sys/auxv.h>
  44 #include <sys/cpuid_drv.h>
  45 #include <sys/systeminfo.h>
  46 
  47 #if defined(__x86)
  48 #include <sys/x86_archext.h>
  49 #endif
  50 
  51 static dev_info_t *cpuid_devi;
  52 
  53 /*ARGSUSED*/
  54 static int
  55 cpuid_getinfo(dev_info_t *devi, ddi_info_cmd_t cmd, void *arg, void **result)
  56 {
  57         switch (cmd) {
  58         case DDI_INFO_DEVT2DEVINFO:
  59         case DDI_INFO_DEVT2INSTANCE:
  60                 break;
  61         default:


 166                 areq[sizeof (areq) - 1] = '\0';
 167 
 168                 if (strcmp(areq, architecture) == 0) {
 169                         STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap);
 170                         STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap_2);
 171 #if defined(_SYSCALL32_IMPL)
 172                 } else if (strcmp(areq, architecture_32) == 0) {
 173                         STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap32);
 174                         STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap32_2);
 175 #endif
 176                 } else {
 177                         STRUCT_FSET(h, cgh_hwcap[0], 0);
 178                         STRUCT_FSET(h, cgh_hwcap[1], 0);
 179                 }
 180                 if (ddi_copyout(STRUCT_BUF(h),
 181                     (void *)arg, STRUCT_SIZE(h), mode))
 182                         return (EFAULT);
 183                 return (0);
 184         }
 185 





























 186         default:
 187                 return (ENOTTY);
 188         }
 189 }
 190 
 191 static struct cb_ops cpuid_cb_ops = {
 192         cpuid_open,
 193         nulldev,        /* close */
 194         nodev,          /* strategy */
 195         nodev,          /* print */
 196         nodev,          /* dump */
 197         cpuid_read,
 198         nodev,          /* write */
 199         cpuid_ioctl,
 200         nodev,          /* devmap */
 201         nodev,          /* mmap */
 202         nodev,          /* segmap */
 203         nochpoll,       /* poll */
 204         ddi_prop_op,
 205         NULL,




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 /*
  25  * Copyright 2019 Joyent, Inc.
  26  */
  27 
  28 
  29 #include <sys/types.h>
  30 #include <sys/file.h>
  31 #include <sys/errno.h>
  32 #include <sys/open.h>
  33 #include <sys/cred.h>
  34 #include <sys/conf.h>
  35 #include <sys/stat.h>
  36 #include <sys/processor.h>
  37 #include <sys/cpuvar.h>
  38 #include <sys/kmem.h>
  39 #include <sys/modctl.h>
  40 #include <sys/ddi.h>
  41 #include <sys/sunddi.h>
  42 #include <sys/policy.h>
  43 
  44 #include <sys/auxv.h>
  45 #include <sys/cpuid_drv.h>
  46 #include <sys/systeminfo.h>
  47 
  48 #if defined(__x86)
  49 #include <sys/x86_archext.h>
  50 #endif
  51 
  52 static dev_info_t *cpuid_devi;
  53 
  54 /*ARGSUSED*/
  55 static int
  56 cpuid_getinfo(dev_info_t *devi, ddi_info_cmd_t cmd, void *arg, void **result)
  57 {
  58         switch (cmd) {
  59         case DDI_INFO_DEVT2DEVINFO:
  60         case DDI_INFO_DEVT2INSTANCE:
  61                 break;
  62         default:


 167                 areq[sizeof (areq) - 1] = '\0';
 168 
 169                 if (strcmp(areq, architecture) == 0) {
 170                         STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap);
 171                         STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap_2);
 172 #if defined(_SYSCALL32_IMPL)
 173                 } else if (strcmp(areq, architecture_32) == 0) {
 174                         STRUCT_FSET(h, cgh_hwcap[0], auxv_hwcap32);
 175                         STRUCT_FSET(h, cgh_hwcap[1], auxv_hwcap32_2);
 176 #endif
 177                 } else {
 178                         STRUCT_FSET(h, cgh_hwcap[0], 0);
 179                         STRUCT_FSET(h, cgh_hwcap[1], 0);
 180                 }
 181                 if (ddi_copyout(STRUCT_BUF(h),
 182                     (void *)arg, STRUCT_SIZE(h), mode))
 183                         return (EFAULT);
 184                 return (0);
 185         }
 186 
 187 #ifdef __x86
 188         case CPUID_RDMSR: {
 189                 struct cpuid_rdmsr crm = { 0, };
 190                 label_t label;
 191 
 192                 if (secpolicy_sys_config(cr, B_FALSE) != 0)
 193                         return (EPERM);
 194 
 195                 if (ddi_copyin((void *)arg, &crm, sizeof (crm), mode))
 196                         return (EFAULT);
 197 
 198                 kpreempt_disable();
 199 
 200                 if (on_fault(&label)) {
 201                         kpreempt_enable();
 202                         return (ENOENT);
 203                 }
 204 
 205                 crm.cr_msr_val = rdmsr(crm.cr_msr_nr);
 206 
 207                 no_fault();
 208                 kpreempt_enable();
 209 
 210                 if (ddi_copyout(&crm, (void *)arg, sizeof (crm), mode))
 211                         return (EFAULT);
 212                 return (0);
 213         }
 214 #endif
 215 
 216         default:
 217                 return (ENOTTY);
 218         }
 219 }
 220 
 221 static struct cb_ops cpuid_cb_ops = {
 222         cpuid_open,
 223         nulldev,        /* close */
 224         nodev,          /* strategy */
 225         nodev,          /* print */
 226         nodev,          /* dump */
 227         cpuid_read,
 228         nodev,          /* write */
 229         cpuid_ioctl,
 230         nodev,          /* devmap */
 231         nodev,          /* mmap */
 232         nodev,          /* segmap */
 233         nochpoll,       /* poll */
 234         ddi_prop_op,
 235         NULL,