diff options
Diffstat (limited to 'arch/x86/kernel/reboot.c')
-rw-r--r-- | arch/x86/kernel/reboot.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 08c44b08bf5b..0c016f727695 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -36,7 +36,7 @@ EXPORT_SYMBOL(pm_power_off); | |||
36 | 36 | ||
37 | static const struct desc_ptr no_idt = {}; | 37 | static const struct desc_ptr no_idt = {}; |
38 | static int reboot_mode; | 38 | static int reboot_mode; |
39 | enum reboot_type reboot_type = BOOT_KBD; | 39 | enum reboot_type reboot_type = BOOT_ACPI; |
40 | int reboot_force; | 40 | int reboot_force; |
41 | 41 | ||
42 | #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) | 42 | #if defined(CONFIG_X86_32) && defined(CONFIG_SMP) |
@@ -478,9 +478,24 @@ void __attribute__((weak)) mach_reboot_fixups(void) | |||
478 | { | 478 | { |
479 | } | 479 | } |
480 | 480 | ||
481 | /* | ||
482 | * Windows compatible x86 hardware expects the following on reboot: | ||
483 | * | ||
484 | * 1) If the FADT has the ACPI reboot register flag set, try it | ||
485 | * 2) If still alive, write to the keyboard controller | ||
486 | * 3) If still alive, write to the ACPI reboot register again | ||
487 | * 4) If still alive, write to the keyboard controller again | ||
488 | * | ||
489 | * If the machine is still alive at this stage, it gives up. We default to | ||
490 | * following the same pattern, except that if we're still alive after (4) we'll | ||
491 | * try to force a triple fault and then cycle between hitting the keyboard | ||
492 | * controller and doing that | ||
493 | */ | ||
481 | static void native_machine_emergency_restart(void) | 494 | static void native_machine_emergency_restart(void) |
482 | { | 495 | { |
483 | int i; | 496 | int i; |
497 | int attempt = 0; | ||
498 | int orig_reboot_type = reboot_type; | ||
484 | 499 | ||
485 | if (reboot_emergency) | 500 | if (reboot_emergency) |
486 | emergency_vmx_disable_all(); | 501 | emergency_vmx_disable_all(); |
@@ -502,6 +517,13 @@ static void native_machine_emergency_restart(void) | |||
502 | outb(0xfe, 0x64); /* pulse reset low */ | 517 | outb(0xfe, 0x64); /* pulse reset low */ |
503 | udelay(50); | 518 | udelay(50); |
504 | } | 519 | } |
520 | if (attempt == 0 && orig_reboot_type == BOOT_ACPI) { | ||
521 | attempt = 1; | ||
522 | reboot_type = BOOT_ACPI; | ||
523 | } else { | ||
524 | reboot_type = BOOT_TRIPLE; | ||
525 | } | ||
526 | break; | ||
505 | 527 | ||
506 | case BOOT_TRIPLE: | 528 | case BOOT_TRIPLE: |
507 | load_idt(&no_idt); | 529 | load_idt(&no_idt); |