aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorMatt Fleming <matt@console-pimps.org>2014-04-08 08:14:00 -0400
committerMatt Fleming <matt.fleming@intel.com>2014-04-10 16:19:52 -0400
commit7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 (patch)
tree6a24e3cd7ca9994d165bd38e83567ab546d01a92 /arch/x86/boot
parent396f1a08db212138418b38f784e4bbe516d2fdb2 (diff)
x86/efi: Correct EFI boot stub use of code32_start
code32_start should point at the start of the protected mode code, and *not* at the beginning of the bzImage. This is much easier to do in assembly so document that callers of make_boot_params() need to fill out code32_start. The fallout from this bug is that we would end up relocating the image but copying the image at some offset, resulting in what appeared to be memory corruption. Reported-by: Thomas Bächler <thomas@archlinux.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r--arch/x86/boot/compressed/eboot.c5
-rw-r--r--arch/x86/boot/compressed/head_32.S8
-rw-r--r--arch/x86/boot/compressed/head_64.S9
3 files changed, 8 insertions, 14 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 280165524ee4..91d17007323b 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params)
1016 * Because the x86 boot code expects to be passed a boot_params we 1016 * Because the x86 boot code expects to be passed a boot_params we
1017 * need to create one ourselves (usually the bootloader would create 1017 * need to create one ourselves (usually the bootloader would create
1018 * one for us). 1018 * one for us).
1019 *
1020 * The caller is responsible for filling out ->code32_start in the
1021 * returned boot_params.
1019 */ 1022 */
1020struct boot_params *make_boot_params(struct efi_config *c) 1023struct boot_params *make_boot_params(struct efi_config *c)
1021{ 1024{
@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
1081 hdr->vid_mode = 0xffff; 1084 hdr->vid_mode = 0xffff;
1082 hdr->boot_flag = 0xAA55; 1085 hdr->boot_flag = 0xAA55;
1083 1086
1084 hdr->code32_start = (__u64)(unsigned long)image->image_base;
1085
1086 hdr->type_of_loader = 0x21; 1087 hdr->type_of_loader = 0x21;
1087 1088
1088 /* Convert unicode cmdline to ascii */ 1089 /* Convert unicode cmdline to ascii */
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index de9d4200d305..cbed1407a5cd 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry)
59 call make_boot_params 59 call make_boot_params
60 cmpl $0, %eax 60 cmpl $0, %eax
61 je fail 61 je fail
62 movl %esi, BP_code32_start(%eax)
62 popl %ecx 63 popl %ecx
63 pushl %eax 64 pushl %eax
64 pushl %ecx 65 pushl %ecx
@@ -90,12 +91,7 @@ fail:
90 hlt 91 hlt
91 jmp fail 92 jmp fail
922: 932:
93 call 3f 94 movl BP_code32_start(%esi), %eax
943:
95 popl %eax
96 subl $3b, %eax
97 subl BP_pref_address(%esi), %eax
98 add BP_code32_start(%esi), %eax
99 leal preferred_addr(%eax), %eax 95 leal preferred_addr(%eax), %eax
100 jmp *%eax 96 jmp *%eax
101 97
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 57e58a5fa210..0d558ee899ae 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry)
261 cmpq $0,%rax 261 cmpq $0,%rax
262 je fail 262 je fail
263 mov %rax, %rsi 263 mov %rax, %rsi
264 leaq startup_32(%rip), %rax
265 movl %eax, BP_code32_start(%rsi)
264 jmp 2f /* Skip the relocation */ 266 jmp 2f /* Skip the relocation */
265 267
266handover_entry: 268handover_entry:
@@ -284,12 +286,7 @@ fail:
284 hlt 286 hlt
285 jmp fail 287 jmp fail
2862: 2882:
287 call 3f 289 movl BP_code32_start(%esi), %eax
2883:
289 popq %rax
290 subq $3b, %rax
291 subq BP_pref_address(%rsi), %rax
292 add BP_code32_start(%esi), %eax
293 leaq preferred_addr(%rax), %rax 290 leaq preferred_addr(%rax), %rax
294 jmp *%rax 291 jmp *%rax
295 292