1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   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) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 /*
  26  * sun4v domain services PRI driver
  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/uio.h>
  35 #include <sys/stat.h>
  36 #include <sys/ksynch.h>
  37 #include <sys/modctl.h>
  38 #include <sys/conf.h>
  39 #include <sys/devops.h>
  40 #include <sys/debug.h>
  41 #include <sys/cmn_err.h>
  42 #include <sys/ddi.h>
  43 #include <sys/sunddi.h>
  44 #include <sys/ds.h>
  45 #include <sys/hypervisor_api.h>
  46 #include <sys/machsystm.h>
  47 #include <sys/sysmacros.h>
  48 #include <sys/hsvc.h>
  49 #include <sys/bitmap.h>
  50 #include <sys/ds_pri.h>
  51 
  52 static uint_t ds_pri_debug = 0;
  53 #define DS_PRI_DBG      if (ds_pri_debug) printf
  54 
  55 #define DS_PRI_NAME     "ds_pri"
  56 
  57 #define TEST_HARNESS
  58 #ifdef TEST_HARNESS
  59 #define DS_PRI_MAX_PRI_SIZE     (64 * 1024)
  60 
  61 #define DSIOC_TEST_REG  97
  62 #define DSIOC_TEST_UNREG        98
  63 #define DSIOC_TEST_DATA 99
  64 
  65 struct ds_pri_test_data {
  66         size_t          size;
  67         void            *data;
  68 };
  69 
  70 struct ds_pri_test_data32 {
  71         size32_t        size;
  72         caddr32_t       data;
  73 };
  74 #endif /* TEST_HARNESS */
  75 
  76 typedef enum {
  77         DS_PRI_REQUEST  = 0,
  78         DS_PRI_DATA     = 1,
  79         DS_PRI_UPDATE   = 2
  80 } ds_pri_msg_type_t;
  81 
  82 typedef struct {
  83         struct {
  84                 uint64_t        seq_num;
  85                 uint64_t        type;
  86         } hdr;
  87         uint8_t         data[1];
  88 } ds_pri_msg_t;
  89 
  90 /*
  91  * The following are bit field flags. No service implies no DS PRI and
  92  * no outstanding request.
  93  */
  94 typedef enum {
  95         DS_PRI_NO_SERVICE = 0x0,
  96         DS_PRI_HAS_SERVICE = 0x1,
  97         DS_PRI_REQUESTED = 0x2,
  98         DS_PRI_HAS_PRI = 0x4
  99 } ds_pri_flags_t;
 100 
 101 struct ds_pri_state {
 102         dev_info_t      *dip;
 103         int             instance;
 104 
 105         kmutex_t        lock;
 106         kcondvar_t      cv;
 107 
 108         /* PRI/DS */
 109         ds_pri_flags_t  state;
 110         uint64_t        gencount;
 111         ds_svc_hdl_t    ds_pri_handle;
 112         void            *ds_pri;
 113         size_t          ds_pri_len;
 114         uint64_t        req_id;
 115         uint64_t        last_req_id;
 116         int             num_opens;
 117 };
 118 
 119 typedef struct ds_pri_state ds_pri_state_t;
 120 
 121 static void *ds_pri_statep;
 122 
 123 static void request_pri(ds_pri_state_t *sp);
 124 static uint64_t ds_get_hv_pri(ds_pri_state_t *sp);
 125 
 126 static int ds_pri_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 127 static int ds_pri_attach(dev_info_t *, ddi_attach_cmd_t);
 128 static int ds_pri_detach(dev_info_t *, ddi_detach_cmd_t);
 129 static int ds_pri_open(dev_t *, int, int, cred_t *);
 130 static int ds_pri_close(dev_t, int, int, cred_t *);
 131 static int ds_pri_read(dev_t, struct uio *, cred_t *);
 132 static int ds_pri_ioctl(dev_t, int, intptr_t, int, cred_t *, int *);
 133 
 134 /*
 135  * DS Callbacks
 136  */
 137 static void ds_pri_reg_handler(ds_cb_arg_t, ds_ver_t *, ds_svc_hdl_t);
 138 static void ds_pri_unreg_handler(ds_cb_arg_t arg);
 139 static void ds_pri_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen);
 140 
 141 /*
 142  * PRI DS capability registration
 143  */
 144 
 145 static ds_ver_t ds_pri_ver_1_0 = { 1, 0 };
 146 
 147 static ds_capability_t ds_pri_cap = {
 148         "pri",
 149         &ds_pri_ver_1_0,
 150         1
 151 };
 152 
 153 /*
 154  * PRI DS Client callback vector
 155  */
 156 static ds_clnt_ops_t ds_pri_ops = {
 157         ds_pri_reg_handler,     /* ds_reg_cb */
 158         ds_pri_unreg_handler,   /* ds_unreg_cb */
 159         ds_pri_data_handler,    /* ds_data_cb */
 160         NULL                    /* cb_arg */
 161 };
 162 
 163 /*
 164  * DS PRI driver Ops Vector
 165  */
 166 static struct cb_ops ds_pri_cb_ops = {
 167         ds_pri_open,            /* cb_open */
 168         ds_pri_close,           /* cb_close */
 169         nodev,                  /* cb_strategy */
 170         nodev,                  /* cb_print */
 171         nodev,                  /* cb_dump */
 172         ds_pri_read,            /* cb_read */
 173         nodev,                  /* cb_write */
 174         ds_pri_ioctl,           /* cb_ioctl */
 175         nodev,                  /* cb_devmap */
 176         nodev,                  /* cb_mmap */
 177         nodev,                  /* cb_segmap */
 178         nochpoll,               /* cb_chpoll */
 179         ddi_prop_op,            /* cb_prop_op */
 180         (struct streamtab *)NULL, /* cb_str */
 181         D_MP | D_64BIT,         /* cb_flag */
 182         CB_REV,                 /* cb_rev */
 183         nodev,                  /* cb_aread */
 184         nodev                   /* cb_awrite */
 185 };
 186 
 187 static struct dev_ops ds_pri_dev_ops = {
 188         DEVO_REV,               /* devo_rev */
 189         0,                      /* devo_refcnt */
 190         ds_pri_getinfo,         /* devo_getinfo */
 191         nulldev,                /* devo_identify */
 192         nulldev,                /* devo_probe */
 193         ds_pri_attach,          /* devo_attach */
 194         ds_pri_detach,          /* devo_detach */
 195         nodev,                  /* devo_reset */
 196         &ds_pri_cb_ops,             /* devo_cb_ops */
 197         (struct bus_ops *)NULL, /* devo_bus_ops */
 198         nulldev,                /* devo_power */
 199         ddi_quiesce_not_needed,         /* devo_quiesce */
 200 };
 201 
 202 static struct modldrv modldrv = {
 203         &mod_driverops,
 204         "Domain Services PRI Driver",
 205         &ds_pri_dev_ops
 206 };
 207 
 208 static struct modlinkage modlinkage = {
 209         MODREV_1,
 210         (void *)&modldrv,
 211         NULL
 212 };
 213 
 214 static boolean_t hsvc_pboot_available = B_FALSE;
 215 static hsvc_info_t pboot_hsvc = {
 216         HSVC_REV_1, NULL, HSVC_GROUP_PBOOT, 1, 0, NULL
 217 };
 218 
 219 int
 220 _init(void)
 221 {
 222         int retval;
 223         uint64_t        hsvc_pboot_minor;
 224         uint64_t        status;
 225 
 226         status = hsvc_register(&pboot_hsvc, &hsvc_pboot_minor);
 227         if (status == H_EOK) {
 228                 hsvc_pboot_available = B_TRUE;
 229         } else {
 230                 DS_PRI_DBG("hypervisor services not negotiated "
 231                     "for group number: 0x%lx errorno: 0x%lx\n",
 232                     pboot_hsvc.hsvc_group, status);
 233         }
 234 
 235         retval = ddi_soft_state_init(&ds_pri_statep,
 236             sizeof (ds_pri_state_t), 0);
 237         if (retval != 0)
 238                 return (retval);
 239 
 240         retval = mod_install(&modlinkage);
 241         if (retval != 0) {
 242                 ddi_soft_state_fini(&ds_pri_statep);
 243                 return (retval);
 244         }
 245 
 246         return (retval);
 247 }
 248 
 249 
 250 int
 251 _info(struct modinfo *modinfop)
 252 {
 253         return (mod_info(&modlinkage, modinfop));
 254 }
 255 
 256 
 257 int
 258 _fini(void)
 259 {
 260         int retval;
 261 
 262         if ((retval = mod_remove(&modlinkage)) != 0)
 263                 return (retval);
 264 
 265         ddi_soft_state_fini(&ds_pri_statep);
 266 
 267         if (hsvc_pboot_available)
 268                 (void) hsvc_unregister(&pboot_hsvc);
 269 
 270         return (retval);
 271 }
 272 
 273 
 274 /*ARGSUSED*/
 275 static int
 276 ds_pri_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **resultp)
 277 {
 278         ds_pri_state_t *sp;
 279         int retval = DDI_FAILURE;
 280 
 281         ASSERT(resultp != NULL);
 282 
 283         switch (cmd) {
 284         case DDI_INFO_DEVT2DEVINFO:
 285                 sp = ddi_get_soft_state(ds_pri_statep, getminor((dev_t)arg));
 286                 if (sp != NULL) {
 287                         *resultp = sp->dip;
 288                         retval = DDI_SUCCESS;
 289                 } else
 290                         *resultp = NULL;
 291                 break;
 292 
 293         case DDI_INFO_DEVT2INSTANCE:
 294                 *resultp = (void *)(uintptr_t)getminor((dev_t)arg);
 295                 retval = DDI_SUCCESS;
 296                 break;
 297 
 298         default:
 299                 break;
 300         }
 301 
 302         return (retval);
 303 }
 304 
 305 
 306 static int
 307 ds_pri_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 308 {
 309         int instance;
 310         ds_pri_state_t *sp;
 311         int rv;
 312         uint64_t status;
 313 
 314         switch (cmd) {
 315         case DDI_ATTACH:
 316                 break;
 317 
 318         case DDI_RESUME:
 319                 return (DDI_SUCCESS);
 320 
 321         default:
 322                 return (DDI_FAILURE);
 323         }
 324 
 325         instance = ddi_get_instance(dip);
 326 
 327         if (ddi_soft_state_zalloc(ds_pri_statep, instance) !=
 328             DDI_SUCCESS) {
 329                 cmn_err(CE_WARN, "%s@%d: Unable to allocate state",
 330                     DS_PRI_NAME, instance);
 331                 return (DDI_FAILURE);
 332         }
 333         sp = ddi_get_soft_state(ds_pri_statep, instance);
 334 
 335         mutex_init(&sp->lock, NULL, MUTEX_DEFAULT, NULL);
 336         cv_init(&sp->cv, NULL, CV_DEFAULT, NULL);
 337 
 338         if (ddi_create_minor_node(dip, DS_PRI_NAME, S_IFCHR, instance,
 339             DDI_PSEUDO, 0) != DDI_SUCCESS) {
 340                 cmn_err(CE_WARN, "%s@%d: Unable to create minor node",
 341                     DS_PRI_NAME, instance);
 342                 goto fail;
 343         }
 344 
 345         if (ds_pri_ops.cb_arg != NULL)
 346                 goto fail;
 347         ds_pri_ops.cb_arg = dip;
 348 
 349         sp->state = DS_PRI_NO_SERVICE;
 350 
 351         /* Until the service registers the handle is invalid */
 352         sp->ds_pri_handle = DS_INVALID_HDL;
 353 
 354         sp->ds_pri = NULL;
 355         sp->ds_pri_len = 0;
 356         sp->req_id = 0;
 357         sp->num_opens = 0;
 358 
 359         /*
 360          * See if we can get the static hv pri data. Static pri data
 361          * is only available for privileged domains.
 362          */
 363         if (hsvc_pboot_available) {
 364                 if ((status = ds_get_hv_pri(sp)) != 0) {
 365                         cmn_err(CE_NOTE, "ds_get_hv_pri failed: 0x%lx", status);
 366                 }
 367         }
 368 
 369         if ((rv = ds_cap_init(&ds_pri_cap, &ds_pri_ops)) != 0) {
 370                 cmn_err(CE_NOTE, "ds_cap_init failed: %d", rv);
 371                 goto fail;
 372         }
 373 
 374         ddi_report_dev(dip);
 375 
 376         return (DDI_SUCCESS);
 377 
 378 fail:
 379         if (sp->ds_pri)
 380                 kmem_free(sp->ds_pri, sp->ds_pri_len);
 381         ddi_remove_minor_node(dip, NULL);
 382         cv_destroy(&sp->cv);
 383         mutex_destroy(&sp->lock);
 384         ddi_soft_state_free(ds_pri_statep, instance);
 385         return (DDI_FAILURE);
 386 
 387 }
 388 
 389 
 390 /*ARGSUSED*/
 391 static int
 392 ds_pri_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
 393 {
 394         ds_pri_state_t *sp;
 395         int instance;
 396         int rv;
 397 
 398         instance = ddi_get_instance(dip);
 399         sp = ddi_get_soft_state(ds_pri_statep, instance);
 400 
 401         switch (cmd) {
 402         case DDI_DETACH:
 403                 break;
 404 
 405         case DDI_SUSPEND:
 406                 return (DDI_SUCCESS);
 407 
 408         default:
 409                 return (DDI_FAILURE);
 410         }
 411 
 412         /* This really shouldn't fail - but check anyway */
 413         if ((rv = ds_cap_fini(&ds_pri_cap)) != 0) {
 414                 cmn_err(CE_WARN, "ds_cap_fini failed: %d", rv);
 415         }
 416 
 417         if (sp != NULL && sp->ds_pri_len != 0)
 418                 kmem_free(sp->ds_pri, sp->ds_pri_len);
 419 
 420         ds_pri_ops.cb_arg = NULL;
 421 
 422         ddi_remove_minor_node(dip, NULL);
 423         cv_destroy(&sp->cv);
 424         mutex_destroy(&sp->lock);
 425         ddi_soft_state_free(ds_pri_statep, instance);
 426 
 427         return (DDI_SUCCESS);
 428 }
 429 
 430 
 431 /*ARGSUSED*/
 432 static int
 433 ds_pri_open(dev_t *devp, int flag, int otyp, cred_t *credp)
 434 {
 435         ds_pri_state_t *sp;
 436         int instance;
 437 
 438         if (otyp != OTYP_CHR)
 439                 return (EINVAL);
 440 
 441         instance = getminor(*devp);
 442         sp = ddi_get_soft_state(ds_pri_statep, instance);
 443         if (sp == NULL)
 444                 return (ENXIO);
 445 
 446         mutex_enter(&sp->lock);
 447 
 448         /*
 449          * Proceed if we have PRI data (possibly obtained from
 450          * static HV PRI or last pushed DS PRI data update).
 451          * If no PRI data and we have no DS PRI service then this
 452          * means that PRI DS has never called the registration callback.
 453          * A while loop is necessary as we might have been woken up
 454          * prematurely, e.g., due to a debugger or "pstack" etc.
 455          * Wait here and the callback will signal us when it has completed
 456          * its work.
 457          */
 458         if (!(sp->state & DS_PRI_HAS_PRI)) {
 459                 while (!(sp->state & DS_PRI_HAS_SERVICE)) {
 460                         if (cv_wait_sig(&sp->cv, &sp->lock) == 0) {
 461                                 mutex_exit(&sp->lock);
 462                                 return (EINTR);
 463                         }
 464                 }
 465         }
 466 
 467         sp->num_opens++;
 468         mutex_exit(&sp->lock);
 469 
 470         DS_PRI_DBG("ds_pri_open: state = 0x%x\n", sp->state);
 471 
 472         return (0);
 473 }
 474 
 475 
 476 /*ARGSUSED*/
 477 static int
 478 ds_pri_close(dev_t dev, int flag, int otyp, cred_t *credp)
 479 {
 480         int instance;
 481         ds_pri_state_t *sp;
 482 
 483         if (otyp != OTYP_CHR)
 484                 return (EINVAL);
 485 
 486         DS_PRI_DBG("ds_pri_close\n");
 487 
 488         instance = getminor(dev);
 489         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 490                 return (ENXIO);
 491 
 492         mutex_enter(&sp->lock);
 493         if (!(sp->state & DS_PRI_HAS_SERVICE)) {
 494                 mutex_exit(&sp->lock);
 495                 return (0);
 496         }
 497 
 498         if (--sp->num_opens > 0) {
 499                 mutex_exit(&sp->lock);
 500                 return (0);
 501         }
 502 
 503         sp->state &= ~DS_PRI_REQUESTED;
 504         mutex_exit(&sp->lock);
 505         return (0);
 506 }
 507 
 508 
 509 /*ARGSUSED*/
 510 static int
 511 ds_pri_read(dev_t dev, struct uio *uiop, cred_t *credp)
 512 {
 513         ds_pri_state_t *sp;
 514         int instance;
 515         size_t len;
 516         int retval;
 517         caddr_t tmpbufp;
 518         offset_t off = uiop->uio_offset;
 519 
 520         instance = getminor(dev);
 521         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 522                 return (ENXIO);
 523 
 524         len = uiop->uio_resid;
 525 
 526         if (len == 0)
 527                 return (0);
 528 
 529         mutex_enter(&sp->lock);
 530 
 531         DS_PRI_DBG("ds_pri_read: state = 0x%x\n", sp->state);
 532 
 533         /* block or bail if there is no current PRI */
 534         if (!(sp->state & DS_PRI_HAS_PRI)) {
 535                 DS_PRI_DBG("ds_pri_read: no PRI held\n");
 536 
 537                 if (uiop->uio_fmode & (FNDELAY | FNONBLOCK)) {
 538                         mutex_exit(&sp->lock);
 539                         return (EAGAIN);
 540                 }
 541 
 542                 while (!(sp->state & DS_PRI_HAS_PRI)) {
 543                         DS_PRI_DBG("ds_pri_read: state = 0x%x\n", sp->state);
 544                         request_pri(sp);
 545                         if (cv_wait_sig(&sp->cv, &sp->lock) == 0) {
 546                                 mutex_exit(&sp->lock);
 547                                 return (EINTR);
 548                         }
 549                 }
 550         }
 551 
 552         if (len > sp->ds_pri_len)
 553                 len = sp->ds_pri_len;
 554 
 555         if (len == 0) {
 556                 mutex_exit(&sp->lock);
 557                 return (0);
 558         }
 559 
 560         /*
 561          * We're supposed to move the data out to userland, but
 562          * that can suspend because of page faults etc., and meanwhile
 563          * other parts of this driver want to update the PRI buffer ...
 564          * we could hold the data buffer locked with a flag etc.,
 565          * but that's still a lock ... a simpler mechanism - if not quite
 566          * as performance efficient is to simply clone here the part of
 567          * the buffer we care about and then the original can be released
 568          * for further updates while the uiomove continues.
 569          */
 570 
 571         tmpbufp = kmem_alloc(len, KM_SLEEP);
 572         bcopy(((caddr_t)sp->ds_pri), tmpbufp, len);
 573         mutex_exit(&sp->lock);
 574 
 575         retval = uiomove(tmpbufp, len, UIO_READ, uiop);
 576 
 577         kmem_free(tmpbufp, len);
 578 
 579         /*
 580          * restore uio_offset after uiomove since the driver
 581          * does not support the concept of position.
 582          */
 583         uiop->uio_offset = off;
 584 
 585         return (retval);
 586 }
 587 
 588 
 589 /*ARGSUSED*/
 590 static int
 591 ds_pri_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp,
 592     int *rvalp)
 593 {
 594         ds_pri_state_t *sp;
 595         int instance;
 596 
 597         instance = getminor(dev);
 598         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 599                 return (ENXIO);
 600 
 601         switch (cmd) {
 602         case DSPRI_GETINFO: {
 603                 struct dspri_info info;
 604 
 605                 if (!(mode & FREAD))
 606                         return (EACCES);
 607 
 608                 /*
 609                  * We are not guaranteed that ddi_copyout(9F) will read
 610                  * atomically anything larger than a byte.  Therefore we
 611                  * must duplicate the size before copying it out to the user.
 612                  */
 613                 mutex_enter(&sp->lock);
 614 
 615 loop:;
 616                 if (sp->state & DS_PRI_HAS_PRI) {
 617                         /* If we have a PRI simply return the info */
 618                         info.size = sp->ds_pri_len;
 619                         info.token = sp->gencount;
 620                 } else
 621                 if (!(sp->state & DS_PRI_HAS_SERVICE)) {
 622                         /* If we have no service return a nil response */
 623                         info.size = 0;
 624                         info.token = 0;
 625                 } else {
 626                         request_pri(sp);
 627                         /* wait for something & check again */
 628                         if (cv_wait_sig(&sp->cv, &sp->lock) == 0) {
 629                                 mutex_exit(&sp->lock);
 630                                 return (EINTR);
 631                         }
 632                         goto loop;
 633                 }
 634                 DS_PRI_DBG("ds_pri_ioctl: DSPRI_GETINFO sz=0x%lx tok=0x%lx\n",
 635                     info.size, info.token);
 636                 mutex_exit(&sp->lock);
 637 
 638                 if (ddi_copyout(&info, (void *)arg, sizeof (info), mode) != 0)
 639                         return (EFAULT);
 640                 break;
 641         }
 642 
 643         case DSPRI_WAIT: {
 644                 uint64_t gencount;
 645 
 646                 if (ddi_copyin((void *)arg, &gencount, sizeof (gencount),
 647                     mode) != 0)
 648                         return (EFAULT);
 649 
 650                 mutex_enter(&sp->lock);
 651 
 652                 DS_PRI_DBG("ds_pri_ioctl: DSPRI_WAIT gen=0x%lx sp->gen=0x%lx\n",
 653                     gencount, sp->gencount);
 654 
 655                 while ((sp->state & DS_PRI_HAS_PRI) == 0 ||
 656                     gencount == sp->gencount) {
 657                         if ((sp->state & DS_PRI_HAS_PRI) == 0)
 658                                 request_pri(sp);
 659                         if (cv_wait_sig(&sp->cv, &sp->lock) == 0) {
 660                                 mutex_exit(&sp->lock);
 661                                 return (EINTR);
 662                         }
 663                 }
 664                 mutex_exit(&sp->lock);
 665                 break;
 666         }
 667 
 668         default:
 669                 return (ENOTTY);
 670         }
 671         return (0);
 672 }
 673 
 674 
 675         /* assumes sp->lock is held when called */
 676 static void
 677 request_pri(ds_pri_state_t *sp)
 678 {
 679         ds_pri_msg_t reqmsg;
 680 
 681         ASSERT(MUTEX_HELD(&sp->lock));
 682 
 683         /* If a request is already pending we're done */
 684         if (!(sp->state & DS_PRI_HAS_SERVICE))
 685                 return;
 686         if (sp->state & DS_PRI_REQUESTED)
 687                 return;
 688 
 689         /* If we have an old PRI - remove it */
 690         if (sp->state & DS_PRI_HAS_PRI) {
 691                 ASSERT(sp->ds_pri_len != 0);
 692                 ASSERT(sp->ds_pri != NULL);
 693 
 694                 /* remove the old data if we have an outstanding request */
 695                 kmem_free(sp->ds_pri, sp->ds_pri_len);
 696                 sp->ds_pri_len = 0;
 697                 sp->ds_pri = NULL;
 698                 sp->state &= ~DS_PRI_HAS_PRI;
 699         } else {
 700                 ASSERT(sp->ds_pri == NULL);
 701                 ASSERT(sp->ds_pri_len == 0);
 702         }
 703 
 704         reqmsg.hdr.seq_num = ++(sp->req_id);
 705         reqmsg.hdr.type = DS_PRI_REQUEST;
 706 
 707         DS_PRI_DBG("request_pri: request id 0x%lx\n", sp->req_id);
 708 
 709                 /*
 710                  * Request consists of header only.
 711                  * We don't care about fail status for ds_send;
 712                  * if it does fail we will get an unregister callback
 713                  * from the DS framework and we handle the state change
 714                  * there.
 715                  */
 716         (void) ds_cap_send(sp->ds_pri_handle, &reqmsg, sizeof (reqmsg.hdr));
 717 
 718         sp->state |= DS_PRI_REQUESTED;
 719         sp->last_req_id = sp->req_id;
 720 }
 721 
 722 /*
 723  * DS Callbacks
 724  */
 725 /*ARGSUSED*/
 726 static void
 727 ds_pri_reg_handler(ds_cb_arg_t arg, ds_ver_t *ver, ds_svc_hdl_t hdl)
 728 {
 729         dev_info_t *dip = arg;
 730         ds_pri_state_t *sp;
 731         int instance;
 732 
 733         instance = ddi_get_instance(dip);
 734         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 735                 return;
 736 
 737         DS_PRI_DBG("ds_pri_reg_handler: registering handle 0x%lx for version "
 738             "0x%x:0x%x\n", (uint64_t)hdl, ver->major, ver->minor);
 739 
 740         /* When the domain service comes up automatically update the state */
 741         mutex_enter(&sp->lock);
 742 
 743         ASSERT(sp->ds_pri_handle == DS_INVALID_HDL);
 744         sp->ds_pri_handle = hdl;
 745 
 746         ASSERT(!(sp->state & DS_PRI_HAS_SERVICE));
 747         sp->state |= DS_PRI_HAS_SERVICE;
 748 
 749         /*
 750          * Cannot request a PRI here, because the reg handler cannot
 751          * do a DS send operation - we take care of this later.
 752          * Static hv pri data might be available.
 753          */
 754 
 755         /* Wake up anyone waiting in open() */
 756         cv_broadcast(&sp->cv);
 757 
 758         mutex_exit(&sp->lock);
 759 }
 760 
 761 
 762 static void
 763 ds_pri_unreg_handler(ds_cb_arg_t arg)
 764 {
 765         dev_info_t *dip = arg;
 766         ds_pri_state_t *sp;
 767         int instance;
 768 
 769         instance = ddi_get_instance(dip);
 770         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 771                 return;
 772 
 773         DS_PRI_DBG("ds_pri_unreg_handler: un-registering ds_pri service\n");
 774 
 775         mutex_enter(&sp->lock);
 776 
 777         /*
 778          * Note that if the service goes offline, we don't
 779          * free up the current PRI data at hand. It is assumed
 780          * that PRI DS service will only push new update when
 781          * it comes online. We mark the state to indicate no
 782          * DS PRI service is available. The current PRI data if
 783          * available is provided to the consumers.
 784          */
 785         sp->ds_pri_handle = DS_INVALID_HDL;
 786         sp->state &= ~DS_PRI_HAS_SERVICE;
 787 
 788         mutex_exit(&sp->lock);
 789 }
 790 
 791 
 792 static void
 793 ds_pri_data_handler(ds_cb_arg_t arg, void *buf, size_t buflen)
 794 {
 795         dev_info_t *dip = arg;
 796         ds_pri_state_t *sp;
 797         int instance;
 798         void *data;
 799         ds_pri_msg_t    *msgp;
 800         size_t  pri_size;
 801 
 802         msgp = (ds_pri_msg_t *)buf;
 803 
 804         /* make sure the header is at least valid */
 805         if (buflen < sizeof (msgp->hdr))
 806                 return;
 807 
 808         DS_PRI_DBG("ds_pri_data_handler: msg buf len 0x%lx : type 0x%lx, "
 809             "seqn 0x%lx\n", buflen, msgp->hdr.type, msgp->hdr.seq_num);
 810 
 811         instance = ddi_get_instance(dip);
 812         if ((sp = ddi_get_soft_state(ds_pri_statep, instance)) == NULL)
 813                 return;
 814 
 815         mutex_enter(&sp->lock);
 816 
 817         ASSERT(sp->state & DS_PRI_HAS_SERVICE);
 818 
 819         switch (msgp->hdr.type) {
 820         case DS_PRI_DATA:       /* in response to a request from us */
 821                 break;
 822         case DS_PRI_UPDATE:     /* aynch notification */
 823                         /* our default response to this is to request the PRI */
 824                 /* simply issue a request for the new PRI */
 825                 request_pri(sp);
 826                 goto done;
 827         default:        /* ignore garbage or unknown message types */
 828                 goto done;
 829         }
 830 
 831         /*
 832          * If there is no pending PRI request, then we've received a
 833          * bogus data message ... so ignore it.
 834          */
 835 
 836         if (!(sp->state & DS_PRI_REQUESTED)) {
 837                 cmn_err(CE_WARN, "Received DS pri data without request");
 838                 goto done;
 839         }
 840 
 841         /* response to a request therefore old PRI must be gone */
 842         ASSERT(!(sp->state & DS_PRI_HAS_PRI));
 843         ASSERT(sp->ds_pri_len == 0);
 844         ASSERT(sp->ds_pri == NULL);
 845 
 846         /* response seq_num should match our request seq_num */
 847         if (msgp->hdr.seq_num != sp->last_req_id) {
 848                 cmn_err(CE_WARN, "Received DS pri data out of sequence with "
 849                     "request");
 850                 goto done;
 851         }
 852 
 853         pri_size = buflen - sizeof (msgp->hdr);
 854         if (pri_size == 0) {
 855                 cmn_err(CE_WARN, "Received DS pri data of size 0");
 856                 goto done;
 857         }
 858         data = kmem_alloc(pri_size, KM_SLEEP);
 859         sp->ds_pri = data;
 860         sp->ds_pri_len = pri_size;
 861         bcopy(msgp->data, data, sp->ds_pri_len);
 862         sp->state &= ~DS_PRI_REQUESTED;
 863         sp->state |= DS_PRI_HAS_PRI;
 864 
 865         sp->gencount++;
 866         cv_broadcast(&sp->cv);
 867 
 868 done:;
 869         mutex_exit(&sp->lock);
 870 }
 871 
 872 /*
 873  * Routine to get static PRI data from the Hypervisor.
 874  * If successful, this PRI data is the last known PRI
 875  * data generated since the last poweron reset.
 876  */
 877 static uint64_t
 878 ds_get_hv_pri(ds_pri_state_t *sp)
 879 {
 880         uint64_t        status;
 881         uint64_t        pri_size;
 882         uint64_t        buf_size;
 883         uint64_t        buf_pa;
 884         caddr_t         buf_va = NULL;
 885         caddr_t         pri_data;
 886 
 887         /*
 888          * Get pri buffer size by calling hcall with buffer size 0.
 889          */
 890         pri_size = 0LL;
 891         status = hv_mach_pri((uint64_t)0, &pri_size);
 892         if (status == H_ENOTSUPPORTED || status == H_ENOACCESS) {
 893                 /*
 894                  * hv_mach_pri() is not supported on a guest domain.
 895                  * Unregister pboot API group to prevent failures.
 896                  */
 897                 (void) hsvc_unregister(&pboot_hsvc);
 898                 hsvc_pboot_available = B_FALSE;
 899                 DS_PRI_DBG("ds_get_hv_pri: hv_mach_pri service is not "
 900                     "available. errorno: 0x%lx\n", status);
 901                 return (0);
 902         } else if (pri_size == 0) {
 903                 return (1);
 904         } else {
 905                 DS_PRI_DBG("ds_get_hv_pri: hv_mach_pri pri size: 0x%lx\n",
 906                     pri_size);
 907         }
 908 
 909         /*
 910          * contig_mem_alloc requires size to be a power of 2.
 911          * Increase size to next power of 2 if necessary.
 912          */
 913         if ((pri_size & (pri_size - 1)) != 0)
 914                 buf_size = 1 << highbit(pri_size);
 915         DS_PRI_DBG("ds_get_hv_pri: buf_size = 0x%lx\n", buf_size);
 916 
 917         buf_va = contig_mem_alloc(buf_size);
 918         if (buf_va == NULL)
 919                 return (1);
 920 
 921         buf_pa = va_to_pa(buf_va);
 922         DS_PRI_DBG("ds_get_hv_pri: buf_pa 0x%lx\n", buf_pa);
 923         status = hv_mach_pri(buf_pa, &pri_size);
 924         DS_PRI_DBG("ds_get_hv_pri: hv_mach_pri status = 0x%lx\n", status);
 925 
 926         if (status == H_EOK) {
 927                 pri_data = kmem_alloc(pri_size, KM_SLEEP);
 928                 sp->ds_pri = pri_data;
 929                 sp->ds_pri_len = pri_size;
 930                 bcopy(buf_va, pri_data, sp->ds_pri_len);
 931                 sp->state |= DS_PRI_HAS_PRI;
 932                 sp->gencount++;
 933         }
 934 
 935         contig_mem_free(buf_va, buf_size);
 936 
 937         return (status);
 938 }