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