cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

reboot.c (23296B)


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