x86/reboot changes for v3.6
Linus,
Please pull the latest x86-reboot-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git x86-reboot-for-linus
HEAD: 9751d7627582fc1cc64625d63bde9528c14f1544 x86-64, reboot: Be more paranoid in 64-bit reboot=bios
Now that the revampted x86 real-mode trampoline code is upstream and seems to be working well, we can extend the 64-bit reboot code to be as capable as the 32-bit one.
Thanks,
Ingo
------------------>
H. Peter Anvin (3):
x86-64, reboot: Allow reboot=bios and reboot-cpu override on x86-64 x86, reboot: Drop redundant write of reboot_mode x86-64, reboot: Be more paranoid in 64-bit reboot=bios
arch/x86/include/asm/emergency-restart.h | 2 -
arch/x86/include/asm/realmode.h | 3 +-
arch/x86/include/asm/reboot.h | 4 +-
arch/x86/kernel/reboot.c | 60 ++++++++++--------------
arch/x86/realmode/rm/Makefile | 2 +-
arch/x86/realmode/rm/header.S | 4 +-
arch/x86/realmode/rm/{reboot_32.S => reboot.S} | 30 ++++++++++--
7 files changed, 59 insertions(+), 46 deletions(-)
rename arch/x86/realmode/rm/{reboot_32.S => reboot.S} (85%)arch/x86/include/asm/emergency-restart.h +0 -2
@@ -4,9 +4,7 @@enum reboot_type {BOOT_TRIPLE ='t' ,BOOT_KBD ='k' , -#ifdef CONFIG_X86_32 BOOT_BIOS ='b' , -#endif BOOT_ACPI ='a' ,BOOT_EFI ='e' ,BOOT_CF9 ='p' ,
arch/x86/include/asm/realmode.h +2 -1
@@ -21,8 +21,9 @@ struct real_mode_header {u32 wakeup_header;#endif /* APM/BIOS reboot */ -#ifdef CONFIG_X86_32 u32 machine_real_restart_asm; +#ifdef CONFIG_X86_64 +u32 machine_real_restart_seg;#endif };
arch/x86/include/asm/reboot.h +2 -2
@@ -18,8 +18,8 @@ extern struct machine_ops machine_ops;void native_machine_crash_shutdown (struct pt_regs *regs);void native_machine_shutdown (void ); -void machine_real_restart (unsigned int type); -/* These must match dispatch_table in reboot_32.S */ +void __noreturn machine_real_restart (unsigned int type); +/* These must match dispatch in arch/x86/realmore/rm/reboot.S */ #define MRR_BIOS 0#define MRR_APM 1
arch/x86/kernel/reboot.c +24 -36
153 lines not on this page · raw message
arch/x86/realmode/rm/Makefile +1 -1
@@ -22,7 +22,7 @@ wakeup-objs += video-bios.o realmode-y += header.o realmode-y += trampoline_$(BITS).o realmode-y += stack.o -realmode-$(CONFIG_X86_32) += reboot_32.o +realmode-y += reboot.o realmode-$(CONFIG_ACPI_SLEEP) += $(wakeup-objs) targets += $(realmode-y)
arch/x86/realmode/rm/header.S +3 -1
@@ -6,6 +6,7 @@ #include <linux/linkage.h> #include <asm/page_types.h> +#include <asm/segment.h> #include "realmode.h"
@@ -28,8 +29,9 @@ GLOBAL(real_mode_header) .long pa_wakeup_header #endif /* APM/BIOS reboot */ -#ifdef CONFIG_X86_32 .long pa_machine_real_restart_asm +#ifdef CONFIG_X86_64 + .long __KERNEL32_CS #endif END(real_mode_header)
arch/x86/realmode/rm/reboot.S renamed from arch/x86/realmode/rm/reboot_32.S +27 -3
@@ -2,6 +2,8 @@ #include <linux/init.h> #include <asm/segment.h> #include <asm/page_types.h> +#include <asm/processor-flags.h> +#include <asm/msr-index.h> #include "realmode.h" /*
@@ -12,13 +14,35 @@ * doesn't work with at least one type of 486 motherboard. It is easy * to stop this code working; hence the copious comments. * - * This code is called with the restart type (0 = BIOS, 1 = APM) in %eax. + * This code is called with the restart type (0 = BIOS, 1 = APM) in + * the primary argument register (%eax for 32 bit, %edi for 64 bit). */ .section ".text32", "ax" .code32 - - .balign 16 ENTRY(machine_real_restart_asm) + +#ifdef CONFIG_X86_64 + /* Switch to trampoline GDT as it is guaranteed < 4 GiB */ + movl $__KERNEL_DS, %eax + movl %eax, %ds + lgdtl pa_tr_gdt + + /* Disable paging to drop us out of long mode */ + movl %cr0, %eax + andl $~X86_CR0_PG, %eax + movl %eax, %cr0 + ljmpl $__KERNEL32_CS, $pa_machine_real_restart_paging_off + +GLOBAL(machine_real_restart_paging_off) + xorl %eax, %eax + xorl %edx, %edx + movl $MSR_EFER, %ecx + wrmsr + + movl %edi, %eax + +#endif /* CONFIG_X86_64 */ + /* Set up the IDT for real mode. */ lidtl pa_machine_real_restart_idt