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