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