1 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 2 3 #include <linux/module.h> 4 #include <linux/reboot.h> 5 #include <linux/init.h> 6 #include <linux/pm.h> 7 #include <linux/efi.h> 8 #include <linux/dmi.h> 9 #include <linux/sched.h> 10 #include <linux/tboot.h> 11 #include <linux/delay.h> 12 #include <acpi/reboot.h> 13 #include <asm/io.h> 14 #include <asm/apic.h> 15 #include <asm/desc.h> 16 #include <asm/hpet.h> 17 #include <asm/pgtable.h> 18 #include <asm/proto.h> 19 #include <asm/reboot_fixups.h> 20 #include <asm/reboot.h> 21 #include <asm/pci_x86.h> 22 #include <asm/virtext.h> 23 #include <asm/cpu.h> 24 #include <asm/nmi.h> 25 #include <asm/smp.h> 26 27 #include <linux/ctype.h> 28 #include <linux/mc146818rtc.h> 29 #include <asm/realmode.h> 30 #include <asm/x86_init.h> 31 32 /* 33 * Power off function, if any 34 */ 35 void (*pm_power_off)(void); 36 EXPORT_SYMBOL(pm_power_off); 37 38 static const struct desc_ptr no_idt = {}; 39 40 /* 41 * This is set if we need to go through the 'emergency' path. 42 * When machine_emergency_restart() is called, we may be on 43 * an inconsistent state and won't be able to do a clean cleanup 44 */ 45 static int reboot_emergency; 46 47 /* This is set by the PCI code if either type 1 or type 2 PCI is detected */ 48 bool port_cf9_safe = false; 49 50 /* 51 * Reboot options and system auto-detection code provided by 52 * Dell Inc. so their systems "just work". :-) 53 */ 54 55 /* 56 * Some machines require the "reboot=b" or "reboot=k" commandline options, 57 * this quirk makes that automatic. 58 */ 59 static int __init set_bios_reboot(const struct dmi_system_id *d) 60 { 61 if (reboot_type != BOOT_BIOS) { 62 reboot_type = BOOT_BIOS; 63 pr_info("%s series board detected. Selecting %s-method for reboots.\n", 64 "BIOS", d->ident); 65 } 66 return 0; 67 } 68 69 void __noreturn machine_real_restart(unsigned int type) 70 { 71 local_irq_disable(); 72 73 /* 74 * Write zero to CMOS register number 0x0f, which the BIOS POST 75 * routine will recognize as telling it to do a proper reboot. (Well 76 * that's what this book in front of me says -- it may only apply to 77 * the Phoenix BIOS though, it's not clear). At the same time, 78 * disable NMIs by setting the top bit in the CMOS address register, 79 * as we're about to do peculiar things to the CPU. I'm not sure if 80 * `outb_p' is needed instead of just `outb'. Use it to be on the 81 * safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.) 82 */ 83 spin_lock(&rtc_lock); 84 CMOS_WRITE(0x00, 0x8f); 85 spin_unlock(&rtc_lock); 86 87 /* 88 * Switch back to the initial page table. 89 */ 90 #ifdef CONFIG_X86_32 91 load_cr3(initial_page_table); 92 #else 93 write_cr3(real_mode_header->trampoline_pgd); 94 #endif 95 96 /* Jump to the identity-mapped low memory code */ 97 #ifdef CONFIG_X86_32 98 asm volatile("jmpl *%0" : : 99 "rm" (real_mode_header->machine_real_restart_asm), 100 "a" (type)); 101 #else 102 asm volatile("ljmpl *%0" : : 103 "m" (real_mode_header->machine_real_restart_asm), 104 "D" (type)); 105 #endif 106 unreachable(); 107 } 108 #ifdef CONFIG_APM_MODULE 109 EXPORT_SYMBOL(machine_real_restart); 110 #endif 111 112 /* 113 * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot 114 */ 115 static int __init set_pci_reboot(const struct dmi_system_id *d) 116 { 117 if (reboot_type != BOOT_CF9) { 118 reboot_type = BOOT_CF9; 119 pr_info("%s series board detected. Selecting %s-method for reboots.\n", 120 "PCI", d->ident); 121 } 122 return 0; 123 } 124 125 static int __init set_kbd_reboot(const struct dmi_system_id *d) 126 { 127 if (reboot_type != BOOT_KBD) { 128 reboot_type = BOOT_KBD; 129 pr_info("%s series board detected. Selecting %s-method for reboot.\n", 130 "KBD", d->ident); 131 } 132 return 0; 133 } 134 135 /* 136 * This is a single dmi_table handling all reboot quirks. 137 */ 138 static struct dmi_system_id __initdata reboot_dmi_table[] = { 139 { /* Handle problems with rebooting on Dell E520's */ 140 .callback = set_bios_reboot, 141 .ident = "Dell E520", 142 .matches = { 143 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 144 DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"), 145 }, 146 }, 147 { /* Handle problems with rebooting on Dell 1300's */ 148 .callback = set_bios_reboot, 149 .ident = "Dell PowerEdge 1300", 150 .matches = { 151 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 152 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"), 153 }, 154 }, 155 { /* Handle problems with rebooting on Dell 300's */ 156 .callback = set_bios_reboot, 157 .ident = "Dell PowerEdge 300", 158 .matches = { 159 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 160 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"), 161 }, 162 }, 163 { /* Handle problems with rebooting on Dell Optiplex 745's SFF */ 164 .callback = set_bios_reboot, 165 .ident = "Dell OptiPlex 745", 166 .matches = { 167 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 168 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), 169 }, 170 }, 171 { /* Handle problems with rebooting on Dell Optiplex 745's DFF */ 172 .callback = set_bios_reboot, 173 .ident = "Dell OptiPlex 745", 174 .matches = { 175 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 176 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), 177 DMI_MATCH(DMI_BOARD_NAME, "0MM599"), 178 }, 179 }, 180 { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */ 181 .callback = set_bios_reboot, 182 .ident = "Dell OptiPlex 745", 183 .matches = { 184 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 185 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"), 186 DMI_MATCH(DMI_BOARD_NAME, "0KW626"), 187 }, 188 }, 189 { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */ 190 .callback = set_bios_reboot, 191 .ident = "Dell OptiPlex 330", 192 .matches = { 193 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 194 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 330"), 195 DMI_MATCH(DMI_BOARD_NAME, "0KP561"), 196 }, 197 }, 198 { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */ 199 .callback = set_bios_reboot, 200 .ident = "Dell OptiPlex 360", 201 .matches = { 202 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 203 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"), 204 DMI_MATCH(DMI_BOARD_NAME, "0T656F"), 205 }, 206 }, 207 { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */ 208 .callback = set_bios_reboot, 209 .ident = "Dell OptiPlex 760", 210 .matches = { 211 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 212 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"), 213 DMI_MATCH(DMI_BOARD_NAME, "0G919G"), 214 }, 215 }, 216 { /* Handle problems with rebooting on Dell 2400's */ 217 .callback = set_bios_reboot, 218 .ident = "Dell PowerEdge 2400", 219 .matches = { 220 DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"), 221 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"), 222 }, 223 }, 224 { /* Handle problems with rebooting on Dell T5400's */ 225 .callback = set_bios_reboot, 226 .ident = "Dell Precision T5400", 227 .matches = { 228 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 229 DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"), 230 }, 231 }, 232 { /* Handle problems with rebooting on Dell T7400's */ 233 .callback = set_bios_reboot, 234 .ident = "Dell Precision T7400", 235 .matches = { 236 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 237 DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T7400"), 238 }, 239 }, 240 { /* Handle problems with rebooting on HP laptops */ 241 .callback = set_bios_reboot, 242 .ident = "HP Compaq Laptop", 243 .matches = { 244 DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"), 245 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"), 246 }, 247 }, 248 { /* Handle problems with rebooting on Dell XPS710 */ 249 .callback = set_bios_reboot, 250 .ident = "Dell XPS710", 251 .matches = { 252 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 253 DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"), 254 }, 255 }, 256 { /* Handle problems with rebooting on Dell DXP061 */ 257 .callback = set_bios_reboot, 258 .ident = "Dell DXP061", 259 .matches = { 260 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 261 DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"), 262 }, 263 }, 264 { /* Handle problems with rebooting on Sony VGN-Z540N */ 265 .callback = set_bios_reboot, 266 .ident = "Sony VGN-Z540N", 267 .matches = { 268 DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), 269 DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"), 270 }, 271 }, 272 { /* Handle problems with rebooting on ASUS P4S800 */ 273 .callback = set_bios_reboot, 274 .ident = "ASUS P4S800", 275 .matches = { 276 DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."), 277 DMI_MATCH(DMI_BOARD_NAME, "P4S800"), 278 }, 279 }, 280 281 { /* Handle reboot issue on Acer Aspire one */ 282 .callback = set_kbd_reboot, 283 .ident = "Acer Aspire One A110", 284 .matches = { 285 DMI_MATCH(DMI_SYS_VENDOR, "Acer"), 286 DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"), 287 }, 288 }, 289 { /* Handle problems with rebooting on Apple MacBook5 */ 290 .callback = set_pci_reboot, 291 .ident = "Apple MacBook5", 292 .matches = { 293 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 294 DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"), 295 }, 296 }, 297 { /* Handle problems with rebooting on Apple MacBookPro5 */ 298 .callback = set_pci_reboot, 299 .ident = "Apple MacBookPro5", 300 .matches = { 301 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 302 DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"), 303 }, 304 }, 305 { /* Handle problems with rebooting on Apple Macmini3,1 */ 306 .callback = set_pci_reboot, 307 .ident = "Apple Macmini3,1", 308 .matches = { 309 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 310 DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"), 311 }, 312 }, 313 { /* Handle problems with rebooting on the iMac9,1. */ 314 .callback = set_pci_reboot, 315 .ident = "Apple iMac9,1", 316 .matches = { 317 DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), 318 DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"), 319 }, 320 }, 321 { /* Handle problems with rebooting on the Latitude E6320. */ 322 .callback = set_pci_reboot, 323 .ident = "Dell Latitude E6320", 324 .matches = { 325 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 326 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"), 327 }, 328 }, 329 { /* Handle problems with rebooting on the Latitude E5420. */ 330 .callback = set_pci_reboot, 331 .ident = "Dell Latitude E5420", 332 .matches = { 333 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 334 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"), 335 }, 336 }, 337 { /* Handle problems with rebooting on the Latitude E6420. */ 338 .callback = set_pci_reboot, 339 .ident = "Dell Latitude E6420", 340 .matches = { 341 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 342 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"), 343 }, 344 }, 345 { /* Handle problems with rebooting on the OptiPlex 990. */ 346 .callback = set_pci_reboot, 347 .ident = "Dell OptiPlex 990", 348 .matches = { 349 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 350 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"), 351 }, 352 }, 353 { /* Handle problems with rebooting on the Precision M6600. */ 354 .callback = set_pci_reboot, 355 .ident = "Dell Precision M6600", 356 .matches = { 357 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 358 DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"), 359 }, 360 }, 361 { /* Handle problems with rebooting on the Dell PowerEdge C6100. */ 362 .callback = set_pci_reboot, 363 .ident = "Dell PowerEdge C6100", 364 .matches = { 365 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), 366 DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), 367 }, 368 }, 369 { /* Some C6100 machines were shipped with vendor being 'Dell'. */ 370 .callback = set_pci_reboot, 371 .ident = "Dell PowerEdge C6100", 372 .matches = { 373 DMI_MATCH(DMI_SYS_VENDOR, "Dell"), 374 DMI_MATCH(DMI_PRODUCT_NAME, "C6100"), 375 }, 376 }, 377 { } 378 }; 379 380 static int __init reboot_init(void) 381 { 382 /* 383 * Only do the DMI check if reboot_type hasn't been overridden 384 * on the command line 385 */ 386 if (reboot_default) 387 dmi_check_system(reboot_dmi_table); 388 return 0; 389 } 390 core_initcall(reboot_init); 391 392 static inline void kb_wait(void) 393 { 394 int i; 395 396 for (i = 0; i < 0x10000; i++) { 397 if ((inb(0x64) & 0x02) == 0) 398 break; 399 udelay(2); 400 } 401 } 402 403 static void vmxoff_nmi(int cpu, struct pt_regs *regs) 404 { 405 cpu_emergency_vmxoff(); 406 } 407 408 /* Use NMIs as IPIs to tell all CPUs to disable virtualization */ 409 static void emergency_vmx_disable_all(void) 410 { 411 /* Just make sure we won't change CPUs while doing this */ 412 local_irq_disable(); 413 414 /* 415 * We need to disable VMX on all CPUs before rebooting, otherwise 416 * we risk hanging up the machine, because the CPU ignore INIT 417 * signals when VMX is enabled. 418 * 419 * We can't take any locks and we may be on an inconsistent 420 * state, so we use NMIs as IPIs to tell the other CPUs to disable 421 * VMX and halt. 422 * 423 * For safety, we will avoid running the nmi_shootdown_cpus() 424 * stuff unnecessarily, but we don't have a way to check 425 * if other CPUs have VMX enabled. So we will call it only if the 426 * CPU we are running on has VMX enabled. 427 * 428 * We will miss cases where VMX is not enabled on all CPUs. This 429 * shouldn't do much harm because KVM always enable VMX on all 430 * CPUs anyway. But we can miss it on the small window where KVM 431 * is still enabling VMX. 432 */ 433 if (cpu_has_vmx() && cpu_vmx_enabled()) { 434 /* Disable VMX on this CPU. */ 435 cpu_vmxoff(); 436 437 /* Halt and disable VMX on the other CPUs */ 438 nmi_shootdown_cpus(vmxoff_nmi); 439 440 } 441 } 442 443 444 void __attribute__((weak)) mach_reboot_fixups(void) 445 { 446 } 447 448 /* 449 * Windows compatible x86 hardware expects the following on reboot: 450 * 451 * 1) If the FADT has the ACPI reboot register flag set, try it 452 * 2) If still alive, write to the keyboard controller 453 * 3) If still alive, write to the ACPI reboot register again 454 * 4) If still alive, write to the keyboard controller again 455 * 456 * If the machine is still alive at this stage, it gives up. We default to 457 * following the same pattern, except that if we're still alive after (4) we'll 458 * try to force a triple fault and then cycle between hitting the keyboard 459 * controller and doing that 460 */ 461 static void native_machine_emergency_restart(void) 462 { 463 int i; 464 int attempt = 0; 465 int orig_reboot_type = reboot_type; 466 unsigned short mode; 467 468 if (reboot_emergency) 469 emergency_vmx_disable_all(); 470 471 tboot_shutdown(TB_SHUTDOWN_REBOOT); 472 473 /* Tell the BIOS if we want cold or warm reboot */ 474 mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0; 475 *((unsigned short *)__va(0x472)) = mode; 476 477 for (;;) { 478 /* Could also try the reset bit in the Hammer NB */ 479 switch (reboot_type) { 480 case BOOT_KBD: 481 mach_reboot_fixups(); /* For board specific fixups */ 482 483 for (i = 0; i < 10; i++) { 484 kb_wait(); 485 udelay(50); 486 outb(0xfe, 0x64); /* Pulse reset low */ 487 udelay(50); 488 } 489 if (attempt == 0 && orig_reboot_type == BOOT_ACPI) { 490 attempt = 1; 491 reboot_type = BOOT_ACPI; 492 } else { 493 reboot_type = BOOT_TRIPLE; 494 } 495 break; 496 497 case BOOT_TRIPLE: 498 load_idt(&no_idt); 499 __asm__ __volatile__("int3"); 500 501 reboot_type = BOOT_KBD; 502 break; 503 504 case BOOT_BIOS: 505 machine_real_restart(MRR_BIOS); 506 507 reboot_type = BOOT_KBD; 508 break; 509 510 case BOOT_ACPI: 511 acpi_reboot(); 512 reboot_type = BOOT_KBD; 513 break; 514 515 case BOOT_EFI: 516 if (efi_enabled(EFI_RUNTIME_SERVICES)) 517 efi.reset_system(reboot_mode == REBOOT_WARM ? 518 EFI_RESET_WARM : 519 EFI_RESET_COLD, 520 EFI_SUCCESS, 0, NULL); 521 reboot_type = BOOT_KBD; 522 break; 523 524 case BOOT_CF9: 525 port_cf9_safe = true; 526 /* Fall through */ 527 528 case BOOT_CF9_COND: 529 if (port_cf9_safe) { 530 u8 cf9 = inb(0xcf9) & ~6; 531 outb(cf9|2, 0xcf9); /* Request hard reset */ 532 udelay(50); 533 outb(cf9|6, 0xcf9); /* Actually do the reset */ 534 udelay(50); 535 } 536 reboot_type = BOOT_KBD; 537 break; 538 } 539 } 540 } 541 542 void native_machine_shutdown(void) 543 { 544 /* Stop the cpus and apics */ 545 #ifdef CONFIG_SMP 546 /* 547 * Stop all of the others. Also disable the local irq to 548 * not receive the per-cpu timer interrupt which may trigger 549 * scheduler's load balance. 550 */ 551 local_irq_disable(); 552 stop_other_cpus(); 553 #endif 554 555 lapic_shutdown(); 556 557 #ifdef CONFIG_X86_IO_APIC 558 disable_IO_APIC(); 559 #endif 560 561 #ifdef CONFIG_HPET_TIMER 562 hpet_disable(); 563 #endif 564 565 #ifdef CONFIG_X86_64 566 x86_platform.iommu_shutdown(); 567 #endif 568 } 569 570 static void __machine_emergency_restart(int emergency) 571 { 572 reboot_emergency = emergency; 573 machine_ops.emergency_restart(); 574 } 575 576 static void native_machine_restart(char *__unused) 577 { 578 pr_notice("machine restart\n"); 579 580 if (!reboot_force) 581 machine_shutdown(); 582 __machine_emergency_restart(0); 583 } 584 585 static void native_machine_halt(void) 586 { 587 /* Stop other cpus and apics */ 588 machine_shutdown(); 589 590 tboot_shutdown(TB_SHUTDOWN_HALT); 591 592 stop_this_cpu(NULL); 593 } 594 595 static void native_machine_power_off(void) 596 { 597 if (pm_power_off) { 598 if (!reboot_force) 599 machine_shutdown(); 600 pm_power_off(); 601 } 602 /* A fallback in case there is no PM info available */ 603 tboot_shutdown(TB_SHUTDOWN_HALT); 604 } 605 606 struct machine_ops machine_ops = { 607 .power_off = native_machine_power_off, 608 .shutdown = native_machine_shutdown, 609 .emergency_restart = native_machine_emergency_restart, 610 .restart = native_machine_restart, 611 .halt = native_machine_halt, 612 #ifdef CONFIG_KEXEC 613 .crash_shutdown = native_machine_crash_shutdown, 614 #endif 615 }; 616 617 void machine_power_off(void) 618 { 619 machine_ops.power_off(); 620 } 621 622 void machine_shutdown(void) 623 { 624 machine_ops.shutdown(); 625 } 626 627 void machine_emergency_restart(void) 628 { 629 __machine_emergency_restart(1); 630 } 631 632 void machine_restart(char *cmd) 633 { 634 machine_ops.restart(cmd); 635 } 636 637 void machine_halt(void) 638 { 639 machine_ops.halt(); 640 } 641 642 #ifdef CONFIG_KEXEC 643 void machine_crash_shutdown(struct pt_regs *regs) 644 { 645 machine_ops.crash_shutdown(regs); 646 } 647 #endif 648 649 650 #if defined(CONFIG_SMP) 651 652 /* This keeps a track of which one is crashing cpu. */ 653 static int crashing_cpu; 654 static nmi_shootdown_cb shootdown_callback; 655 656 static atomic_t waiting_for_crash_ipi; 657 658 static int crash_nmi_callback(unsigned int val, struct pt_regs *regs) 659 { 660 int cpu; 661 662 cpu = raw_smp_processor_id(); 663 664 /* 665 * Don't do anything if this handler is invoked on crashing cpu. 666 * Otherwise, system will completely hang. Crashing cpu can get 667 * an NMI if system was initially booted with nmi_watchdog parameter. 668 */ 669 if (cpu == crashing_cpu) 670 return NMI_HANDLED; 671 local_irq_disable(); 672 673 shootdown_callback(cpu, regs); 674 675 atomic_dec(&waiting_for_crash_ipi); 676 /* Assume hlt works */ 677 halt(); 678 for (;;) 679 cpu_relax(); 680 681 return NMI_HANDLED; 682 } 683 684 static void smp_send_nmi_allbutself(void) 685 { 686 apic->send_IPI_allbutself(NMI_VECTOR); 687 } 688 689 /* 690 * Halt all other CPUs, calling the specified function on each of them 691 * 692 * This function can be used to halt all other CPUs on crash 693 * or emergency reboot time. The function passed as parameter 694 * will be called inside a NMI handler on all CPUs. 695 */ 696 void nmi_shootdown_cpus(nmi_shootdown_cb callback) 697 { 698 unsigned long msecs; 699 local_irq_disable(); 700 701 /* Make a note of crashing cpu. Will be used in NMI callback. */ 702 crashing_cpu = safe_smp_processor_id(); 703 704 shootdown_callback = callback; 705 706 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); 707 /* Would it be better to replace the trap vector here? */ 708 if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback, 709 NMI_FLAG_FIRST, "crash")) 710 return; /* Return what? */ 711 /* 712 * Ensure the new callback function is set before sending 713 * out the NMI 714 */ 715 wmb(); 716 717 smp_send_nmi_allbutself(); 718 719 msecs = 1000; /* Wait at most a second for the other cpus to stop */ 720 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) { 721 mdelay(1); 722 msecs--; 723 } 724 725 /* Leave the nmi callback set */ 726 } 727 #else /* !CONFIG_SMP */ 728 void nmi_shootdown_cpus(nmi_shootdown_cb callback) 729 { 730 /* No other CPUs to shoot down */ 731 } 732 #endif 733