^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/dmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/tboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/objtool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <acpi/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <asm/apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <asm/io_apic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <asm/desc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/hpet.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/proto.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <asm/reboot_fixups.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <asm/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <asm/pci_x86.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <asm/virtext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <asm/cpu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <asm/nmi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <asm/smp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/ctype.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/mc146818rtc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/realmode.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/x86_init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/efi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Power off function, if any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) void (*pm_power_off)(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) EXPORT_SYMBOL(pm_power_off);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * This is set if we need to go through the 'emergency' path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * When machine_emergency_restart() is called, we may be on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * an inconsistent state and won't be able to do a clean cleanup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int reboot_emergency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) /* This is set by the PCI code if either type 1 or type 2 PCI is detected */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) bool port_cf9_safe = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * Reboot options and system auto-detection code provided by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Dell Inc. so their systems "just work". :-)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * Some machines require the "reboot=a" commandline options
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static int __init set_acpi_reboot(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if (reboot_type != BOOT_ACPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) reboot_type = BOOT_ACPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) pr_info("%s series board detected. Selecting %s-method for reboots.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) d->ident, "ACPI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) * Some machines require the "reboot=b" or "reboot=k" commandline options,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * this quirk makes that automatic.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static int __init set_bios_reboot(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (reboot_type != BOOT_BIOS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) reboot_type = BOOT_BIOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) pr_info("%s series board detected. Selecting %s-method for reboots.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) d->ident, "BIOS");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * Some machines don't handle the default ACPI reboot method and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * require the EFI reboot method:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static int __init set_efi_reboot(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (reboot_type != BOOT_EFI && !efi_runtime_disabled()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) reboot_type = BOOT_EFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) pr_info("%s series board detected. Selecting EFI-method for reboot.\n", d->ident);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void __noreturn machine_real_restart(unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Write zero to CMOS register number 0x0f, which the BIOS POST
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * routine will recognize as telling it to do a proper reboot. (Well
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * that's what this book in front of me says -- it may only apply to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * the Phoenix BIOS though, it's not clear). At the same time,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * disable NMIs by setting the top bit in the CMOS address register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * as we're about to do peculiar things to the CPU. I'm not sure if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * `outb_p' is needed instead of just `outb'. Use it to be on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * safe side. (Yes, CMOS_WRITE does outb_p's. - Paul G.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) spin_lock(&rtc_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) CMOS_WRITE(0x00, 0x8f);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) spin_unlock(&rtc_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) * Switch to the trampoline page table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) load_trampoline_pgtable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* Jump to the identity-mapped low memory code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) asm volatile("jmpl *%0" : :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) "rm" (real_mode_header->machine_real_restart_asm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) "a" (type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) asm volatile("ljmpl *%0" : :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) "m" (real_mode_header->machine_real_restart_asm),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) "D" (type));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) unreachable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) #ifdef CONFIG_APM_MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) EXPORT_SYMBOL(machine_real_restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) STACK_FRAME_NON_STANDARD(machine_real_restart);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * Some Apple MacBook and MacBookPro's needs reboot=p to be able to reboot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) static int __init set_pci_reboot(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (reboot_type != BOOT_CF9_FORCE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) reboot_type = BOOT_CF9_FORCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) pr_info("%s series board detected. Selecting %s-method for reboots.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) d->ident, "PCI");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) static int __init set_kbd_reboot(const struct dmi_system_id *d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (reboot_type != BOOT_KBD) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) reboot_type = BOOT_KBD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) pr_info("%s series board detected. Selecting %s-method for reboot.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) d->ident, "KBD");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * This is a single dmi_table handling all reboot quirks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static const struct dmi_system_id reboot_dmi_table[] __initconst = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* Acer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) { /* Handle reboot issue on Acer Aspire one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) .callback = set_kbd_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) .ident = "Acer Aspire One A110",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) DMI_MATCH(DMI_PRODUCT_NAME, "AOA110"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) { /* Handle reboot issue on Acer TravelMate X514-51T */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) .callback = set_efi_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) .ident = "Acer TravelMate X514-51T",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) DMI_MATCH(DMI_PRODUCT_NAME, "TravelMate X514-51T"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* Apple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) { /* Handle problems with rebooting on Apple MacBook5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) .ident = "Apple MacBook5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) DMI_MATCH(DMI_PRODUCT_NAME, "MacBook5"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) { /* Handle problems with rebooting on Apple MacBook6,1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) .ident = "Apple MacBook6,1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) DMI_MATCH(DMI_PRODUCT_NAME, "MacBook6,1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) { /* Handle problems with rebooting on Apple MacBookPro5 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) .ident = "Apple MacBookPro5",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro5"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) { /* Handle problems with rebooting on Apple Macmini3,1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) .ident = "Apple Macmini3,1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) DMI_MATCH(DMI_PRODUCT_NAME, "Macmini3,1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) { /* Handle problems with rebooting on the iMac9,1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) .ident = "Apple iMac9,1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) DMI_MATCH(DMI_PRODUCT_NAME, "iMac9,1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) { /* Handle problems with rebooting on the iMac10,1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) .ident = "Apple iMac10,1",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) DMI_MATCH(DMI_PRODUCT_NAME, "iMac10,1"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* ASRock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) { /* Handle problems with rebooting on ASRock Q1900DC-ITX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) .ident = "ASRock Q1900DC-ITX",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) DMI_MATCH(DMI_BOARD_VENDOR, "ASRock"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) DMI_MATCH(DMI_BOARD_NAME, "Q1900DC-ITX"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) /* ASUS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) { /* Handle problems with rebooting on ASUS P4S800 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) .ident = "ASUS P4S800",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK Computer INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) DMI_MATCH(DMI_BOARD_NAME, "P4S800"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) { /* Handle problems with rebooting on ASUS EeeBook X205TA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) .callback = set_acpi_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) .ident = "ASUS EeeBook X205TA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) DMI_MATCH(DMI_PRODUCT_NAME, "X205TA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) { /* Handle problems with rebooting on ASUS EeeBook X205TAW */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) .callback = set_acpi_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) .ident = "ASUS EeeBook X205TAW",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) DMI_MATCH(DMI_PRODUCT_NAME, "X205TAW"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* Certec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) { /* Handle problems with rebooting on Certec BPC600 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) .ident = "Certec BPC600",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) DMI_MATCH(DMI_SYS_VENDOR, "Certec"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) DMI_MATCH(DMI_PRODUCT_NAME, "BPC600"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* Dell */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) { /* Handle problems with rebooting on Dell DXP061 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) .ident = "Dell DXP061",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) DMI_MATCH(DMI_PRODUCT_NAME, "Dell DXP061"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) { /* Handle problems with rebooting on Dell E520's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) .ident = "Dell E520",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) DMI_MATCH(DMI_PRODUCT_NAME, "Dell DM061"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) { /* Handle problems with rebooting on the Latitude E5410. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) .ident = "Dell Latitude E5410",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5410"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) { /* Handle problems with rebooting on the Latitude E5420. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) .ident = "Dell Latitude E5420",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E5420"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) { /* Handle problems with rebooting on the Latitude E6320. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) .ident = "Dell Latitude E6320",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6320"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) { /* Handle problems with rebooting on the Latitude E6420. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) .ident = "Dell Latitude E6420",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6420"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) { /* Handle problems with rebooting on Dell Optiplex 330 with 0KP561 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .ident = "Dell OptiPlex 330",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 330"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) DMI_MATCH(DMI_BOARD_NAME, "0KP561"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) { /* Handle problems with rebooting on Dell Optiplex 360 with 0T656F */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .ident = "Dell OptiPlex 360",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 360"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) DMI_MATCH(DMI_BOARD_NAME, "0T656F"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) { /* Handle problems with rebooting on Dell Optiplex 745's SFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) .ident = "Dell OptiPlex 745",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) { /* Handle problems with rebooting on Dell Optiplex 745's DFF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) .ident = "Dell OptiPlex 745",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) DMI_MATCH(DMI_BOARD_NAME, "0MM599"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) { /* Handle problems with rebooting on Dell Optiplex 745 with 0KW626 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) .ident = "Dell OptiPlex 745",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 745"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) DMI_MATCH(DMI_BOARD_NAME, "0KW626"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) { /* Handle problems with rebooting on Dell OptiPlex 760 with 0G919G */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .ident = "Dell OptiPlex 760",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 760"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) DMI_MATCH(DMI_BOARD_NAME, "0G919G"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) { /* Handle problems with rebooting on the OptiPlex 990. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) .ident = "Dell OptiPlex 990 BIOS A0x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) DMI_MATCH(DMI_BIOS_VERSION, "A0"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) { /* Handle problems with rebooting on Dell 300's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) .ident = "Dell PowerEdge 300",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 300/"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) { /* Handle problems with rebooting on Dell 1300's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) .ident = "Dell PowerEdge 1300",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 1300/"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) { /* Handle problems with rebooting on Dell 2400's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) .ident = "Dell PowerEdge 2400",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) DMI_MATCH(DMI_SYS_VENDOR, "Dell Computer Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2400"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) { /* Handle problems with rebooting on the Dell PowerEdge C6100. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) .ident = "Dell PowerEdge C6100",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) DMI_MATCH(DMI_SYS_VENDOR, "Dell"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) DMI_MATCH(DMI_PRODUCT_NAME, "C6100"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) { /* Handle problems with rebooting on the Precision M6600. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) .ident = "Dell Precision M6600",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) DMI_MATCH(DMI_PRODUCT_NAME, "Precision M6600"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) { /* Handle problems with rebooting on Dell T5400's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) .ident = "Dell Precision T5400",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T5400"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) { /* Handle problems with rebooting on Dell T7400's */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) .ident = "Dell Precision T7400",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) DMI_MATCH(DMI_PRODUCT_NAME, "Precision WorkStation T7400"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) { /* Handle problems with rebooting on Dell XPS710 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) .ident = "Dell XPS710",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) DMI_MATCH(DMI_PRODUCT_NAME, "Dell XPS710"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) { /* Handle problems with rebooting on Dell Optiplex 7450 AIO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) .callback = set_acpi_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) .ident = "Dell OptiPlex 7450 AIO",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 7450 AIO"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /* Hewlett-Packard */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) { /* Handle problems with rebooting on HP laptops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .ident = "HP Compaq Laptop",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) DMI_MATCH(DMI_SYS_VENDOR, "Hewlett-Packard"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) { /* PCIe Wifi card isn't detected after reboot otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) .callback = set_pci_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) .ident = "Zotac ZBOX CI327 nano",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) DMI_MATCH(DMI_SYS_VENDOR, "NA"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) DMI_MATCH(DMI_PRODUCT_NAME, "ZBOX-CI327NANO-GS-01"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) /* Sony */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) { /* Handle problems with rebooting on Sony VGN-Z540N */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) .callback = set_bios_reboot,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) .ident = "Sony VGN-Z540N",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) .matches = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) DMI_MATCH(DMI_PRODUCT_NAME, "VGN-Z540N"),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static int __init reboot_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) int rv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) * Only do the DMI check if reboot_type hasn't been overridden
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) * on the command line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) if (!reboot_default)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * The DMI quirks table takes precedence. If no quirks entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * matches and the ACPI Hardware Reduced bit is set and EFI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * runtime services are enabled, force EFI reboot.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) rv = dmi_check_system(reboot_dmi_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) if (!rv && efi_reboot_required() && !efi_runtime_disabled())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) reboot_type = BOOT_EFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) core_initcall(reboot_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static inline void kb_wait(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) for (i = 0; i < 0x10000; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if ((inb(0x64) & 0x02) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) udelay(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) static void vmxoff_nmi(int cpu, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) cpu_emergency_vmxoff();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /* Use NMIs as IPIs to tell all CPUs to disable virtualization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) static void emergency_vmx_disable_all(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) /* Just make sure we won't change CPUs while doing this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * Disable VMX on all CPUs before rebooting, otherwise we risk hanging
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) * the machine, because the CPU blocks INIT when it's in VMX root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * We can't take any locks and we may be on an inconsistent state, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * use NMIs as IPIs to tell the other CPUs to exit VMX root and halt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * Do the NMI shootdown even if VMX if off on _this_ CPU, as that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * doesn't prevent a different CPU from being in VMX root operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (cpu_has_vmx()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* Safely force _this_ CPU out of VMX root operation. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) __cpu_emergency_vmxoff();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* Halt and exit VMX root operation on the other CPUs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) nmi_shootdown_cpus(vmxoff_nmi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) void __attribute__((weak)) mach_reboot_fixups(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * To the best of our knowledge Windows compatible x86 hardware expects
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) * the following on reboot:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) * 1) If the FADT has the ACPI reboot register flag set, try it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * 2) If still alive, write to the keyboard controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * 3) If still alive, write to the ACPI reboot register again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * 4) If still alive, write to the keyboard controller again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * 5) If still alive, call the EFI runtime service to reboot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * 6) If no EFI runtime service, call the BIOS to do a reboot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * We default to following the same pattern. We also have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * two other reboot methods: 'triple fault' and 'PCI', which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * can be triggered via the reboot= kernel boot option or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * via quirks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * This means that this function can never return, it can misbehave
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * by not rebooting properly and hanging.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void native_machine_emergency_restart(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) int attempt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) int orig_reboot_type = reboot_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) unsigned short mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (reboot_emergency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) emergency_vmx_disable_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) tboot_shutdown(TB_SHUTDOWN_REBOOT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) /* Tell the BIOS if we want cold or warm reboot */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *((unsigned short *)__va(0x472)) = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) * If an EFI capsule has been registered with the firmware then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) * override the reboot= parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (efi_capsule_pending(NULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) pr_info("EFI capsule is pending, forcing EFI reboot.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) reboot_type = BOOT_EFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /* Could also try the reset bit in the Hammer NB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) switch (reboot_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) case BOOT_ACPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) acpi_reboot();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) reboot_type = BOOT_KBD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) case BOOT_KBD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) mach_reboot_fixups(); /* For board specific fixups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) for (i = 0; i < 10; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) kb_wait();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) outb(0xfe, 0x64); /* Pulse reset low */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) attempt = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) reboot_type = BOOT_ACPI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) reboot_type = BOOT_EFI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) case BOOT_EFI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) efi_reboot(reboot_mode, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) reboot_type = BOOT_BIOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case BOOT_BIOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) machine_real_restart(MRR_BIOS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /* We're probably dead after this, but... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) reboot_type = BOOT_CF9_SAFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) case BOOT_CF9_FORCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) port_cf9_safe = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) case BOOT_CF9_SAFE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (port_cf9_safe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) u8 cf9 = inb(0xcf9) & ~reboot_code;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) outb(cf9|2, 0xcf9); /* Request hard reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) /* Actually do the reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) outb(cf9|reboot_code, 0xcf9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) udelay(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) reboot_type = BOOT_TRIPLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) case BOOT_TRIPLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) idt_invalidate(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) __asm__ __volatile__("int3");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) /* We're probably dead after this, but... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) reboot_type = BOOT_KBD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) void native_machine_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) /* Stop the cpus and apics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) #ifdef CONFIG_X86_IO_APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Disabling IO APIC before local APIC is a workaround for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * erratum AVR31 in "Intel Atom Processor C2000 Product Family
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * Specification Update". In this situation, interrupts that target
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) * a Logical Processor whose Local APIC is either in the process of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) * being hardware disabled or software disabled are neither delivered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * nor discarded. When this erratum occurs, the processor may hang.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * Even without the erratum, it still makes sense to quiet IO APIC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * before disabling Local APIC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) clear_IO_APIC();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) #ifdef CONFIG_SMP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * Stop all of the others. Also disable the local irq to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * not receive the per-cpu timer interrupt which may trigger
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) * scheduler's load balance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) stop_other_cpus();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) lapic_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) restore_boot_irq_mode();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) #ifdef CONFIG_HPET_TIMER
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) hpet_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) x86_platform.iommu_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) static void __machine_emergency_restart(int emergency)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) reboot_emergency = emergency;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) machine_ops.emergency_restart();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) static void native_machine_restart(char *__unused)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) pr_notice("machine restart\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (!reboot_force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) machine_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) __machine_emergency_restart(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) static void native_machine_halt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) /* Stop other cpus and apics */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) machine_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) tboot_shutdown(TB_SHUTDOWN_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) stop_this_cpu(NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) static void native_machine_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (pm_power_off) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!reboot_force)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) machine_shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) pm_power_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* A fallback in case there is no PM info available */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) tboot_shutdown(TB_SHUTDOWN_HALT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct machine_ops machine_ops __ro_after_init = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) .power_off = native_machine_power_off,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) .shutdown = native_machine_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) .emergency_restart = native_machine_emergency_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .restart = native_machine_restart,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) .halt = native_machine_halt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) #ifdef CONFIG_KEXEC_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) .crash_shutdown = native_machine_crash_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) void machine_power_off(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) machine_ops.power_off();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) void machine_shutdown(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) machine_ops.shutdown();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) void machine_emergency_restart(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) __machine_emergency_restart(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) void machine_restart(char *cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) machine_ops.restart(cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) void machine_halt(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) machine_ops.halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) #ifdef CONFIG_KEXEC_CORE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) void machine_crash_shutdown(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) machine_ops.crash_shutdown(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* This is the CPU performing the emergency shutdown work. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) int crashing_cpu = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) #if defined(CONFIG_SMP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) static nmi_shootdown_cb shootdown_callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) static atomic_t waiting_for_crash_ipi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) static int crash_ipi_issued;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) int cpu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) cpu = raw_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * Don't do anything if this handler is invoked on crashing cpu.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) * Otherwise, system will completely hang. Crashing cpu can get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * an NMI if system was initially booted with nmi_watchdog parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) if (cpu == crashing_cpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return NMI_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) shootdown_callback(cpu, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) atomic_dec(&waiting_for_crash_ipi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* Assume hlt works */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) halt();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) for (;;)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return NMI_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) * Halt all other CPUs, calling the specified function on each of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) * This function can be used to halt all other CPUs on crash
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) * or emergency reboot time. The function passed as parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * will be called inside a NMI handler on all CPUs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) void nmi_shootdown_cpus(nmi_shootdown_cb callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) unsigned long msecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) local_irq_disable();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) /* Make a note of crashing cpu. Will be used in NMI callback. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) crashing_cpu = safe_smp_processor_id();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) shootdown_callback = callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /* Would it be better to replace the trap vector here? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) NMI_FLAG_FIRST, "crash"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) return; /* Return what? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * Ensure the new callback function is set before sending
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * out the NMI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) wmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) apic_send_IPI_allbutself(NMI_VECTOR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /* Kick CPUs looping in NMI context. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) WRITE_ONCE(crash_ipi_issued, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) msecs = 1000; /* Wait at most a second for the other cpus to stop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) mdelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) msecs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) /* Leave the nmi callback set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * Check if the crash dumping IPI got issued and if so, call its callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * directly. This function is used when we have already been in NMI handler.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * It doesn't return.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) void run_crash_ipi_callback(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (crash_ipi_issued)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) crash_nmi_callback(0, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* Override the weak function in kernel/panic.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) void nmi_panic_self_stop(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) /* If no CPU is preparing crash dump, we simply loop here. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) run_crash_ipi_callback(regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) #else /* !CONFIG_SMP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) void nmi_shootdown_cpus(nmi_shootdown_cb callback)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) /* No other CPUs to shoot down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) void run_crash_ipi_callback(struct pt_regs *regs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) #endif