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 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 27 /* 28 * Niagara 2 Random Number Generator (RNG) driver 29 */ 30 31 #include <sys/types.h> 32 #include <sys/sysmacros.h> 33 #include <sys/modctl.h> 34 #include <sys/conf.h> 35 #include <sys/devops.h> 36 #include <sys/cmn_err.h> 37 #include <sys/ksynch.h> 38 #include <sys/kmem.h> 39 #include <sys/stat.h> 40 #include <sys/open.h> 41 #include <sys/file.h> 42 #include <sys/ddi.h> 43 #include <sys/sunddi.h> 44 #include <sys/param.h> 45 #include <sys/cpuvar.h> 46 #include <sys/disp.h> 47 #include <sys/hsvc.h> 48 #include <sys/machsystm.h> 49 #include <sys/hypervisor_api.h> 50 #include <sys/n2rng.h> 51 52 static int n2rng_attach(dev_info_t *, ddi_attach_cmd_t); 53 static int n2rng_detach(dev_info_t *, ddi_detach_cmd_t); 54 static int n2rng_suspend(n2rng_t *); 55 static int n2rng_resume(n2rng_t *); 56 static uint64_t sticks_per_usec(void); 57 u_longlong_t gettick(void); 58 static int n2rng_init_ctl(n2rng_t *); 59 static void n2rng_uninit_ctl(n2rng_t *); 60 static int n2rng_config(n2rng_t *); 61 static void n2rng_config_task(void * targ); 62 63 /* 64 * Device operations. 65 */ 66 67 static struct dev_ops devops = { 68 DEVO_REV, /* devo_rev */ 69 0, /* devo_refcnt */ 70 nodev, /* devo_getinfo */ 71 nulldev, /* devo_identify */ 72 nulldev, /* devo_probe */ 73 n2rng_attach, /* devo_attach */ 74 n2rng_detach, /* devo_detach */ 75 nodev, /* devo_reset */ 76 NULL, /* devo_cb_ops */ 77 NULL, /* devo_bus_ops */ 78 ddi_power, /* devo_power */ 79 ddi_quiesce_not_supported, /* devo_quiesce */ 80 }; 81 82 /* 83 * Module linkage. 84 */ 85 static struct modldrv modldrv = { 86 &mod_driverops, /* drv_modops */ 87 "N2 RNG Driver", /* drv_linkinfo */ 88 &devops, /* drv_dev_ops */ 89 }; 90 91 static struct modlinkage modlinkage = { 92 MODREV_1, /* ml_rev */ 93 &modldrv, /* ml_linkage */ 94 NULL 95 }; 96 97 /* 98 * Driver globals Soft state. 99 */ 100 static void *n2rng_softstate = NULL; 101 102 /* 103 * Hypervisor NCS services information. 104 */ 105 static boolean_t ncs_hsvc_available = B_FALSE; 106 107 #define NVERSIONS 2 108 109 /* 110 * HV API versions supported by this driver. 111 */ 112 static hsvc_info_t ncs_hsvc[NVERSIONS] = { 113 { HSVC_REV_1, NULL, HSVC_GROUP_RNG, 2, 0, DRIVER }, /* v2.0 */ 114 { HSVC_REV_1, NULL, HSVC_GROUP_RNG, 1, 0, DRIVER }, /* v1.0 */ 115 }; 116 int ncs_version_index; /* index into ncs_hsvc[] */ 117 118 /* 119 * DDI entry points. 120 */ 121 int 122 _init(void) 123 { 124 int rv; 125 126 rv = ddi_soft_state_init(&n2rng_softstate, sizeof (n2rng_t), 1); 127 if (rv != 0) { 128 /* this should *never* happen! */ 129 return (rv); 130 } 131 132 if ((rv = mod_install(&modlinkage)) != 0) { 133 /* cleanup here */ 134 ddi_soft_state_fini(&n2rng_softstate); 135 return (rv); 136 } 137 138 return (0); 139 } 140 141 int 142 _fini(void) 143 { 144 int rv; 145 146 rv = mod_remove(&modlinkage); 147 if (rv == 0) { 148 /* cleanup here */ 149 ddi_soft_state_fini(&n2rng_softstate); 150 } 151 152 return (rv); 153 } 154 155 int 156 _info(struct modinfo *modinfop) 157 { 158 return (mod_info(&modlinkage, modinfop)); 159 } 160 161 static int 162 n2rng_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 163 { 164 n2rng_t *n2rng = NULL; 165 int instance; 166 int rv; 167 int version; 168 uint64_t ncs_minor_ver; 169 170 instance = ddi_get_instance(dip); 171 DBG1(NULL, DENTRY, "n2rng_attach called, instance %d", instance); 172 /* 173 * Only instance 0 of n2rng driver is allowed. 174 */ 175 if (instance != 0) { 176 n2rng_diperror(dip, "only one instance (0) allowed"); 177 return (DDI_FAILURE); 178 } 179 180 switch (cmd) { 181 case DDI_RESUME: 182 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, 183 instance); 184 if (n2rng == NULL) { 185 n2rng_diperror(dip, "no soft state in attach"); 186 return (DDI_FAILURE); 187 } 188 return (n2rng_resume(n2rng)); 189 190 case DDI_ATTACH: 191 break; 192 default: 193 return (DDI_FAILURE); 194 } 195 196 rv = ddi_soft_state_zalloc(n2rng_softstate, instance); 197 if (rv != DDI_SUCCESS) { 198 n2rng_diperror(dip, "unable to allocate soft state"); 199 return (DDI_FAILURE); 200 } 201 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, instance); 202 ASSERT(n2rng != NULL); 203 n2rng->n_dip = dip; 204 205 mutex_init(&n2rng->n_lock, NULL, MUTEX_DRIVER, NULL); 206 n2rng->n_flags = 0; 207 n2rng->n_timeout_id = 0; 208 n2rng->n_sticks_per_usec = sticks_per_usec(); 209 210 /* Determine binding type */ 211 n2rng->n_binding_name = ddi_binding_name(dip); 212 if (strncmp(n2rng->n_binding_name, N2RNG_BINDNAME_N2, 213 strlen(N2RNG_BINDNAME_N2)) == 0) { 214 /* 215 * Niagara 2 216 */ 217 n2rng->n_binding = N2RNG_CPU_N2; 218 } else if (strncmp(n2rng->n_binding_name, N2RNG_BINDNAME_VF, 219 strlen(N2RNG_BINDNAME_VF)) == 0) { 220 /* 221 * Victoria Falls 222 */ 223 n2rng->n_binding = N2RNG_CPU_VF; 224 } else if (strncmp(n2rng->n_binding_name, N2RNG_BINDNAME_KT, 225 strlen(N2RNG_BINDNAME_KT)) == 0) { 226 /* 227 * Rainbow Falls 228 */ 229 n2rng->n_binding = N2RNG_CPU_KT; 230 } else { 231 n2rng_diperror(dip, 232 "unable to determine n2rng (cpu) binding (%s)", 233 n2rng->n_binding_name); 234 goto errorexit; 235 } 236 DBG1(n2rng, DCHATTY, "n2rng_attach: n2rng->n_binding_name = %s", 237 n2rng->n_binding_name); 238 239 /* Negotiate HV api version number */ 240 for (version = 0; version < NVERSIONS; version++) { 241 rv = hsvc_register(&ncs_hsvc[version], &ncs_minor_ver); 242 if (rv == 0) 243 break; 244 245 DBG4(n2rng, DCHATTY, "n2rng_attach: grp: 0x%lx, maj: %ld, " 246 "min: %ld, errno: %d", ncs_hsvc[version].hsvc_group, 247 ncs_hsvc[version].hsvc_major, 248 ncs_hsvc[version].hsvc_minor, rv); 249 } 250 if (version == NVERSIONS) { 251 for (version = 0; version < NVERSIONS; version++) { 252 cmn_err(CE_WARN, 253 "%s: cannot negotiate hypervisor services " 254 "group: 0x%lx major: %ld minor: %ld errno: %d", 255 ncs_hsvc[version].hsvc_modname, 256 ncs_hsvc[version].hsvc_group, 257 ncs_hsvc[version].hsvc_major, 258 ncs_hsvc[version].hsvc_minor, rv); 259 } 260 goto errorexit; 261 } 262 ncs_version_index = version; 263 ncs_hsvc_available = B_TRUE; 264 DBG2(n2rng, DATTACH, "n2rng_attach: ncs api version (%ld.%ld)", 265 ncs_hsvc[ncs_version_index].hsvc_major, ncs_minor_ver); 266 n2rng->n_hvapi_major_version = ncs_hsvc[ncs_version_index].hsvc_major; 267 n2rng->n_hvapi_minor_version = (uint_t)ncs_minor_ver; 268 269 /* 270 * Verify that we are running version 2.0 or later api on multiple 271 * rng systems. 272 */ 273 if ((n2rng->n_binding != N2RNG_CPU_N2) && 274 (n2rng->n_hvapi_major_version < 2)) { 275 cmn_err(CE_NOTE, "n2rng: Incompatible hyperviser api " 276 "version %d.%d detected", n2rng->n_hvapi_major_version, 277 n2rng->n_hvapi_minor_version); 278 } 279 280 /* Initialize ctl structure if runnning in the control domain */ 281 if (n2rng_init_ctl(n2rng) != DDI_SUCCESS) { 282 cmn_err(CE_WARN, "n2rng: unable to initialize rng " 283 "control structures"); 284 goto errorexit; 285 } 286 287 /* Allocate single thread task queue for rng diags and registration */ 288 n2rng->n_taskq = ddi_taskq_create(dip, "n2rng_taskq", 1, 289 TASKQ_DEFAULTPRI, 0); 290 291 if (n2rng->n_taskq == NULL) { 292 n2rng_diperror(dip, "ddi_taskq_create() failed"); 293 goto errorexit; 294 } 295 296 /* Dispatch task to configure the RNG and register with KCF */ 297 if (ddi_taskq_dispatch(n2rng->n_taskq, n2rng_config_task, 298 (void *)n2rng, DDI_SLEEP) != DDI_SUCCESS) { 299 n2rng_diperror(dip, "ddi_taskq_dispatch() failed"); 300 goto errorexit; 301 } 302 303 return (DDI_SUCCESS); 304 305 errorexit: 306 /* Wait for pending config tasks to complete and delete the taskq */ 307 if (n2rng->n_taskq != NULL) { 308 ddi_taskq_destroy(n2rng->n_taskq); 309 n2rng->n_taskq = NULL; 310 } 311 312 n2rng_uninit_ctl(n2rng); 313 314 (void) n2rng_uninit(n2rng); 315 316 if (ncs_hsvc_available == B_TRUE) { 317 (void) hsvc_unregister(&ncs_hsvc[ncs_version_index]); 318 ncs_hsvc_available = B_FALSE; 319 } 320 321 mutex_destroy(&n2rng->n_lock); 322 ddi_soft_state_free(n2rng_softstate, instance); 323 324 return (DDI_FAILURE); 325 } 326 327 static int 328 n2rng_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 329 { 330 int instance; 331 int rv; 332 n2rng_t *n2rng; 333 timeout_id_t tid; 334 335 instance = ddi_get_instance(dip); 336 n2rng = (n2rng_t *)ddi_get_soft_state(n2rng_softstate, instance); 337 if (n2rng == NULL) { 338 n2rng_diperror(dip, "no soft state in detach"); 339 return (DDI_FAILURE); 340 } 341 342 switch (cmd) { 343 case DDI_SUSPEND: 344 return (n2rng_suspend(n2rng)); 345 case DDI_DETACH: 346 break; 347 default: 348 return (DDI_FAILURE); 349 } 350 351 /* Destroy task queue first to insure configuration has completed */ 352 if (n2rng->n_taskq != NULL) { 353 ddi_taskq_destroy(n2rng->n_taskq); 354 n2rng->n_taskq = NULL; 355 } 356 357 /* Untimeout pending config retry operations */ 358 mutex_enter(&n2rng->n_lock); 359 tid = n2rng->n_timeout_id; 360 n2rng->n_timeout_id = 0; 361 mutex_exit(&n2rng->n_lock); 362 if (tid) { 363 DBG1(n2rng, DCHATTY, "n2rng_detach: untimeout pending retry " 364 "id = %x", tid); 365 (void) untimeout(tid); 366 } 367 368 n2rng_uninit_ctl(n2rng); 369 370 /* unregister with KCF---also tears down FIPS state */ 371 rv = n2rng_uninit(n2rng) ? DDI_FAILURE : DDI_SUCCESS; 372 373 if (ncs_hsvc_available == B_TRUE) { 374 (void) hsvc_unregister(&ncs_hsvc[ncs_version_index]); 375 ncs_hsvc_available = B_FALSE; 376 } 377 378 mutex_destroy(&n2rng->n_lock); 379 ddi_soft_state_free(n2rng_softstate, instance); 380 381 return (rv); 382 } 383 384 /*ARGSUSED*/ 385 static int 386 n2rng_suspend(n2rng_t *n2rng) 387 { 388 /* unregister with KCF---also tears down FIPS state */ 389 if (n2rng_uninit(n2rng) != DDI_SUCCESS) { 390 cmn_err(CE_WARN, "n2rng: unable to unregister from KCF"); 391 return (DDI_FAILURE); 392 } 393 394 return (DDI_SUCCESS); 395 } 396 397 /*ARGSUSED*/ 398 static int 399 n2rng_resume(n2rng_t *n2rng) 400 { 401 /* Assume clock is same speed and all data structures are intact */ 402 403 /* Re-configure the RNG hardware and register with KCF */ 404 return (n2rng_config(n2rng)); 405 } 406 407 /* 408 * Map hypervisor error code to solaris. Only 409 * H_ENORADDR, H_EBADALIGN, H_EWOULDBLOCK, and EIO 410 * are meaningful to this device. Any other error 411 * codes are mapped EINVAL. 412 */ 413 int 414 n2rng_herr2kerr(uint64_t hv_errcode) 415 { 416 int s_errcode; 417 418 switch (hv_errcode) { 419 case H_EWOULDBLOCK: 420 s_errcode = EWOULDBLOCK; 421 break; 422 case H_EIO: 423 s_errcode = EIO; 424 break; 425 case H_EBUSY: 426 s_errcode = EBUSY; 427 break; 428 case H_EOK: 429 s_errcode = 0; 430 break; 431 case H_ENOACCESS: 432 s_errcode = EPERM; 433 break; 434 case H_ENORADDR: 435 case H_EBADALIGN: 436 default: 437 s_errcode = EINVAL; 438 break; 439 } 440 return (s_errcode); 441 } 442 443 /* 444 * Waits approximately delay_sticks counts of the stick register. 445 * Times shorter than one sys clock tick (10ms on most systems) are 446 * done by busy waiting. 447 */ 448 void 449 cyclesleep(n2rng_t *n2rng, uint64_t delay_sticks) 450 { 451 uint64_t end_stick = gettick() + delay_sticks; 452 int64_t sticks_to_wait; 453 clock_t sys_ticks_to_wait; 454 clock_t usecs_to_wait; 455 456 /*CONSTCOND*/ 457 while (1) { 458 sticks_to_wait = end_stick - gettick(); 459 if (sticks_to_wait <= 0) { 460 return; 461 } 462 463 usecs_to_wait = sticks_to_wait / n2rng->n_sticks_per_usec; 464 sys_ticks_to_wait = drv_usectohz(usecs_to_wait); 465 466 if (sys_ticks_to_wait > 0) { 467 /* sleep */ 468 delay(sys_ticks_to_wait); 469 } else if (usecs_to_wait > 0) { 470 /* busy wait */ 471 drv_usecwait(usecs_to_wait); 472 } 473 } 474 } 475 476 static void 477 log_internal_errors(uint64_t hverr, char *fname) 478 { 479 switch (hverr) { 480 case H_EBADALIGN: 481 cmn_err(CE_WARN, 482 "n2rng: internal alignment " 483 "problem"); 484 break; 485 case H_ENORADDR: 486 cmn_err(CE_WARN, "n2rng: internal " 487 "invalid address"); 488 break; 489 case H_ENOACCESS: 490 cmn_err(CE_WARN, "n2rng: access failure"); 491 break; 492 case H_EWOULDBLOCK: 493 cmn_err(CE_WARN, "n2rng: hardware busy"); 494 break; 495 default: 496 cmn_err(CE_NOTE, 497 "n2rng: %s " 498 "unexpectedly " 499 "returned hverr %ld", fname, hverr); 500 break; 501 } 502 } 503 504 /* 505 * Collects a buffer full of bits, using the specified setup. numbytes 506 * must be a multiple of 8. If a sub-operation fails with EIO (handle 507 * mismatch), returns EIO. If collect_setupp is NULL, the current 508 * setup is used. If exit_setupp is NULL, the control configuratin 509 * and state are not set at exit. WARNING: the buffer must be 8-byte 510 * aligned and in contiguous physical addresses. Contiguousness is 511 * not checked! 512 */ 513 int 514 n2rng_collect_diag_bits(n2rng_t *n2rng, int rngid, 515 n2rng_setup_t *collect_setupp, void *buffer, int numbytes, 516 n2rng_setup_t *exit_setupp, uint64_t exitstate) 517 { 518 int rv; 519 int override_rv = 0; 520 uint64_t hverr; 521 int i; 522 uint64_t tdelta; 523 n2rng_setup_t setupbuffer[2]; 524 n2rng_setup_t *setupcontigp; 525 uint64_t setupphys; 526 int numchunks; 527 boolean_t rnglooping; 528 int busycount = 0; 529 int blockcount = 0; 530 531 if (numbytes % sizeof (uint64_t)) { 532 return (EINVAL); 533 } 534 535 if ((uint64_t)buffer % sizeof (uint64_t) != 0) { 536 return (EINVAL); 537 } 538 539 numchunks = ((numbytes / sizeof (uint64_t)) + RNG_DIAG_CHUNK_SIZE - 1) 540 / RNG_DIAG_CHUNK_SIZE; 541 /* 542 * Use setupbuffer[0] if it is contiguous, otherwise 543 * setupbuffer[1]. 544 */ 545 setupcontigp = &setupbuffer[ 546 CONTIGUOUS(&setupbuffer[0], n2rng_setup_t) ? 0 : 1]; 547 setupphys = va_to_pa(setupcontigp); 548 549 /* 550 * If a non-null collect_setupp pointer has been provided, 551 * push the specified setup into the hardware. 552 */ 553 if (collect_setupp != NULL) { 554 /* copy the specified state to the aligned buffer */ 555 *setupcontigp = *collect_setupp; 556 rnglooping = B_TRUE; 557 while (rnglooping) { 558 hverr = n2rng_ctl_write(n2rng, rngid, setupphys, 559 CTL_STATE_HEALTHCHECK, 560 n2rng->n_ctl_data->n_watchdog_cycles, &tdelta); 561 rv = n2rng_herr2kerr(hverr); 562 switch (hverr) { 563 case H_EOK: 564 rnglooping = B_FALSE; 565 break; 566 case H_EIO: /* control yanked from us */ 567 case H_ENOACCESS: /* We are not control domain */ 568 return (rv); 569 case H_EWOULDBLOCK: 570 /* Data currently not available, try again */ 571 if (++blockcount > RNG_MAX_BLOCK_ATTEMPTS) { 572 DBG1(n2rng, DHEALTH, 573 "n2rng_collect_diag_bits(1) : " 574 "exceeded block count of %d", 575 RNG_MAX_BLOCK_ATTEMPTS); 576 return (rv); 577 } else { 578 cyclesleep(n2rng, tdelta); 579 } 580 break; 581 case H_EBUSY: 582 /* 583 * A control write is already in progress. 584 * Note: This shouldn't happen since 585 * n2rng_ctl_write() waits for the 586 * write to complete. 587 */ 588 if (++busycount > RNG_MAX_BUSY_ATTEMPTS) { 589 DBG1(n2rng, DHEALTH, 590 "n2rng_collect_diag_bits(1): " 591 "exceeded busy count of %d", 592 RNG_MAX_BUSY_ATTEMPTS); 593 return (rv); 594 } else { 595 delay(RNG_RETRY_BUSY_DELAY); 596 } 597 break; 598 default: 599 log_internal_errors(hverr, "hv_rng_ctl_write"); 600 override_rv = rv; 601 goto restore_state; 602 } 603 } /* while (rnglooping) */ 604 } /* if (collect_setupp != NULL) */ 605 606 /* If the caller asks for some bytes, collect the data */ 607 if (numbytes > 0) { 608 for (i = 0; i < numchunks; i++) { 609 size_t thisnumbytes = (i == numchunks - 1) ? 610 numbytes - i * (RNG_DIAG_CHUNK_SIZE * 611 sizeof (uint64_t)) : 612 RNG_DIAG_CHUNK_SIZE * sizeof (uint64_t); 613 614 /* try until we successfully read a word of data */ 615 rnglooping = B_TRUE; 616 busycount = 0; 617 blockcount = 0; 618 while (rnglooping) { 619 hverr = n2rng_data_read_diag(n2rng, rngid, 620 va_to_pa((uint64_t *)buffer + 621 RNG_DIAG_CHUNK_SIZE * i), 622 thisnumbytes, &tdelta); 623 rv = n2rng_herr2kerr(hverr); 624 switch (hverr) { 625 case H_EOK: 626 rnglooping = B_FALSE; 627 break; 628 case H_EIO: 629 case H_ENOACCESS: 630 return (rv); 631 case H_EWOULDBLOCK: 632 /* Data not available, try again */ 633 if (++blockcount > 634 RNG_MAX_BLOCK_ATTEMPTS) { 635 DBG1(n2rng, DHEALTH, 636 "n2rng_collect_diag_bits" 637 "(2): exceeded block count" 638 " of %d", 639 RNG_MAX_BLOCK_ATTEMPTS); 640 return (rv); 641 } else { 642 cyclesleep(n2rng, tdelta); 643 } 644 break; 645 default: 646 log_internal_errors(hverr, 647 "hv_rng_data_read_diag"); 648 override_rv = rv; 649 goto restore_state; 650 } 651 } /* while (!rnglooping) */ 652 } /* for */ 653 } 654 655 restore_state: 656 657 /* restore the preferred configuration and set exit state */ 658 if (exit_setupp != NULL) { 659 660 *setupcontigp = *exit_setupp; 661 rnglooping = B_TRUE; 662 busycount = 0; 663 blockcount = 0; 664 while (rnglooping) { 665 hverr = n2rng_ctl_write(n2rng, rngid, setupphys, 666 exitstate, n2rng->n_ctl_data->n_watchdog_cycles, 667 &tdelta); 668 rv = n2rng_herr2kerr(hverr); 669 switch (hverr) { 670 case H_EOK: 671 case H_EIO: /* control yanked from us */ 672 case H_EINVAL: /* some external error, probably */ 673 case H_ENOACCESS: /* We are not control domain */ 674 rnglooping = B_FALSE; 675 break; 676 case H_EWOULDBLOCK: 677 /* Data currently not available, try again */ 678 if (++blockcount > RNG_MAX_BLOCK_ATTEMPTS) { 679 DBG1(n2rng, DHEALTH, 680 "n2rng_collect_diag_bits(3): " 681 "exceeded block count of %d", 682 RNG_MAX_BLOCK_ATTEMPTS); 683 return (rv); 684 } else { 685 cyclesleep(n2rng, tdelta); 686 } 687 break; 688 case H_EBUSY: 689 /* 690 * A control write is already in progress. 691 * Note: This shouldn't happen since 692 * n2rng_ctl_write() waits for the 693 * write to complete. 694 */ 695 if (++busycount > RNG_MAX_BUSY_ATTEMPTS) { 696 DBG1(n2rng, DHEALTH, 697 "n2rng_collect_diag_bits(3): " 698 "exceeded busy count of %d", 699 RNG_MAX_BUSY_ATTEMPTS); 700 return (rv); 701 } else { 702 delay(RNG_RETRY_BUSY_DELAY); 703 } 704 break; 705 default: 706 rnglooping = B_FALSE; 707 log_internal_errors(hverr, "hv_rng_ctl_write"); 708 break; 709 } 710 } /* while */ 711 } /* if */ 712 713 /* 714 * override_rv takes care of the case where we abort becuase 715 * of some error, but still want to restore the peferred state 716 * and return the first error, even if other error occur. 717 */ 718 return (override_rv ? override_rv : rv); 719 } 720 721 int 722 n2rng_getentropy(n2rng_t *n2rng, void *buffer, size_t size) 723 { 724 int i, rv = 0; /* so it works if size is zero */ 725 uint64_t hverr; 726 uint64_t *buffer_w = (uint64_t *)buffer; 727 int num_w = size / sizeof (uint64_t); 728 uint64_t randval; 729 uint64_t randvalphys = va_to_pa(&randval); 730 uint64_t tdelta; 731 int failcount = 0; 732 int blockcount = 0; 733 boolean_t rnglooping; 734 735 for (i = 0; i < num_w; i++) { 736 rnglooping = B_TRUE; 737 while (rnglooping) { 738 hverr = hv_rng_data_read(randvalphys, &tdelta); 739 rv = n2rng_herr2kerr(hverr); 740 switch (hverr) { 741 case H_EOK: 742 buffer_w[i] = randval; 743 failcount = 0; 744 rnglooping = B_FALSE; 745 break; 746 case H_EIO: 747 /* 748 * Either a health check is in progress, or 749 * the watchdog timer has expired while running 750 * hv api version 2.0 or higher with health 751 * checks enabled. 752 */ 753 if (n2rng->n_hvapi_major_version < 2) { 754 /* 755 * A health check is in progress. 756 * Wait RNG_RETRY_HLCHK_USECS and fail 757 * after RNG_MAX_DATA_READ_ATTEMPTS 758 * failures. 759 */ 760 if (++failcount > 761 RNG_MAX_DATA_READ_ATTEMPTS) { 762 DBG2(n2rng, DHEALTH, 763 "n2rng_getentropy: exceeded" 764 "EIO count of %d on cpu %d", 765 RNG_MAX_DATA_READ_ATTEMPTS, 766 CPU->cpu_id); 767 goto exitpoint; 768 } else { 769 delay(drv_usectohz 770 (RNG_RETRY_HLCHK_USECS)); 771 } 772 } else { 773 /* 774 * Just return the error. If a flurry of 775 * random data requests happen to occur 776 * during a health check, there are 777 * multiple levels of defense: 778 * - 2.0 HV provides random data pool 779 * - FIPS algorithm tolerates failures 780 * - Software failover 781 * - Automatic configuration retries 782 * - Hardware failover on some systems 783 */ 784 goto exitpoint; 785 } 786 break; 787 case H_EWOULDBLOCK: 788 /* Data currently not available, try again */ 789 if (++blockcount > RNG_MAX_BLOCK_ATTEMPTS) { 790 DBG1(n2rng, DHEALTH, 791 "n2rng_getentropy: " 792 "exceeded block count of %d", 793 RNG_MAX_BLOCK_ATTEMPTS); 794 goto exitpoint; 795 } else { 796 cyclesleep(n2rng, tdelta); 797 } 798 break; 799 default: 800 log_internal_errors(hverr, "hv_rng_data_read"); 801 goto exitpoint; 802 } 803 } /* while */ 804 } /* for */ 805 806 exitpoint: 807 return (rv); 808 } 809 810 uint64_t 811 n2rng_ctl_read(n2rng_t *n2rng, int rngid, uint64_t ctlregs_pa, uint64_t *state, 812 uint64_t *tdelta, uint64_t *wdelta) 813 { 814 uint64_t rv; 815 uint64_t wstatus; 816 817 /* Call correct hv function based on api version */ 818 if (n2rng->n_hvapi_major_version == 2) { 819 rv = hv_rng_ctl_read_v2(ctlregs_pa, (uint64_t)rngid, state, 820 tdelta, wdelta, &wstatus); 821 if (rv == 0) { 822 rv = wstatus; 823 } 824 } else { 825 rv = hv_rng_ctl_read(ctlregs_pa, state, tdelta); 826 *wdelta = 0; 827 } 828 829 return (rv); 830 } 831 832 uint64_t 833 n2rng_ctl_wait(n2rng_t *n2rng, int rngid) 834 { 835 uint64_t state; 836 uint64_t tdelta; 837 uint64_t wdelta; 838 uint64_t wstatus; 839 boolean_t rnglooping = B_TRUE; 840 uint64_t rv; 841 n2rng_setup_t setupbuffer[2]; 842 n2rng_setup_t *setupcontigp; 843 uint64_t setupphys; 844 int busycount = 0; 845 int blockcount = 0; 846 847 /* 848 * Use setupbuffer[0] if it is contiguous, otherwise 849 * setupbuffer[1]. 850 */ 851 setupcontigp = &setupbuffer[ 852 CONTIGUOUS(&setupbuffer[0], n2rng_setup_t) ? 0 : 1]; 853 setupphys = va_to_pa(setupcontigp); 854 855 while (rnglooping) { 856 rv = hv_rng_ctl_read_v2(setupphys, (uint64_t)rngid, &state, 857 &tdelta, &wdelta, &wstatus); 858 switch (rv) { 859 case H_EOK: 860 rv = wstatus; 861 rnglooping = B_FALSE; 862 break; 863 case H_EWOULDBLOCK: 864 /* Data currently not available, try again */ 865 if (++blockcount > RNG_MAX_BLOCK_ATTEMPTS) { 866 DBG1(n2rng, DHEALTH, "n2rng_ctl_wait: " 867 "exceeded block count of %d", 868 RNG_MAX_BLOCK_ATTEMPTS); 869 return (rv); 870 } else { 871 cyclesleep(n2rng, tdelta); 872 } 873 break; 874 case H_EBUSY: 875 /* Control write still pending, try again */ 876 if (++busycount > RNG_MAX_BUSY_ATTEMPTS) { 877 DBG1(n2rng, DHEALTH, "n2rng_ctl_wait: " 878 "exceeded busy count of %d", 879 RNG_MAX_BUSY_ATTEMPTS); 880 return (rv); 881 } else { 882 delay(RNG_RETRY_BUSY_DELAY); 883 } 884 break; 885 default: 886 log_internal_errors(rv, "n2rng_ctl_wait"); 887 rnglooping = B_FALSE; 888 } 889 } /* while (rnglooping) */ 890 891 return (rv); 892 } 893 894 uint64_t 895 n2rng_ctl_write(n2rng_t *n2rng, int rngid, uint64_t ctlregs_pa, 896 uint64_t newstate, uint64_t wtimeout, uint64_t *tdelta) 897 { 898 uint64_t rv; 899 900 /* Call correct hv function based on api version */ 901 if (n2rng->n_hvapi_major_version == 2) { 902 rv = hv_rng_ctl_write_v2(ctlregs_pa, newstate, wtimeout, 903 (uint64_t)rngid); 904 if (rv == H_EOK) { 905 /* Wait for control registers to be written */ 906 rv = n2rng_ctl_wait(n2rng, rngid); 907 } 908 *tdelta = RNG_DEFAULT_ACCUMULATE_CYCLES; 909 } else { 910 rv = hv_rng_ctl_write(ctlregs_pa, newstate, wtimeout, tdelta); 911 } 912 913 return (rv); 914 } 915 916 uint64_t 917 n2rng_data_read_diag(n2rng_t *n2rng, int rngid, uint64_t data_pa, 918 size_t datalen, uint64_t *tdelta) 919 { 920 uint64_t rv; 921 922 /* Call correct hv function based on api version */ 923 if (n2rng->n_hvapi_major_version == 2) { 924 rv = hv_rng_data_read_diag_v2(data_pa, datalen, 925 (uint64_t)rngid, tdelta); 926 if (*tdelta == 0) { 927 *tdelta = RNG_DEFAULT_ACCUMULATE_CYCLES; 928 } 929 } else { 930 rv = hv_rng_data_read_diag(data_pa, datalen, tdelta); 931 } 932 933 return (rv); 934 } 935 936 uint64_t 937 n2rng_check_ctl_access(n2rng_t *n2rng) 938 { 939 uint64_t rv; 940 uint64_t unused_64; 941 942 /* Call correct hv function based on api version */ 943 if (n2rng->n_hvapi_major_version == 2) { 944 /* 945 * Attempt to read control registers with invalid ID and data 946 * just to see if we get an access error 947 */ 948 rv = hv_rng_ctl_read_v2(NULL, N2RNG_INVALID_ID, 949 &unused_64, &unused_64, &unused_64, &unused_64); 950 } else { 951 rv = hv_rng_get_diag_control(); 952 } 953 954 return (rv); 955 } 956 957 /* 958 * n2rng_config_retry() 959 * 960 * Schedule a timed call to n2rng_config() if one is not already pending 961 */ 962 void 963 n2rng_config_retry(n2rng_t *n2rng, clock_t seconds) 964 { 965 mutex_enter(&n2rng->n_lock); 966 /* Check if a config retry is already pending */ 967 if (n2rng->n_timeout_id) { 968 DBG1(n2rng, DCFG, "n2rng_config_retry: retry pending " 969 "id = %x", n2rng->n_timeout_id); 970 } else { 971 n2rng->n_timeout_id = timeout(n2rng_config_task, 972 (void *)n2rng, drv_usectohz(seconds * SECOND)); 973 DBG2(n2rng, DCFG, "n2rng_config_retry: retry scheduled in " 974 "%d seconds, id = %x", seconds, n2rng->n_timeout_id); 975 } 976 mutex_exit(&n2rng->n_lock); 977 } 978 979 static uint64_t 980 sticks_per_usec(void) 981 { 982 uint64_t starttick = gettick(); 983 hrtime_t starttime = gethrtime(); 984 uint64_t endtick; 985 hrtime_t endtime; 986 987 delay(2); 988 989 endtick = gettick(); 990 endtime = gethrtime(); 991 992 return ((1000 * (endtick - starttick)) / (endtime - starttime)); 993 } 994 995 static int 996 n2rng_init_ctl(n2rng_t *n2rng) 997 { 998 int rv; 999 int hverr; 1000 rng_entry_t *rng; 1001 int rngid; 1002 int blockcount = 0; 1003 1004 n2rng->n_ctl_data = NULL; 1005 1006 /* Attempt to gain diagnostic control */ 1007 do { 1008 hverr = n2rng_check_ctl_access(n2rng); 1009 rv = n2rng_herr2kerr(hverr); 1010 if ((hverr == H_EWOULDBLOCK) && 1011 (++blockcount > RNG_MAX_BUSY_ATTEMPTS)) { 1012 DBG1(n2rng, DHEALTH, "n2rng_int_ctl: exceeded busy " 1013 "count of %d", RNG_MAX_BUSY_ATTEMPTS); 1014 return (rv); 1015 } else { 1016 delay(RNG_RETRY_BUSY_DELAY); 1017 } 1018 } while (hverr == H_EWOULDBLOCK); 1019 1020 /* 1021 * If attempt fails with EPERM, the driver is not running in the 1022 * control domain 1023 */ 1024 if (rv == EPERM) { 1025 DBG0(n2rng, DATTACH, 1026 "n2rng_init_ctl: Running in guest domain"); 1027 return (DDI_SUCCESS); 1028 } 1029 1030 /* Allocate control stucture only used in control domain */ 1031 n2rng->n_ctl_data = kmem_alloc(sizeof (rng_ctl_data_t), KM_SLEEP); 1032 n2rng->n_ctl_data->n_num_rngs_online = 0; 1033 1034 /* 1035 * If running with an API version less than 2.0 default to one rng. 1036 * Otherwise get number of rngs from device properties. 1037 */ 1038 if (n2rng->n_hvapi_major_version < 2) { 1039 n2rng->n_ctl_data->n_num_rngs = 1; 1040 } else { 1041 n2rng->n_ctl_data->n_num_rngs = 1042 ddi_getprop(DDI_DEV_T_ANY, n2rng->n_dip, 1043 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, 1044 N2RNG_PROP_NUM_UNITS, 0); 1045 if (n2rng->n_ctl_data->n_num_rngs == 0) { 1046 cmn_err(CE_WARN, "n2rng: %s property not found", 1047 N2RNG_PROP_NUM_UNITS); 1048 return (DDI_FAILURE); 1049 } 1050 } 1051 1052 /* Allocate space for all rng entries */ 1053 n2rng->n_ctl_data->n_rngs = 1054 kmem_zalloc(n2rng->n_ctl_data->n_num_rngs * 1055 sizeof (rng_entry_t), KM_SLEEP); 1056 1057 /* Get accumulate cycles from .conf file. */ 1058 n2rng->n_ctl_data->n_accumulate_cycles = 1059 ddi_getprop(DDI_DEV_T_ANY, n2rng->n_dip, 1060 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "acc_cycles", 1061 RNG_DEFAULT_ACCUMULATE_CYCLES); 1062 1063 /* Get health check frequency from .conf file */ 1064 n2rng->n_ctl_data->n_hc_secs = ddi_getprop(DDI_DEV_T_ANY, n2rng->n_dip, 1065 DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "hc_seconds", 1066 RNG_DEFAULT_HC_SECS); 1067 1068 /* API versions prior to 2.0 do not support health checks */ 1069 if ((n2rng->n_hvapi_major_version < 2) && 1070 (n2rng->n_ctl_data->n_hc_secs > 0)) { 1071 cmn_err(CE_WARN, "n2rng: Hyperviser api " 1072 "version %d.%d does not support health checks", 1073 n2rng->n_hvapi_major_version, 1074 n2rng->n_hvapi_minor_version); 1075 n2rng->n_ctl_data->n_hc_secs = 0; 1076 } 1077 1078 /* Calculate watchdog timeout value */ 1079 if (n2rng->n_ctl_data->n_hc_secs <= 0) { 1080 n2rng->n_ctl_data->n_watchdog_cycles = 0; 1081 } else { 1082 n2rng->n_ctl_data->n_watchdog_cycles = 1083 ((uint64_t)(RNG_EXTRA_WATCHDOG_SECS) + 1084 n2rng->n_ctl_data->n_hc_secs) * 1085 n2rng->n_sticks_per_usec * 1000000; 1086 } 1087 1088 /* 1089 * Set some plausible state into the preferred configuration. 1090 * The intent is that the health check will immediately overwrite it. 1091 */ 1092 for (rngid = 0; rngid < n2rng->n_ctl_data->n_num_rngs; rngid++) { 1093 1094 rng = &n2rng->n_ctl_data->n_rngs[rngid]; 1095 1096 rng->n_preferred_config.ctlwds[0].word = 0; 1097 rng->n_preferred_config.ctlwds[0].fields.rnc_anlg_sel = 1098 N2RNG_NOANALOGOUT; 1099 rng->n_preferred_config.ctlwds[0].fields.rnc_cnt = 1100 RNG_DEFAULT_ACCUMULATE_CYCLES; 1101 rng->n_preferred_config.ctlwds[0].fields.rnc_mode = 1102 RNG_MODE_NORMAL; 1103 rng->n_preferred_config.ctlwds[1].word = 1104 rng->n_preferred_config.ctlwds[0].word; 1105 rng->n_preferred_config.ctlwds[2].word = 1106 rng->n_preferred_config.ctlwds[0].word; 1107 rng->n_preferred_config.ctlwds[3].word = 1108 rng->n_preferred_config.ctlwds[0].word; 1109 rng->n_preferred_config.ctlwds[0].fields.rnc_vcoctl = 1; 1110 rng->n_preferred_config.ctlwds[0].fields.rnc_selbits = 1; 1111 rng->n_preferred_config.ctlwds[1].fields.rnc_vcoctl = 2; 1112 rng->n_preferred_config.ctlwds[1].fields.rnc_selbits = 2; 1113 rng->n_preferred_config.ctlwds[2].fields.rnc_vcoctl = 3; 1114 rng->n_preferred_config.ctlwds[2].fields.rnc_selbits = 4; 1115 rng->n_preferred_config.ctlwds[3].fields.rnc_vcoctl = 0; 1116 rng->n_preferred_config.ctlwds[3].fields.rnc_selbits = 7; 1117 } 1118 1119 n2rng_setcontrol(n2rng); 1120 DBG2(n2rng, DATTACH, 1121 "n2rng_init_ctl: Running in control domain with %d rng device%s", 1122 n2rng->n_ctl_data->n_num_rngs, 1123 (n2rng->n_ctl_data->n_num_rngs == 1) ? "" : "s"); 1124 DBG2(n2rng, DCFG, 1125 "n2rng_init_ctl: n_sticks_per_usec = %ld, n_hc_secs = %d", 1126 n2rng->n_sticks_per_usec, 1127 n2rng->n_ctl_data->n_hc_secs); 1128 DBG2(n2rng, DCFG, 1129 "n2rng_init_ctl: n_watchdog_cycles = %ld, " 1130 "n_accumulate_cycles = %ld", n2rng->n_ctl_data->n_watchdog_cycles, 1131 n2rng->n_ctl_data->n_accumulate_cycles); 1132 1133 return (DDI_SUCCESS); 1134 } 1135 1136 static void 1137 n2rng_uninit_ctl(n2rng_t *n2rng) 1138 { 1139 if (n2rng->n_ctl_data) { 1140 if (n2rng->n_ctl_data->n_num_rngs) { 1141 kmem_free(n2rng->n_ctl_data->n_rngs, 1142 n2rng->n_ctl_data->n_num_rngs * 1143 sizeof (rng_entry_t)); 1144 n2rng->n_ctl_data->n_rngs = NULL; 1145 n2rng->n_ctl_data->n_num_rngs = 0; 1146 } 1147 kmem_free(n2rng->n_ctl_data, sizeof (rng_ctl_data_t)); 1148 n2rng->n_ctl_data = NULL; 1149 } 1150 } 1151 1152 1153 /* 1154 * n2rng_config_test() 1155 * 1156 * Attempt read random data to see if the rng is configured. 1157 */ 1158 int 1159 n2rng_config_test(n2rng_t *n2rng) 1160 { 1161 int rv = 0; 1162 uint64_t hverr; 1163 uint64_t randval = 0; 1164 uint64_t randvalphys = va_to_pa(&randval); 1165 uint64_t tdelta; 1166 int failcount = 0; 1167 int blockcount = 0; 1168 boolean_t rnglooping = B_TRUE; 1169 1170 while (rnglooping) { 1171 hverr = hv_rng_data_read(randvalphys, &tdelta); 1172 rv = n2rng_herr2kerr(hverr); 1173 switch (hverr) { 1174 case H_EOK: 1175 failcount = 0; 1176 rnglooping = B_FALSE; 1177 break; 1178 case H_EIO: 1179 /* 1180 * A health check is in progress. 1181 * Wait RNG_RETRY_HLCHK_USECS and fail 1182 * after RNG_MAX_DATA_READ_ATTEMPTS 1183 * failures. 1184 */ 1185 if (++failcount > RNG_MAX_DATA_READ_ATTEMPTS) { 1186 goto exitpoint; 1187 } else { 1188 delay(drv_usectohz(RNG_RETRY_HLCHK_USECS)); 1189 } 1190 break; 1191 case H_EWOULDBLOCK: 1192 /* Data currently not available, try again */ 1193 if (++blockcount > RNG_MAX_BLOCK_ATTEMPTS) { 1194 DBG1(n2rng, DHEALTH, "n2rng_config_test: " 1195 "exceeded block count of %d", 1196 RNG_MAX_BLOCK_ATTEMPTS); 1197 goto exitpoint; 1198 } else { 1199 cyclesleep(n2rng, tdelta); 1200 } 1201 break; 1202 case H_ENOACCESS: 1203 /* An rng error has occured during health check */ 1204 goto exitpoint; 1205 default: 1206 log_internal_errors(hverr, "hv_rng_data_read"); 1207 goto exitpoint; 1208 } 1209 } /* while */ 1210 1211 exitpoint: 1212 return (rv); 1213 } 1214 1215 /* 1216 * n2rng_config() 1217 * 1218 * Run health check on the RNG hardware 1219 * Configure the RNG hardware 1220 * Register with crypto framework 1221 */ 1222 static int 1223 n2rng_config(n2rng_t *n2rng) 1224 { 1225 int rv; 1226 rng_entry_t *rng; 1227 int rngid; 1228 1229 /* 1230 * Run health checks and configure rngs if running in control domain, 1231 * otherwise just check if at least one rng is available. 1232 */ 1233 if (n2rng_iscontrol(n2rng)) { 1234 1235 for (rngid = 0; rngid < n2rng->n_ctl_data->n_num_rngs; 1236 rngid++) { 1237 1238 rng = &n2rng->n_ctl_data->n_rngs[rngid]; 1239 1240 /* Only test rngs that have not already failed */ 1241 if (rng->n_rng_state == CTL_STATE_ERROR) { 1242 continue; 1243 } 1244 1245 if ((n2rng->n_binding == N2RNG_CPU_VF) && 1246 (n2rng->n_hvapi_major_version < 2)) { 1247 /* 1248 * Since api versions prior to 2.0 do not 1249 * support multiple rngs, bind to the current 1250 * processor for the entire health check 1251 * process. 1252 */ 1253 thread_affinity_set(curthread, CPU_CURRENT); 1254 DBG1(n2rng, DCFG, "n2rng_config: " 1255 "Configuring single rng from cpu %d", 1256 CPU->cpu_id); 1257 rv = n2rng_do_health_check(n2rng, rngid); 1258 thread_affinity_clear(curthread); 1259 } else { 1260 rv = n2rng_do_health_check(n2rng, rngid); 1261 } 1262 1263 switch (rv) { 1264 case 0: 1265 /* 1266 * Successful, increment online count if 1267 * necessary 1268 */ 1269 DBG1(n2rng, DCFG, "n2rng_config: rng(%d) " 1270 "passed health checks", rngid); 1271 if (rng->n_rng_state != CTL_STATE_CONFIGURED) { 1272 rng->n_rng_state = 1273 CTL_STATE_CONFIGURED; 1274 n2rng->n_ctl_data->n_num_rngs_online++; 1275 } 1276 break; 1277 default: 1278 /* 1279 * Health checks failed, decrement online 1280 * count if necessary 1281 */ 1282 cmn_err(CE_WARN, "n2rng: rng(%d) " 1283 "failed health checks", rngid); 1284 if (rng->n_rng_state == CTL_STATE_CONFIGURED) { 1285 n2rng->n_ctl_data->n_num_rngs_online--; 1286 } 1287 rng->n_rng_state = CTL_STATE_ERROR; 1288 break; 1289 } 1290 } 1291 DBG2(n2rng, DCFG, "n2rng_config: %d rng%s online", 1292 n2rng->n_ctl_data->n_num_rngs_online, 1293 (n2rng->n_ctl_data->n_num_rngs_online == 1) ? "" : "s"); 1294 1295 /* Check if all rngs have failed */ 1296 if (n2rng->n_ctl_data->n_num_rngs_online == 0) { 1297 cmn_err(CE_WARN, "n2rng: %d RNG device%s failed", 1298 n2rng->n_ctl_data->n_num_rngs, 1299 (n2rng->n_ctl_data->n_num_rngs == 1) ? "" : "s"); 1300 goto errorexit; 1301 } else { 1302 n2rng_setconfigured(n2rng); 1303 } 1304 } else { 1305 /* Running in guest domain, just check if rng is configured */ 1306 rv = n2rng_config_test(n2rng); 1307 switch (rv) { 1308 case 0: 1309 n2rng_setconfigured(n2rng); 1310 break; 1311 case EIO: 1312 /* Don't set configured to force a retry */ 1313 break; 1314 default: 1315 goto errorexit; 1316 } 1317 } 1318 1319 /* 1320 * Initialize FIPS state and register with KCF if we have at least one 1321 * RNG configured. Otherwise schedule a retry if all rngs have not 1322 * failed. 1323 */ 1324 if (n2rng_isconfigured(n2rng)) { 1325 1326 if (n2rng_init(n2rng) != DDI_SUCCESS) { 1327 cmn_err(CE_WARN, "n2rng: unable to register with KCF"); 1328 goto errorexit; 1329 } 1330 1331 /* 1332 * Schedule a retry if running in the control domain and a 1333 * health check time has been specified. 1334 */ 1335 if (n2rng_iscontrol(n2rng) && 1336 (n2rng->n_ctl_data->n_hc_secs > 0)) { 1337 n2rng_config_retry(n2rng, 1338 n2rng->n_ctl_data->n_hc_secs); 1339 } 1340 } else if (!n2rng_isfailed(n2rng)) { 1341 /* Schedule a retry if one is not already pending */ 1342 n2rng_config_retry(n2rng, RNG_CFG_RETRY_SECS); 1343 } 1344 return (DDI_SUCCESS); 1345 1346 errorexit: 1347 /* Unregister from kCF if we are registered */ 1348 (void) n2rng_unregister_provider(n2rng); 1349 n2rng_setfailed(n2rng); 1350 cmn_err(CE_WARN, "n2rng: hardware failure detected"); 1351 return (DDI_FAILURE); 1352 } 1353 1354 /* 1355 * n2rng_config_task() 1356 * 1357 * Call n2rng_config() from the task queue or after a timeout, ignore result. 1358 */ 1359 static void 1360 n2rng_config_task(void *targ) 1361 { 1362 n2rng_t *n2rng = (n2rng_t *)targ; 1363 1364 mutex_enter(&n2rng->n_lock); 1365 n2rng->n_timeout_id = 0; 1366 mutex_exit(&n2rng->n_lock); 1367 (void) n2rng_config(n2rng); 1368 } 1369