summaryrefslogtreecommitdiff
path: root/arch/x86/boot/compressed/head_32.S
diff options
context:
space:
mode:
authorArvind Sankar <nivedita@alum.mit.edu>2020-02-02 12:13:51 -0500
committerArd Biesheuvel <ardb@kernel.org>2020-02-22 23:37:37 +0100
commitef5a7b5eb13ed88ba9690ab27def3a085332cc8c (patch)
tree33800f398124e6675d2f2f00a5853f77694c50aa /arch/x86/boot/compressed/head_32.S
parentcae0e431a02cd63fecaf677ae166f184644125a7 (diff)
efi/x86: Remove GDT setup from efi_main
The 64-bit kernel will already load a GDT in startup_64, which is the next function to execute after return from efi_main. Add GDT setup code to the 32-bit kernel's startup_32 as well. Doing it in the head code has the advantage that we can avoid potentially corrupting the GDT during copy/decompression. This also removes dependence on having a specific GDT layout setup by the bootloader. Both startup_32 and startup_64 now clear interrupts on entry, so we can remove that from efi_main as well. Signed-off-by: Arvind Sankar <nivedita@alum.mit.edu> Link: https://lore.kernel.org/r/20200202171353.3736319-6-nivedita@alum.mit.edu Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Diffstat (limited to 'arch/x86/boot/compressed/head_32.S')
-rw-r--r--arch/x86/boot/compressed/head_32.S40
1 files changed, 34 insertions, 6 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index cb2cb91fce45..356060c5332c 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -64,12 +64,6 @@
SYM_FUNC_START(startup_32)
cld
cli
- movl $__BOOT_DS, %eax
- movl %eax, %ds
- movl %eax, %es
- movl %eax, %fs
- movl %eax, %gs
- movl %eax, %ss
/*
* Calculate the delta between where we were compiled to run
@@ -84,6 +78,19 @@ SYM_FUNC_START(startup_32)
1: popl %ebp
subl $1b, %ebp
+ /* Load new GDT */
+ leal gdt(%ebp), %eax
+ movl %eax, 2(%eax)
+ lgdt (%eax)
+
+ /* Load segment registers with our descriptors */
+ movl $__BOOT_DS, %eax
+ movl %eax, %ds
+ movl %eax, %es
+ movl %eax, %fs
+ movl %eax, %gs
+ movl %eax, %ss
+
/*
* %ebp contains the address we are loaded at by the boot loader and %ebx
* contains the address where we should move the kernel image temporarily
@@ -129,6 +136,16 @@ SYM_FUNC_START(startup_32)
cld
popl %esi
+ /*
+ * The GDT may get overwritten either during the copy we just did or
+ * during extract_kernel below. To avoid any issues, repoint the GDTR
+ * to the new copy of the GDT. EAX still contains the previously
+ * calculated relocation offset of init_size - _end.
+ */
+ leal gdt(%ebx), %edx
+ addl %eax, 2(%edx)
+ lgdt (%edx)
+
/*
* Jump to the relocated address.
*/
@@ -201,6 +218,17 @@ SYM_FUNC_START_LOCAL_NOALIGN(.Lrelocated)
jmp *%eax
SYM_FUNC_END(.Lrelocated)
+ .data
+ .balign 8
+SYM_DATA_START_LOCAL(gdt)
+ .word gdt_end - gdt - 1
+ .long 0
+ .word 0
+ .quad 0x0000000000000000 /* Reserved */
+ .quad 0x00cf9a000000ffff /* __KERNEL_CS */
+ .quad 0x00cf92000000ffff /* __KERNEL_DS */
+SYM_DATA_END_LABEL(gdt, SYM_L_LOCAL, gdt_end)
+
/*
* Stack and heap for uncompression
*/