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

source code of linux/arch/x86/kernel/reboot.c