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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/systm.h> 30 #include <sys/archsystm.h> 31 #include <sys/t_lock.h> 32 #include <sys/uadmin.h> 33 #include <sys/panic.h> 34 #include <sys/reboot.h> 35 #include <sys/autoconf.h> 36 #include <sys/machsystm.h> 37 #include <sys/promif.h> 38 #include <sys/membar.h> 39 #include <vm/hat_sfmmu.h> 40 #include <sys/cpu_module.h> 41 #include <sys/cpu_sgnblk_defs.h> 42 #include <sys/intreg.h> 43 #include <sys/consdev.h> 44 #include <sys/kdi_impl.h> 45 #include <sys/traptrace.h> 46 #include <sys/hypervisor_api.h> 47 #include <sys/vmsystm.h> 48 #include <sys/dtrace.h> 49 #include <sys/xc_impl.h> 50 #include <sys/callb.h> 51 #include <sys/mdesc.h> 52 #include <sys/mach_descrip.h> 53 54 /* 55 * hvdump_buf_va is a pointer to the currently-configured hvdump_buf. 56 * A value of NULL indicates that this area is not configured. 57 * hvdump_buf_sz is tunable but will be clamped to HVDUMP_SIZE_MAX. 58 */ 59 60 caddr_t hvdump_buf_va; 61 uint64_t hvdump_buf_sz = HVDUMP_SIZE_DEFAULT; 62 static uint64_t hvdump_buf_pa; 63 64 u_longlong_t panic_tick; 65 66 extern u_longlong_t gettick(); 67 static void reboot_machine(char *); 68 static void update_hvdump_buffer(void); 69 70 /* 71 * For xt_sync synchronization. 72 */ 73 extern uint64_t xc_tick_limit; 74 extern uint64_t xc_tick_jump_limit; 75 76 /* 77 * We keep our own copies, used for cache flushing, because we can be called 78 * before cpu_fiximpl(). 79 */ 80 static int kdi_dcache_size; 81 static int kdi_dcache_linesize; 82 static int kdi_icache_size; 83 static int kdi_icache_linesize; 84 85 /* 86 * Assembly support for generic modules in sun4v/ml/mach_xc.s 87 */ 88 extern void init_mondo_nocheck(xcfunc_t *func, uint64_t arg1, uint64_t arg2); 89 extern void kdi_flush_idcache(int, int, int, int); 90 extern uint64_t get_cpuaddr(uint64_t, uint64_t); 91 92 /* 93 * Machine dependent code to reboot. 94 * "mdep" is interpreted as a character pointer; if non-null, it is a pointer 95 * to a string to be used as the argument string when rebooting. 96 * 97 * "invoke_cb" is a boolean. It is set to true when mdboot() can safely 98 * invoke CB_CL_MDBOOT callbacks before shutting the system down, i.e. when 99 * we are in a normal shutdown sequence (interrupts are not blocked, the 100 * system is not panic'ing or being suspended). 101 */ 102 /*ARGSUSED*/ 103 void 104 mdboot(int cmd, int fcn, char *bootstr, boolean_t invoke_cb) 105 { 106 extern void pm_cfb_check_and_powerup(void); 107 108 /* 109 * XXX - rconsvp is set to NULL to ensure that output messages 110 * are sent to the underlying "hardware" device using the 111 * monitor's printf routine since we are in the process of 112 * either rebooting or halting the machine. 113 */ 114 rconsvp = NULL; 115 116 /* 117 * At a high interrupt level we can't: 118 * 1) bring up the console 119 * or 120 * 2) wait for pending interrupts prior to redistribution 121 * to the current CPU 122 * 123 * so we do them now. 124 */ 125 pm_cfb_check_and_powerup(); 126 127 /* make sure there are no more changes to the device tree */ 128 devtree_freeze(); 129 130 if (invoke_cb) 131 (void) callb_execute_class(CB_CL_MDBOOT, NULL); 132 133 /* 134 * Clear any unresolved UEs from memory. 135 */ 136 if (memsegs != NULL) 137 page_retire_hunt(page_retire_mdboot_cb); 138 139 /* 140 * stop other cpus which also raise our priority. since there is only 141 * one active cpu after this, and our priority will be too high 142 * for us to be preempted, we're essentially single threaded 143 * from here on out. 144 */ 145 stop_other_cpus(); 146 147 /* 148 * try and reset leaf devices. reset_leaves() should only 149 * be called when there are no other threads that could be 150 * accessing devices 151 */ 152 reset_leaves(); 153 154 if (fcn == AD_HALT) { 155 halt((char *)NULL); 156 } else if (fcn == AD_POWEROFF) { 157 power_down(NULL); 158 } else { 159 if (bootstr == NULL) { 160 switch (fcn) { 161 162 case AD_BOOT: 163 bootstr = ""; 164 break; 165 166 case AD_IBOOT: 167 bootstr = "-a"; 168 break; 169 170 case AD_SBOOT: 171 bootstr = "-s"; 172 break; 173 174 case AD_SIBOOT: 175 bootstr = "-sa"; 176 break; 177 default: 178 cmn_err(CE_WARN, 179 "mdboot: invalid function %d", fcn); 180 bootstr = ""; 181 break; 182 } 183 } 184 reboot_machine(bootstr); 185 } 186 /* MAYBE REACHED */ 187 } 188 189 /* mdpreboot - may be called prior to mdboot while root fs still mounted */ 190 /*ARGSUSED*/ 191 void 192 mdpreboot(int cmd, int fcn, char *bootstr) 193 { 194 } 195 196 /* 197 * Halt the machine and then reboot with the device 198 * and arguments specified in bootstr. 199 */ 200 static void 201 reboot_machine(char *bootstr) 202 { 203 flush_windows(); 204 stop_other_cpus(); /* send stop signal to other CPUs */ 205 prom_printf("rebooting...\n"); 206 /* 207 * For platforms that use CPU signatures, we 208 * need to set the signature block to OS and 209 * the state to exiting for all the processors. 210 */ 211 CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_REBOOT, -1); 212 prom_reboot(bootstr); 213 /*NOTREACHED*/ 214 } 215 216 /* 217 * We use the x-trap mechanism and idle_stop_xcall() to stop the other CPUs. 218 * Once in panic_idle() they raise spl, record their location, and spin. 219 */ 220 static void 221 panic_idle(void) 222 { 223 (void) spl7(); 224 225 debug_flush_windows(); 226 (void) setjmp(&curthread->t_pcb); 227 228 CPU->cpu_m.in_prom = 1; 229 membar_stld(); 230 231 for (;;); 232 } 233 234 /* 235 * Force the other CPUs to trap into panic_idle(), and then remove them 236 * from the cpu_ready_set so they will no longer receive cross-calls. 237 */ 238 /*ARGSUSED*/ 239 void 240 panic_stopcpus(cpu_t *cp, kthread_t *t, int spl) 241 { 242 cpuset_t cps; 243 int i; 244 245 (void) splzs(); 246 CPUSET_ALL_BUT(cps, cp->cpu_id); 247 xt_some(cps, (xcfunc_t *)idle_stop_xcall, (uint64_t)&panic_idle, NULL); 248 249 for (i = 0; i < NCPU; i++) { 250 if (i != cp->cpu_id && CPU_XCALL_READY(i)) { 251 int ntries = 0x10000; 252 253 while (!cpu[i]->cpu_m.in_prom && ntries) { 254 DELAY(50); 255 ntries--; 256 } 257 258 if (!cpu[i]->cpu_m.in_prom) 259 printf("panic: failed to stop cpu%d\n", i); 260 261 cpu[i]->cpu_flags &= ~CPU_READY; 262 cpu[i]->cpu_flags |= CPU_QUIESCED; 263 CPUSET_DEL(cpu_ready_set, cpu[i]->cpu_id); 264 } 265 } 266 } 267 268 /* 269 * Platform callback following each entry to panicsys(). If we've panicked at 270 * level 14, we examine t_panic_trap to see if a fatal trap occurred. If so, 271 * we disable further %tick_cmpr interrupts. If not, an explicit call to panic 272 * was made and so we re-enqueue an interrupt request structure to allow 273 * further level 14 interrupts to be processed once we lower PIL. This allows 274 * us to handle panics from the deadman() CY_HIGH_LEVEL cyclic. 275 */ 276 void 277 panic_enter_hw(int spl) 278 { 279 if (!panic_tick) { 280 panic_tick = gettick(); 281 if (mach_htraptrace_enable) { 282 uint64_t prev_freeze; 283 284 /* there are no possible error codes for this hcall */ 285 (void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL, 286 &prev_freeze); 287 } 288 #ifdef TRAPTRACE 289 TRAPTRACE_FREEZE; 290 #endif 291 } 292 if (spl == ipltospl(PIL_14)) { 293 uint_t opstate = disable_vec_intr(); 294 295 if (curthread->t_panic_trap != NULL) { 296 tickcmpr_disable(); 297 intr_dequeue_req(PIL_14, cbe_level14_inum); 298 } else { 299 if (!tickcmpr_disabled()) 300 intr_enqueue_req(PIL_14, cbe_level14_inum); 301 /* 302 * Clear SOFTINT<14>, SOFTINT<0> (TICK_INT) 303 * and SOFTINT<16> (STICK_INT) to indicate 304 * that the current level 14 has been serviced. 305 */ 306 wr_clr_softint((1 << PIL_14) | 307 TICK_INT_MASK | STICK_INT_MASK); 308 } 309 310 enable_vec_intr(opstate); 311 } 312 } 313 314 /* 315 * Miscellaneous hardware-specific code to execute after panicstr is set 316 * by the panic code: we also print and record PTL1 panic information here. 317 */ 318 /*ARGSUSED*/ 319 void 320 panic_quiesce_hw(panic_data_t *pdp) 321 { 322 extern uint_t getpstate(void); 323 extern void setpstate(uint_t); 324 325 /* 326 * Turn off TRAPTRACE and save the current %tick value in panic_tick. 327 */ 328 if (!panic_tick) { 329 panic_tick = gettick(); 330 if (mach_htraptrace_enable) { 331 uint64_t prev_freeze; 332 333 /* there are no possible error codes for this hcall */ 334 (void) hv_ttrace_freeze((uint64_t)TRAP_TFREEZE_ALL, 335 &prev_freeze); 336 } 337 #ifdef TRAPTRACE 338 TRAPTRACE_FREEZE; 339 #endif 340 } 341 /* 342 * For Platforms that use CPU signatures, we 343 * need to set the signature block to OS, the state to 344 * exiting, and the substate to panic for all the processors. 345 */ 346 CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_PANIC, -1); 347 348 update_hvdump_buffer(); 349 350 /* 351 * Disable further ECC errors from the bus nexus. 352 */ 353 (void) bus_func_invoke(BF_TYPE_ERRDIS); 354 355 /* 356 * Redirect all interrupts to the current CPU. 357 */ 358 intr_redist_all_cpus_shutdown(); 359 360 /* 361 * This call exists solely to support dumps to network 362 * devices after sync from OBP. 363 * 364 * If we came here via the sync callback, then on some 365 * platforms, interrupts may have arrived while we were 366 * stopped in OBP. OBP will arrange for those interrupts to 367 * be redelivered if you say "go", but not if you invoke a 368 * client callback like 'sync'. For some dump devices 369 * (network swap devices), we need interrupts to be 370 * delivered in order to dump, so we have to call the bus 371 * nexus driver to reset the interrupt state machines. 372 */ 373 (void) bus_func_invoke(BF_TYPE_RESINTR); 374 375 setpstate(getpstate() | PSTATE_IE); 376 } 377 378 /* 379 * Platforms that use CPU signatures need to set the signature block to OS and 380 * the state to exiting for all CPUs. PANIC_CONT indicates that we're about to 381 * write the crash dump, which tells the SSP/SMS to begin a timeout routine to 382 * reboot the machine if the dump never completes. 383 */ 384 /*ARGSUSED*/ 385 void 386 panic_dump_hw(int spl) 387 { 388 CPU_SIGNATURE(OS_SIG, SIGST_EXIT, SIGSUBST_DUMP, -1); 389 } 390 391 /* 392 * for ptl1_panic 393 */ 394 void 395 ptl1_init_cpu(struct cpu *cpu) 396 { 397 ptl1_state_t *pstate = &cpu->cpu_m.ptl1_state; 398 399 /*CONSTCOND*/ 400 if (sizeof (struct cpu) + PTL1_SSIZE > CPU_ALLOC_SIZE) { 401 panic("ptl1_init_cpu: not enough space left for ptl1_panic " 402 "stack, sizeof (struct cpu) = %lu", 403 (unsigned long)sizeof (struct cpu)); 404 } 405 406 pstate->ptl1_stktop = (uintptr_t)cpu + CPU_ALLOC_SIZE; 407 cpu_pa[cpu->cpu_id] = va_to_pa(cpu); 408 } 409 410 void 411 ptl1_panic_handler(ptl1_state_t *pstate) 412 { 413 static const char *ptl1_reasons[] = { 414 #ifdef PTL1_PANIC_DEBUG 415 "trap for debug purpose", /* PTL1_BAD_DEBUG */ 416 #else 417 "unknown trap", /* PTL1_BAD_DEBUG */ 418 #endif 419 "register window trap", /* PTL1_BAD_WTRAP */ 420 "kernel MMU miss", /* PTL1_BAD_KMISS */ 421 "kernel protection fault", /* PTL1_BAD_KPROT_FAULT */ 422 "ISM MMU miss", /* PTL1_BAD_ISM */ 423 "kernel MMU trap", /* PTL1_BAD_MMUTRAP */ 424 "kernel trap handler state", /* PTL1_BAD_TRAP */ 425 "floating point trap", /* PTL1_BAD_FPTRAP */ 426 #ifdef DEBUG 427 "pointer to intr_req", /* PTL1_BAD_INTR_REQ */ 428 #else 429 "unknown trap", /* PTL1_BAD_INTR_REQ */ 430 #endif 431 #ifdef TRAPTRACE 432 "TRACE_PTR state", /* PTL1_BAD_TRACE_PTR */ 433 #else 434 "unknown trap", /* PTL1_BAD_TRACE_PTR */ 435 #endif 436 "stack overflow", /* PTL1_BAD_STACK */ 437 "DTrace flags", /* PTL1_BAD_DTRACE_FLAGS */ 438 "attempt to steal locked ctx", /* PTL1_BAD_CTX_STEAL */ 439 "CPU ECC error loop", /* PTL1_BAD_ECC */ 440 "unexpected error from hypervisor call", /* PTL1_BAD_HCALL */ 441 "unexpected global level(%gl)", /* PTL1_BAD_GL */ 442 "Watchdog Reset", /* PTL1_BAD_WATCHDOG */ 443 "unexpected RED mode trap", /* PTL1_BAD_RED */ 444 "return value EINVAL from hcall: "\ 445 "UNMAP_PERM_ADDR", /* PTL1_BAD_HCALL_UNMAP_PERM_EINVAL */ 446 "return value ENOMAP from hcall: "\ 447 "UNMAP_PERM_ADDR", /* PTL1_BAD_HCALL_UNMAP_PERM_ENOMAP */ 448 }; 449 450 uint_t reason = pstate->ptl1_regs.ptl1_gregs[0].ptl1_g1; 451 uint_t tl = pstate->ptl1_regs.ptl1_trap_regs[0].ptl1_tl; 452 struct trap_info ti = { 0 }; 453 454 /* 455 * Use trap_info for a place holder to call panic_savetrap() and 456 * panic_showtrap() to save and print out ptl1_panic information. 457 */ 458 if (curthread->t_panic_trap == NULL) 459 curthread->t_panic_trap = &ti; 460 461 if (reason < sizeof (ptl1_reasons) / sizeof (ptl1_reasons[0])) 462 panic("bad %s at TL %u", ptl1_reasons[reason], tl); 463 else 464 panic("ptl1_panic reason 0x%x at TL %u", reason, tl); 465 } 466 467 void 468 clear_watchdog_on_exit(void) 469 { 470 } 471 472 void 473 clear_watchdog_timer(void) 474 { 475 } 476 477 int 478 kdi_watchdog_disable(void) 479 { 480 return (0); /* sun4v has no watchdog */ 481 } 482 483 void 484 kdi_watchdog_restore(void) 485 { 486 /* nothing to do -- no watchdog to re-enable */ 487 } 488 489 void 490 mach_dump_buffer_init(void) 491 { 492 uint64_t ret, minsize = 0; 493 494 if (hvdump_buf_sz > HVDUMP_SIZE_MAX) 495 hvdump_buf_sz = HVDUMP_SIZE_MAX; 496 497 hvdump_buf_va = contig_mem_alloc_align(hvdump_buf_sz, PAGESIZE); 498 if (hvdump_buf_va == NULL) 499 return; 500 501 hvdump_buf_pa = va_to_pa(hvdump_buf_va); 502 503 ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz, 504 &minsize); 505 506 if (ret != H_EOK) { 507 contig_mem_free(hvdump_buf_va, hvdump_buf_sz); 508 hvdump_buf_va = NULL; 509 cmn_err(CE_NOTE, "!Error in setting up hvstate" 510 "dump buffer. Error = 0x%lx, size = 0x%lx," 511 "buf_pa = 0x%lx", ret, hvdump_buf_sz, 512 hvdump_buf_pa); 513 514 if (ret == H_EINVAL) { 515 cmn_err(CE_NOTE, "!Buffer size too small." 516 "Available buffer size = 0x%lx," 517 "Minimum buffer size required = 0x%lx", 518 hvdump_buf_sz, minsize); 519 } 520 } 521 } 522 523 524 static void 525 update_hvdump_buffer(void) 526 { 527 uint64_t ret, dummy_val; 528 529 if (hvdump_buf_va == NULL) 530 return; 531 532 ret = hv_dump_buf_update(hvdump_buf_pa, hvdump_buf_sz, 533 &dummy_val); 534 if (ret != H_EOK) { 535 cmn_err(CE_NOTE, "!Cannot update hvstate dump" 536 "buffer. Error = 0x%lx", ret); 537 } 538 } 539 540 541 static int 542 getintprop(pnode_t node, char *name, int deflt) 543 { 544 int value; 545 546 switch (prom_getproplen(node, name)) { 547 case 0: 548 value = 1; /* boolean properties */ 549 break; 550 551 case sizeof (int): 552 (void) prom_getprop(node, name, (caddr_t)&value); 553 break; 554 555 default: 556 value = deflt; 557 break; 558 } 559 560 return (value); 561 } 562 563 /* 564 * Called by setcpudelay 565 */ 566 void 567 cpu_init_tick_freq(void) 568 { 569 md_t *mdp; 570 mde_cookie_t rootnode; 571 int listsz; 572 mde_cookie_t *listp = NULL; 573 int num_nodes; 574 uint64_t stick_prop; 575 576 if (broken_md_flag) { 577 sys_tick_freq = cpunodes[CPU->cpu_id].clock_freq; 578 return; 579 } 580 581 if ((mdp = md_get_handle()) == NULL) 582 panic("stick_frequency property not found in MD"); 583 584 rootnode = md_root_node(mdp); 585 ASSERT(rootnode != MDE_INVAL_ELEM_COOKIE); 586 587 num_nodes = md_node_count(mdp); 588 589 ASSERT(num_nodes > 0); 590 listsz = num_nodes * sizeof (mde_cookie_t); 591 listp = (mde_cookie_t *)prom_alloc((caddr_t)0, listsz, 0); 592 593 if (listp == NULL) 594 panic("cannot allocate list for MD properties"); 595 596 num_nodes = md_scan_dag(mdp, rootnode, md_find_name(mdp, "platform"), 597 md_find_name(mdp, "fwd"), listp); 598 599 ASSERT(num_nodes == 1); 600 601 if (md_get_prop_val(mdp, *listp, "stick-frequency", &stick_prop) != 0) 602 panic("stick_frequency property not found in MD"); 603 604 sys_tick_freq = stick_prop; 605 606 prom_free((caddr_t)listp, listsz); 607 (void) md_fini_handle(mdp); 608 } 609 610 int shipit(int n, uint64_t cpu_list_ra); 611 extern uint64_t xc_tick_limit; 612 extern uint64_t xc_tick_jump_limit; 613 614 #ifdef DEBUG 615 #define SEND_MONDO_STATS 1 616 #endif 617 618 #ifdef SEND_MONDO_STATS 619 uint32_t x_one_stimes[64]; 620 uint32_t x_one_ltimes[16]; 621 uint32_t x_set_stimes[64]; 622 uint32_t x_set_ltimes[16]; 623 uint32_t x_set_cpus[NCPU]; 624 #endif 625 626 void 627 send_one_mondo(int cpuid) 628 { 629 int retries, stat; 630 uint64_t starttick, endtick, tick, lasttick; 631 struct machcpu *mcpup = &(CPU->cpu_m); 632 633 CPU_STATS_ADDQ(CPU, sys, xcalls, 1); 634 starttick = lasttick = gettick(); 635 mcpup->cpu_list[0] = (uint16_t)cpuid; 636 stat = shipit(1, mcpup->cpu_list_ra); 637 endtick = starttick + xc_tick_limit; 638 retries = 0; 639 while (stat != H_EOK) { 640 if (stat != H_EWOULDBLOCK) { 641 if (panic_quiesce) 642 return; 643 if (stat == H_ECPUERROR) 644 cmn_err(CE_PANIC, "send_one_mondo: " 645 "cpuid: 0x%x has been marked in " 646 "error", cpuid); 647 else 648 cmn_err(CE_PANIC, "send_one_mondo: " 649 "unexpected hypervisor error 0x%x " 650 "while sending a mondo to cpuid: " 651 "0x%x", stat, cpuid); 652 } 653 tick = gettick(); 654 /* 655 * If there is a big jump between the current tick 656 * count and lasttick, we have probably hit a break 657 * point. Adjust endtick accordingly to avoid panic. 658 */ 659 if (tick > (lasttick + xc_tick_jump_limit)) 660 endtick += (tick - lasttick); 661 lasttick = tick; 662 if (tick > endtick) { 663 if (panic_quiesce) 664 return; 665 cmn_err(CE_PANIC, "send mondo timeout " 666 "(target 0x%x) [retries: 0x%x hvstat: 0x%x]", 667 cpuid, retries, stat); 668 } 669 drv_usecwait(1); 670 stat = shipit(1, mcpup->cpu_list_ra); 671 retries++; 672 } 673 #ifdef SEND_MONDO_STATS 674 { 675 uint64_t n = gettick() - starttick; 676 if (n < 8192) 677 x_one_stimes[n >> 7]++; 678 else if (n < 15*8192) 679 x_one_ltimes[n >> 13]++; 680 else 681 x_one_ltimes[0xf]++; 682 } 683 #endif 684 } 685 686 void 687 send_mondo_set(cpuset_t set) 688 { 689 uint64_t starttick, endtick, tick, lasttick; 690 int shipped = 0; 691 int retries = 0; 692 struct machcpu *mcpup = &(CPU->cpu_m); 693 694 ASSERT(!CPUSET_ISNULL(set)); 695 starttick = lasttick = gettick(); 696 endtick = starttick + xc_tick_limit; 697 698 do { 699 int ncpuids = 0; 700 int i, stat; 701 702 /* assemble CPU list for HV argument */ 703 for (i = 0; i < NCPU; i++) { 704 if (CPU_IN_SET(set, i)) { 705 mcpup->cpu_list[ncpuids] = (uint16_t)i; 706 ncpuids++; 707 } 708 } 709 710 stat = shipit(ncpuids, mcpup->cpu_list_ra); 711 if (stat == H_EOK) { 712 shipped += ncpuids; 713 break; 714 } 715 716 /* 717 * Either not all CPU mondos were sent, or an 718 * error occurred. CPUs that were sent mondos 719 * have their CPU IDs overwritten in cpu_list. 720 * Reset the cpuset so that its only members 721 * are those CPU IDs that still need to be sent. 722 */ 723 CPUSET_ZERO(set); 724 for (i = 0; i < ncpuids; i++) { 725 if (mcpup->cpu_list[i] == HV_SEND_MONDO_ENTRYDONE) { 726 shipped++; 727 } else { 728 CPUSET_ADD(set, mcpup->cpu_list[i]); 729 } 730 } 731 732 /* 733 * Now handle possible errors returned 734 * from hypervisor. 735 */ 736 if (stat == H_ECPUERROR) { 737 cpuset_t error_set; 738 739 /* 740 * One or more of the CPUs passed to HV is 741 * in the error state. Remove those CPUs from 742 * set and record them in error_set. 743 */ 744 CPUSET_ZERO(error_set); 745 for (i = 0; i < NCPU; i++) { 746 if (CPU_IN_SET(set, i)) { 747 uint64_t state = CPU_STATE_INVALID; 748 (void) hv_cpu_state(i, &state); 749 if (state == CPU_STATE_ERROR) { 750 CPUSET_ADD(error_set, i); 751 CPUSET_DEL(set, i); 752 } 753 } 754 } 755 756 if (!panic_quiesce) { 757 if (CPUSET_ISNULL(error_set)) { 758 cmn_err(CE_PANIC, "send_mondo_set: " 759 "hypervisor returned " 760 "H_ECPUERROR but no CPU in " 761 "cpu_list in error state"); 762 } 763 764 cmn_err(CE_CONT, "send_mondo_set: cpuid(s) "); 765 for (i = 0; i < NCPU; i++) { 766 if (CPU_IN_SET(error_set, i)) { 767 cmn_err(CE_CONT, "0x%x ", i); 768 } 769 } 770 cmn_err(CE_CONT, "have been marked in " 771 "error\n"); 772 cmn_err(CE_PANIC, "send_mondo_set: CPU(s) " 773 "in error state"); 774 } 775 } else if (stat != H_EWOULDBLOCK) { 776 if (panic_quiesce) 777 return; 778 /* 779 * For all other errors, panic. 780 */ 781 cmn_err(CE_CONT, "send_mondo_set: unexpected " 782 "hypervisor error 0x%x while sending a " 783 "mondo to cpuid(s):", stat); 784 for (i = 0; i < NCPU; i++) { 785 if (CPU_IN_SET(set, i)) { 786 cmn_err(CE_CONT, " 0x%x", i); 787 } 788 } 789 cmn_err(CE_CONT, "\n"); 790 cmn_err(CE_PANIC, "send_mondo_set: unexpected " 791 "hypervisor error"); 792 } 793 794 tick = gettick(); 795 /* 796 * If there is a big jump between the current tick 797 * count and lasttick, we have probably hit a break 798 * point. Adjust endtick accordingly to avoid panic. 799 */ 800 if (tick > (lasttick + xc_tick_jump_limit)) 801 endtick += (tick - lasttick); 802 lasttick = tick; 803 if (tick > endtick) { 804 if (panic_quiesce) 805 return; 806 cmn_err(CE_CONT, "send mondo timeout " 807 "[retries: 0x%x] cpuids: ", retries); 808 for (i = 0; i < NCPU; i++) 809 if (CPU_IN_SET(set, i)) 810 cmn_err(CE_CONT, " 0x%x", i); 811 cmn_err(CE_CONT, "\n"); 812 cmn_err(CE_PANIC, "send_mondo_set: timeout"); 813 } 814 815 while (gettick() < (tick + sys_clock_mhz)) 816 ; 817 retries++; 818 } while (!CPUSET_ISNULL(set)); 819 820 CPU_STATS_ADDQ(CPU, sys, xcalls, shipped); 821 822 #ifdef SEND_MONDO_STATS 823 { 824 uint64_t n = gettick() - starttick; 825 if (n < 8192) 826 x_set_stimes[n >> 7]++; 827 else if (n < 15*8192) 828 x_set_ltimes[n >> 13]++; 829 else 830 x_set_ltimes[0xf]++; 831 } 832 x_set_cpus[shipped]++; 833 #endif 834 } 835 836 void 837 syncfpu(void) 838 { 839 } 840 841 void 842 cpu_flush_ecache(void) 843 { 844 } 845 846 void 847 sticksync_slave(void) 848 {} 849 850 void 851 sticksync_master(void) 852 {} 853 854 void 855 cpu_init_cache_scrub(void) 856 {} 857 858 int 859 dtrace_blksuword32_err(uintptr_t addr, uint32_t *data) 860 { 861 int ret, watched; 862 863 watched = watch_disable_addr((void *)addr, 4, S_WRITE); 864 ret = dtrace_blksuword32(addr, data, 0); 865 if (watched) 866 watch_enable_addr((void *)addr, 4, S_WRITE); 867 868 return (ret); 869 } 870 871 int 872 dtrace_blksuword32(uintptr_t addr, uint32_t *data, int tryagain) 873 { 874 if (suword32((void *)addr, *data) == -1) 875 return (tryagain ? dtrace_blksuword32_err(addr, data) : -1); 876 dtrace_flush_sec(addr); 877 878 return (0); 879 } 880 881 /*ARGSUSED*/ 882 void 883 cpu_faulted_enter(struct cpu *cp) 884 { 885 } 886 887 /*ARGSUSED*/ 888 void 889 cpu_faulted_exit(struct cpu *cp) 890 { 891 } 892 893 static int 894 kdi_cpu_ready_iter(int (*cb)(int, void *), void *arg) 895 { 896 int rc, i; 897 898 for (rc = 0, i = 0; i < NCPU; i++) { 899 if (CPU_IN_SET(cpu_ready_set, i)) 900 rc += cb(i, arg); 901 } 902 903 return (rc); 904 } 905 906 /* 907 * Sends a cross-call to a specified processor. The caller assumes 908 * responsibility for repetition of cross-calls, as appropriate (MARSA for 909 * debugging). 910 */ 911 static int 912 kdi_xc_one(int cpuid, void (*func)(uintptr_t, uintptr_t), uintptr_t arg1, 913 uintptr_t arg2) 914 { 915 int stat; 916 struct machcpu *mcpup; 917 uint64_t cpuaddr_reg = 0, cpuaddr_scr = 0; 918 919 mcpup = &(((cpu_t *)get_cpuaddr(cpuaddr_reg, cpuaddr_scr))->cpu_m); 920 921 /* 922 * if (idsr_busy()) 923 * return (KDI_XC_RES_ERR); 924 */ 925 926 init_mondo_nocheck((xcfunc_t *)func, arg1, arg2); 927 928 mcpup->cpu_list[0] = (uint16_t)cpuid; 929 stat = shipit(1, mcpup->cpu_list_ra); 930 931 if (stat == 0) 932 return (KDI_XC_RES_OK); 933 else 934 return (KDI_XC_RES_NACK); 935 } 936 937 static void 938 kdi_tickwait(clock_t nticks) 939 { 940 clock_t endtick = gettick() + nticks; 941 942 while (gettick() < endtick); 943 } 944 945 static void 946 kdi_cpu_init(int dcache_size, int dcache_linesize, int icache_size, 947 int icache_linesize) 948 { 949 kdi_dcache_size = dcache_size; 950 kdi_dcache_linesize = dcache_linesize; 951 kdi_icache_size = icache_size; 952 kdi_icache_linesize = icache_linesize; 953 } 954 955 /* used directly by kdi_read/write_phys */ 956 void 957 kdi_flush_caches(void) 958 { 959 /* Not required on sun4v architecture. */ 960 } 961 962 /*ARGSUSED*/ 963 int 964 kdi_get_stick(uint64_t *stickp) 965 { 966 return (-1); 967 } 968 969 void 970 cpu_kdi_init(kdi_t *kdi) 971 { 972 kdi->kdi_flush_caches = kdi_flush_caches; 973 kdi->mkdi_cpu_init = kdi_cpu_init; 974 kdi->mkdi_cpu_ready_iter = kdi_cpu_ready_iter; 975 kdi->mkdi_xc_one = kdi_xc_one; 976 kdi->mkdi_tickwait = kdi_tickwait; 977 kdi->mkdi_get_stick = kdi_get_stick; 978 } 979 980 /* 981 * Routine to return memory information associated 982 * with a physical address and syndrome. 983 */ 984 /* ARGSUSED */ 985 int 986 cpu_get_mem_info(uint64_t synd, uint64_t afar, 987 uint64_t *mem_sizep, uint64_t *seg_sizep, uint64_t *bank_sizep, 988 int *segsp, int *banksp, int *mcidp) 989 { 990 return (ENOTSUP); 991 } 992 993 /* 994 * This routine returns the size of the kernel's FRU name buffer. 995 */ 996 size_t 997 cpu_get_name_bufsize() 998 { 999 return (UNUM_NAMLEN); 1000 } 1001 1002 /* 1003 * This routine is a more generic interface to cpu_get_mem_unum(), 1004 * that may be used by other modules (e.g. mm). 1005 */ 1006 /* ARGSUSED */ 1007 int 1008 cpu_get_mem_name(uint64_t synd, uint64_t *afsr, uint64_t afar, 1009 char *buf, int buflen, int *lenp) 1010 { 1011 return (ENOTSUP); 1012 } 1013 1014 /* ARGSUSED */ 1015 int 1016 cpu_get_mem_sid(char *unum, char *buf, int buflen, int *lenp) 1017 { 1018 return (ENOTSUP); 1019 } 1020 1021 /* ARGSUSED */ 1022 int 1023 cpu_get_mem_addr(char *unum, char *sid, uint64_t offset, uint64_t *addrp) 1024 { 1025 return (ENOTSUP); 1026 } 1027 1028 /* 1029 * xt_sync - wait for previous x-traps to finish 1030 */ 1031 void 1032 xt_sync(cpuset_t cpuset) 1033 { 1034 union { 1035 uint8_t volatile byte[NCPU]; 1036 uint64_t volatile xword[NCPU / 8]; 1037 } cpu_sync; 1038 uint64_t starttick, endtick, tick, lasttick; 1039 int i; 1040 1041 kpreempt_disable(); 1042 CPUSET_DEL(cpuset, CPU->cpu_id); 1043 CPUSET_AND(cpuset, cpu_ready_set); 1044 1045 /* 1046 * Sun4v uses a queue for receiving mondos. Successful 1047 * transmission of a mondo only indicates that the mondo 1048 * has been written into the queue. 1049 * 1050 * We use an array of bytes to let each cpu to signal back 1051 * to the cross trap sender that the cross trap has been 1052 * executed. Set the byte to 1 before sending the cross trap 1053 * and wait until other cpus reset it to 0. 1054 */ 1055 bzero((void *)&cpu_sync, NCPU); 1056 for (i = 0; i < NCPU; i++) 1057 if (CPU_IN_SET(cpuset, i)) 1058 cpu_sync.byte[i] = 1; 1059 1060 xt_some(cpuset, (xcfunc_t *)xt_sync_tl1, 1061 (uint64_t)cpu_sync.byte, 0); 1062 1063 starttick = lasttick = gettick(); 1064 endtick = starttick + xc_tick_limit; 1065 1066 for (i = 0; i < (NCPU / 8); i ++) { 1067 while (cpu_sync.xword[i] != 0) { 1068 tick = gettick(); 1069 /* 1070 * If there is a big jump between the current tick 1071 * count and lasttick, we have probably hit a break 1072 * point. Adjust endtick accordingly to avoid panic. 1073 */ 1074 if (tick > (lasttick + xc_tick_jump_limit)) { 1075 endtick += (tick - lasttick); 1076 } 1077 lasttick = tick; 1078 if (tick > endtick) { 1079 if (panic_quiesce) 1080 goto out; 1081 cmn_err(CE_CONT, "Cross trap sync timeout " 1082 "at cpu_sync.xword[%d]: 0x%lx\n", 1083 i, cpu_sync.xword[i]); 1084 cmn_err(CE_PANIC, "xt_sync: timeout"); 1085 } 1086 } 1087 } 1088 1089 out: 1090 kpreempt_enable(); 1091 } 1092