diff options
author | Matt Fleming <matt@console-pimps.org> | 2014-04-08 08:14:00 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-05-06 10:55:30 -0400 |
commit | 35d5134b7d5a55e269c953096224248b9f6f72c2 (patch) | |
tree | bf5c5b9e459bb6e71b5d2cc7277469fdd581a1cc /arch | |
parent | 9e2dcd00681f852c1cb1864f79e9992ea1b5981f (diff) |
x86/efi: Correct EFI boot stub use of code32_start
commit 7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 upstream.
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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 5 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 14 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 9 |
3 files changed, 14 insertions, 14 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index d606463aa6d6..1308beed7abe 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -865,6 +865,9 @@ fail: | |||
865 | * Because the x86 boot code expects to be passed a boot_params we | 865 | * Because the x86 boot code expects to be passed a boot_params we |
866 | * need to create one ourselves (usually the bootloader would create | 866 | * need to create one ourselves (usually the bootloader would create |
867 | * one for us). | 867 | * one for us). |
868 | * | ||
869 | * The caller is responsible for filling out ->code32_start in the | ||
870 | * returned boot_params. | ||
868 | */ | 871 | */ |
869 | struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) | 872 | struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) |
870 | { | 873 | { |
@@ -921,8 +924,6 @@ struct boot_params *make_boot_params(void *handle, efi_system_table_t *_table) | |||
921 | hdr->vid_mode = 0xffff; | 924 | hdr->vid_mode = 0xffff; |
922 | hdr->boot_flag = 0xAA55; | 925 | hdr->boot_flag = 0xAA55; |
923 | 926 | ||
924 | hdr->code32_start = (__u64)(unsigned long)image->image_base; | ||
925 | |||
926 | hdr->type_of_loader = 0x21; | 927 | hdr->type_of_loader = 0x21; |
927 | 928 | ||
928 | /* Convert unicode cmdline to ascii */ | 929 | /* Convert unicode cmdline to ascii */ |
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index 1e3184f6072f..abb988a54c69 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S | |||
@@ -50,6 +50,13 @@ ENTRY(efi_pe_entry) | |||
50 | pushl %eax | 50 | pushl %eax |
51 | pushl %esi | 51 | pushl %esi |
52 | pushl %ecx | 52 | pushl %ecx |
53 | |||
54 | call reloc | ||
55 | reloc: | ||
56 | popl %ecx | ||
57 | subl reloc, %ecx | ||
58 | movl %ecx, BP_code32_start(%eax) | ||
59 | |||
53 | sub $0x4, %esp | 60 | sub $0x4, %esp |
54 | 61 | ||
55 | ENTRY(efi_stub_entry) | 62 | ENTRY(efi_stub_entry) |
@@ -63,12 +70,7 @@ ENTRY(efi_stub_entry) | |||
63 | hlt | 70 | hlt |
64 | jmp 1b | 71 | jmp 1b |
65 | 2: | 72 | 2: |
66 | call 3f | 73 | movl BP_code32_start(%esi), %eax |
67 | 3: | ||
68 | popl %eax | ||
69 | subl $3b, %eax | ||
70 | subl BP_pref_address(%esi), %eax | ||
71 | add BP_code32_start(%esi), %eax | ||
72 | leal preferred_addr(%eax), %eax | 74 | leal preferred_addr(%eax), %eax |
73 | jmp *%eax | 75 | jmp *%eax |
74 | 76 | ||
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S index 16f24e6dad79..92059b8f3f7b 100644 --- a/arch/x86/boot/compressed/head_64.S +++ b/arch/x86/boot/compressed/head_64.S | |||
@@ -217,6 +217,8 @@ ENTRY(efi_pe_entry) | |||
217 | cmpq $0,%rax | 217 | cmpq $0,%rax |
218 | je 1f | 218 | je 1f |
219 | mov %rax, %rdx | 219 | mov %rax, %rdx |
220 | leaq startup_32(%rip), %rax | ||
221 | movl %eax, BP_code32_start(%rdx) | ||
220 | popq %rsi | 222 | popq %rsi |
221 | popq %rdi | 223 | popq %rdi |
222 | 224 | ||
@@ -230,12 +232,7 @@ ENTRY(efi_stub_entry) | |||
230 | hlt | 232 | hlt |
231 | jmp 1b | 233 | jmp 1b |
232 | 2: | 234 | 2: |
233 | call 3f | 235 | movl BP_code32_start(%esi), %eax |
234 | 3: | ||
235 | popq %rax | ||
236 | subq $3b, %rax | ||
237 | subq BP_pref_address(%rsi), %rax | ||
238 | add BP_code32_start(%esi), %eax | ||
239 | leaq preferred_addr(%rax), %rax | 236 | leaq preferred_addr(%rax), %rax |
240 | jmp *%rax | 237 | jmp *%rax |
241 | 238 | ||