]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame_incremental - arch/x86/kernel/reboot.c
x86/mm: Flush global TLB when switching to trampoline page-table
[mirror_ubuntu-jammy-kernel.git] / arch / x86 / kernel / reboot.c
... / ...
CommitLineData
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#include <asm/nospec-branch.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(&rtc_lock);
113 CMOS_WRITE(0x00, 0x8f);
114 spin_unlock(&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 { /* Handle problems with rebooting on the Latitude E6520. */
493 .callback = set_pci_reboot,
494 .ident = "Dell Latitude E6520",
495 .matches = {
496 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
497 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6520"),
498 },
499 },
500 { /* Handle problems with rebooting on the OptiPlex 790. */
501 .callback = set_pci_reboot,
502 .ident = "Dell OptiPlex 790",
503 .matches = {
504 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
505 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 790"),
506 },
507 },
508 { /* Handle problems with rebooting on the OptiPlex 990. */
509 .callback = set_pci_reboot,
510 .ident = "Dell OptiPlex 990",
511 .matches = {
512 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
513 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 990"),
514 },
515 },
516 { /* Handle problems with rebooting on the Latitude E6220. */
517 .callback = set_pci_reboot,
518 .ident = "Dell Latitude E6220",
519 .matches = {
520 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
521 DMI_MATCH(DMI_PRODUCT_NAME, "Latitude E6220"),
522 },
523 },
524 { /* Handle problems with rebooting on the OptiPlex 390. */
525 .callback = set_pci_reboot,
526 .ident = "Dell OptiPlex 390",
527 .matches = {
528 DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
529 DMI_MATCH(DMI_PRODUCT_NAME, "OptiPlex 390"),
530 },
531 },
532 { }
533};
534
535static int __init reboot_init(void)
536{
537 int rv;
538
539 /*
540 * Only do the DMI check if reboot_type hasn't been overridden
541 * on the command line
542 */
543 if (!reboot_default)
544 return 0;
545
546 /*
547 * The DMI quirks table takes precedence. If no quirks entry
548 * matches and the ACPI Hardware Reduced bit is set and EFI
549 * runtime services are enabled, force EFI reboot.
550 */
551 rv = dmi_check_system(reboot_dmi_table);
552
553 if (!rv && efi_reboot_required() && !efi_runtime_disabled())
554 reboot_type = BOOT_EFI;
555
556 return 0;
557}
558core_initcall(reboot_init);
559
560static inline void kb_wait(void)
561{
562 int i;
563
564 for (i = 0; i < 0x10000; i++) {
565 if ((inb(0x64) & 0x02) == 0)
566 break;
567 udelay(2);
568 }
569}
570
571static void vmxoff_nmi(int cpu, struct pt_regs *regs)
572{
573 cpu_emergency_vmxoff();
574}
575
576/* Use NMIs as IPIs to tell all CPUs to disable virtualization */
577static void emergency_vmx_disable_all(void)
578{
579 /* Just make sure we won't change CPUs while doing this */
580 local_irq_disable();
581
582 /*
583 * Disable VMX on all CPUs before rebooting, otherwise we risk hanging
584 * the machine, because the CPU blocks INIT when it's in VMX root.
585 *
586 * We can't take any locks and we may be on an inconsistent state, so
587 * use NMIs as IPIs to tell the other CPUs to exit VMX root and halt.
588 *
589 * Do the NMI shootdown even if VMX if off on _this_ CPU, as that
590 * doesn't prevent a different CPU from being in VMX root operation.
591 */
592 if (cpu_has_vmx()) {
593 /* Safely force _this_ CPU out of VMX root operation. */
594 __cpu_emergency_vmxoff();
595
596 /* Halt and exit VMX root operation on the other CPUs. */
597 nmi_shootdown_cpus(vmxoff_nmi);
598 }
599}
600
601
602void __attribute__((weak)) mach_reboot_fixups(void)
603{
604}
605
606/*
607 * To the best of our knowledge Windows compatible x86 hardware expects
608 * the following on reboot:
609 *
610 * 1) If the FADT has the ACPI reboot register flag set, try it
611 * 2) If still alive, write to the keyboard controller
612 * 3) If still alive, write to the ACPI reboot register again
613 * 4) If still alive, write to the keyboard controller again
614 * 5) If still alive, call the EFI runtime service to reboot
615 * 6) If no EFI runtime service, call the BIOS to do a reboot
616 *
617 * We default to following the same pattern. We also have
618 * two other reboot methods: 'triple fault' and 'PCI', which
619 * can be triggered via the reboot= kernel boot option or
620 * via quirks.
621 *
622 * This means that this function can never return, it can misbehave
623 * by not rebooting properly and hanging.
624 */
625static void native_machine_emergency_restart(void)
626{
627 int i;
628 int attempt = 0;
629 int orig_reboot_type = reboot_type;
630 unsigned short mode;
631
632 if (reboot_emergency)
633 emergency_vmx_disable_all();
634
635 tboot_shutdown(TB_SHUTDOWN_REBOOT);
636
637 /* Tell the BIOS if we want cold or warm reboot */
638 mode = reboot_mode == REBOOT_WARM ? 0x1234 : 0;
639 *((unsigned short *)__va(0x472)) = mode;
640
641 /*
642 * If an EFI capsule has been registered with the firmware then
643 * override the reboot= parameter.
644 */
645 if (efi_capsule_pending(NULL)) {
646 pr_info("EFI capsule is pending, forcing EFI reboot.\n");
647 reboot_type = BOOT_EFI;
648 }
649
650 for (;;) {
651 /* Could also try the reset bit in the Hammer NB */
652 switch (reboot_type) {
653 case BOOT_ACPI:
654 acpi_reboot();
655 reboot_type = BOOT_KBD;
656 break;
657
658 case BOOT_KBD:
659 mach_reboot_fixups(); /* For board specific fixups */
660
661 for (i = 0; i < 10; i++) {
662 kb_wait();
663 udelay(50);
664 outb(0xfe, 0x64); /* Pulse reset low */
665 udelay(50);
666 }
667 if (attempt == 0 && orig_reboot_type == BOOT_ACPI) {
668 attempt = 1;
669 reboot_type = BOOT_ACPI;
670 } else {
671 reboot_type = BOOT_EFI;
672 }
673 break;
674
675 case BOOT_EFI:
676 efi_reboot(reboot_mode, NULL);
677 reboot_type = BOOT_BIOS;
678 break;
679
680 case BOOT_BIOS:
681 machine_real_restart(MRR_BIOS);
682
683 /* We're probably dead after this, but... */
684 reboot_type = BOOT_CF9_SAFE;
685 break;
686
687 case BOOT_CF9_FORCE:
688 port_cf9_safe = true;
689 fallthrough;
690
691 case BOOT_CF9_SAFE:
692 if (port_cf9_safe) {
693 u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
694 u8 cf9 = inb(0xcf9) & ~reboot_code;
695 outb(cf9|2, 0xcf9); /* Request hard reset */
696 udelay(50);
697 /* Actually do the reset */
698 outb(cf9|reboot_code, 0xcf9);
699 udelay(50);
700 }
701 reboot_type = BOOT_TRIPLE;
702 break;
703
704 case BOOT_TRIPLE:
705 idt_invalidate();
706 __asm__ __volatile__("int3");
707
708 /* We're probably dead after this, but... */
709 reboot_type = BOOT_KBD;
710 break;
711 }
712 }
713}
714
715void native_machine_shutdown(void)
716{
717 /* Stop the cpus and apics */
718#ifdef CONFIG_X86_IO_APIC
719 /*
720 * Disabling IO APIC before local APIC is a workaround for
721 * erratum AVR31 in "Intel Atom Processor C2000 Product Family
722 * Specification Update". In this situation, interrupts that target
723 * a Logical Processor whose Local APIC is either in the process of
724 * being hardware disabled or software disabled are neither delivered
725 * nor discarded. When this erratum occurs, the processor may hang.
726 *
727 * Even without the erratum, it still makes sense to quiet IO APIC
728 * before disabling Local APIC.
729 */
730 clear_IO_APIC();
731#endif
732
733#ifdef CONFIG_SMP
734 /*
735 * Stop all of the others. Also disable the local irq to
736 * not receive the per-cpu timer interrupt which may trigger
737 * scheduler's load balance.
738 */
739 local_irq_disable();
740 stop_other_cpus();
741#endif
742
743 lapic_shutdown();
744 restore_boot_irq_mode();
745
746#ifdef CONFIG_HPET_TIMER
747 hpet_disable();
748#endif
749
750#ifdef CONFIG_X86_64
751 x86_platform.iommu_shutdown();
752#endif
753}
754
755static void __machine_emergency_restart(int emergency)
756{
757 reboot_emergency = emergency;
758 machine_ops.emergency_restart();
759}
760
761static void native_machine_restart(char *__unused)
762{
763 pr_notice("machine restart\n");
764
765 if (!reboot_force)
766 machine_shutdown();
767 __machine_emergency_restart(0);
768}
769
770static void native_machine_halt(void)
771{
772 /* Stop other cpus and apics */
773 machine_shutdown();
774
775 tboot_shutdown(TB_SHUTDOWN_HALT);
776
777 stop_this_cpu(NULL);
778}
779
780static void native_machine_power_off(void)
781{
782 if (pm_power_off) {
783 if (!reboot_force)
784 machine_shutdown();
785 pm_power_off();
786 }
787 /* A fallback in case there is no PM info available */
788 tboot_shutdown(TB_SHUTDOWN_HALT);
789}
790
791struct machine_ops machine_ops __ro_after_init = {
792 .power_off = native_machine_power_off,
793 .shutdown = native_machine_shutdown,
794 .emergency_restart = native_machine_emergency_restart,
795 .restart = native_machine_restart,
796 .halt = native_machine_halt,
797#ifdef CONFIG_KEXEC_CORE
798 .crash_shutdown = native_machine_crash_shutdown,
799#endif
800};
801
802void machine_power_off(void)
803{
804 machine_ops.power_off();
805}
806
807void machine_shutdown(void)
808{
809 machine_ops.shutdown();
810}
811
812void machine_emergency_restart(void)
813{
814 __machine_emergency_restart(1);
815}
816
817void machine_restart(char *cmd)
818{
819 machine_ops.restart(cmd);
820}
821
822void machine_halt(void)
823{
824 machine_ops.halt();
825}
826
827#ifdef CONFIG_KEXEC_CORE
828void machine_crash_shutdown(struct pt_regs *regs)
829{
830 machine_ops.crash_shutdown(regs);
831}
832#endif
833
834
835/* This is the CPU performing the emergency shutdown work. */
836int crashing_cpu = -1;
837
838#if defined(CONFIG_SMP)
839
840static nmi_shootdown_cb shootdown_callback;
841
842static atomic_t waiting_for_crash_ipi;
843static int crash_ipi_issued;
844
845static int crash_nmi_callback(unsigned int val, struct pt_regs *regs)
846{
847 int cpu;
848
849 cpu = raw_smp_processor_id();
850
851 /*
852 * Don't do anything if this handler is invoked on crashing cpu.
853 * Otherwise, system will completely hang. Crashing cpu can get
854 * an NMI if system was initially booted with nmi_watchdog parameter.
855 */
856 if (cpu == crashing_cpu)
857 return NMI_HANDLED;
858 local_irq_disable();
859
860 shootdown_callback(cpu, regs);
861
862 atomic_dec(&waiting_for_crash_ipi);
863 /* Assume hlt works */
864 halt();
865 for (;;)
866 cpu_relax();
867
868 return NMI_HANDLED;
869}
870
871/*
872 * Halt all other CPUs, calling the specified function on each of them
873 *
874 * This function can be used to halt all other CPUs on crash
875 * or emergency reboot time. The function passed as parameter
876 * will be called inside a NMI handler on all CPUs.
877 */
878void nmi_shootdown_cpus(nmi_shootdown_cb callback)
879{
880 unsigned long msecs;
881 local_irq_disable();
882
883 /* Make a note of crashing cpu. Will be used in NMI callback. */
884 crashing_cpu = safe_smp_processor_id();
885
886 shootdown_callback = callback;
887
888 atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
889 /* Would it be better to replace the trap vector here? */
890 if (register_nmi_handler(NMI_LOCAL, crash_nmi_callback,
891 NMI_FLAG_FIRST, "crash"))
892 return; /* Return what? */
893 /*
894 * Ensure the new callback function is set before sending
895 * out the NMI
896 */
897 wmb();
898
899 apic_send_IPI_allbutself(NMI_VECTOR);
900
901 /* Kick CPUs looping in NMI context. */
902 WRITE_ONCE(crash_ipi_issued, 1);
903
904 msecs = 1000; /* Wait at most a second for the other cpus to stop */
905 while ((atomic_read(&waiting_for_crash_ipi) > 0) && msecs) {
906 mdelay(1);
907 msecs--;
908 }
909
910 /* Leave the nmi callback set */
911}
912
913/*
914 * Check if the crash dumping IPI got issued and if so, call its callback
915 * directly. This function is used when we have already been in NMI handler.
916 * It doesn't return.
917 */
918void run_crash_ipi_callback(struct pt_regs *regs)
919{
920 if (crash_ipi_issued)
921 crash_nmi_callback(0, regs);
922}
923
924/* Override the weak function in kernel/panic.c */
925void nmi_panic_self_stop(struct pt_regs *regs)
926{
927 while (1) {
928 /* If no CPU is preparing crash dump, we simply loop here. */
929 run_crash_ipi_callback(regs);
930 cpu_relax();
931 }
932}
933
934#else /* !CONFIG_SMP */
935void nmi_shootdown_cpus(nmi_shootdown_cb callback)
936{
937 /* No other CPUs to shoot down */
938}
939
940void run_crash_ipi_callback(struct pt_regs *regs)
941{
942}
943#endif