GIT e6e14b0608322fd02ab89e34c730d8c6c5d05fc7 git+ssh://master.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-x86setup.git commit Author: H. Peter Anvin Date: Fri Nov 9 22:17:23 2007 -0800 x86 setup: use X86_CR0_PE macro instead of hard-coded constant To set CR0.PE, use the X86_CR0_PE macro defined in instead of hardcoding it as a constant (1). Signed-off-by: H. Peter Anvin commit 88686eff7b987fa37036e88b57b7da60e2d47b75 Author: H. Peter Anvin Date: Mon Nov 5 12:21:47 2007 -0800 x86 setup: initialize LDTR and TR to make life easier to Intel VT Intel VT doesn't like to engage when the protected-mode state isn't fully initialized. Make life easier for it by initializing LDTR (to null) and TR (to a dummy hunk of low memory which will never actually be touched.) Signed-off-by: H. Peter Anvin commit 5512897906c2b404add0722d44c182844c8571c8 Author: H. Peter Anvin Date: Mon Nov 5 11:20:14 2007 -0800 x86 setup: make PM transition more paranoid; cleanup 32-bit entry Make the transition to protected mode more paranoid by having back-to-back near jump (to synchronize the 386/486 prefetch queue) and far jump (to set up the code segment.) While we're at it, zero as many registers as practical (for future expandability of the 32-bit entry interface) and enter 32-bit mode with a valid stack. Note that the 32-bit code cannot rely on this stack, or we'll break all other existing users of the 32-bit entrypoint, but it may make debugging hacks easier to write. Signed-off-by: H. Peter Anvin arch/x86/boot/pm.c | 4 +++ arch/x86/boot/pmjump.S | 54 +++++++++++++++++++++++++++++++---------- include/asm-x86/segment_32.h | 3 ++ include/asm-x86/segment_64.h | 3 ++ 4 files changed, 51 insertions(+), 13 deletions(-) diff --git a/arch/x86/boot/pm.c b/arch/x86/boot/pm.c index 09fb342..b23cbdc 100644 --- a/arch/x86/boot/pm.c +++ b/arch/x86/boot/pm.c @@ -121,6 +121,10 @@ static void setup_gdt(void) [GDT_ENTRY_BOOT_CS] = GDT_ENTRY(0xc09b, 0, 0xfffff), /* DS: data, read/write, 4 GB, base 0 */ [GDT_ENTRY_BOOT_DS] = GDT_ENTRY(0xc093, 0, 0xfffff), + /* TSS: 32-bit tss, 104 bytes, base 4096 */ + /* We only have a TSS here to keep Intel VT happy; + we don't actually use it for anything. */ + [GDT_ENTRY_BOOT_TSS] = GDT_ENTRY(0x0089, 4096, 103), }; /* Xen HVM incorrectly stores a pointer to the gdt_ptr, instead of the gdt_ptr contents. Thus, make it static so it will diff --git a/arch/x86/boot/pmjump.S b/arch/x86/boot/pmjump.S index fa6bed1..f5402d5 100644 --- a/arch/x86/boot/pmjump.S +++ b/arch/x86/boot/pmjump.S @@ -15,6 +15,7 @@ */ #include +#include #include .text @@ -29,28 +30,55 @@ */ protected_mode_jump: movl %edx, %esi # Pointer to boot_params table - movl %eax, 2f # Patch ljmpl instruction + + xorl %ebx, %ebx + movw %cs, %bx + shll $4, %ebx + addl %ebx, 2f movw $__BOOT_DS, %cx - xorl %ebx, %ebx # Per the 32-bit boot protocol - xorl %ebp, %ebp # Per the 32-bit boot protocol - xorl %edi, %edi # Per the 32-bit boot protocol + movw $__BOOT_TSS, %di movl %cr0, %edx - orb $1, %dl # Protected mode (PE) bit + orb $X86_CR0_PE, %dl # Protected mode movl %edx, %cr0 jmp 1f # Short jump to serialize on 386/486 1: - movw %cx, %ds - movw %cx, %es - movw %cx, %fs - movw %cx, %gs - movw %cx, %ss - - # Jump to the 32-bit entrypoint + # Transition to 32-bit mode .byte 0x66, 0xea # ljmpl opcode -2: .long 0 # offset +2: .long in_pm32 # offset .word __BOOT_CS # segment .size protected_mode_jump, .-protected_mode_jump + + .code32 + .type in_pm32, @function +in_pm32: + # Set up data segments for flat 32-bit mode + movl %ecx, %ds + movl %ecx, %es + movl %ecx, %fs + movl %ecx, %gs + movl %ecx, %ss + # The 32-bit code sets up its own stack, but this way we do have + # a valid stack if some debugging hack wants to use it. + addl %ebx, %esp + + # Set up TR to make Intel VT happy + ltr %di + + # Clear registers to allow for future extensions to the + # 32-bit boot protocol + xorl %ecx, %ecx + xorl %edx, %edx + xorl %ebx, %ebx + xorl %ebp, %ebp + xorl %edi, %edi + + # Set up LDTR to make Intel VT happy + lldt %cx + + jmpl *%eax # Jump to the 32-bit entrypoint + + .size in_pm32, .-in_pm32 diff --git a/include/asm-x86/segment_32.h b/include/asm-x86/segment_32.h index 597a47c..8b72d57 100644 --- a/include/asm-x86/segment_32.h +++ b/include/asm-x86/segment_32.h @@ -97,6 +97,9 @@ #define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) +#define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2) +#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) + /* The PnP BIOS entries in the GDT */ #define GDT_ENTRY_PNPBIOS_CS32 (GDT_ENTRY_PNPBIOS_BASE + 0) #define GDT_ENTRY_PNPBIOS_CS16 (GDT_ENTRY_PNPBIOS_BASE + 1) diff --git a/include/asm-x86/segment_64.h b/include/asm-x86/segment_64.h index 04b8ab2..0fb1214 100644 --- a/include/asm-x86/segment_64.h +++ b/include/asm-x86/segment_64.h @@ -11,6 +11,9 @@ #define GDT_ENTRY_BOOT_DS (GDT_ENTRY_BOOT_CS + 1) #define __BOOT_DS (GDT_ENTRY_BOOT_DS * 8) +#define GDT_ENTRY_BOOT_TSS (GDT_ENTRY_BOOT_CS + 2) +#define __BOOT_TSS (GDT_ENTRY_BOOT_TSS * 8) + #define __KERNEL_CS 0x10 #define __KERNEL_DS 0x18