x86/efi: Correct EFI boot stub use of code32_start
authorMatt Fleming <matt@console-pimps.org>
Tue, 8 Apr 2014 12:14:00 +0000 (13:14 +0100)
committerMatt Fleming <matt.fleming@intel.com>
Thu, 10 Apr 2014 20:19:52 +0000 (21:19 +0100)
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>
arch/x86/boot/compressed/eboot.c
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S

index 280165524ee44213386194f17ac5e81fcb0ace44..91d17007323b7c0fbc9d3bf6a0fc3aae6d62efdd 100644 (file)
@@ -1016,6 +1016,9 @@ void setup_graphics(struct boot_params *boot_params)
  * Because the x86 boot code expects to be passed a boot_params we
  * need to create one ourselves (usually the bootloader would create
  * one for us).
+ *
+ * The caller is responsible for filling out ->code32_start in the
+ * returned boot_params.
  */
 struct boot_params *make_boot_params(struct efi_config *c)
 {
@@ -1081,8 +1084,6 @@ struct boot_params *make_boot_params(struct efi_config *c)
        hdr->vid_mode = 0xffff;
        hdr->boot_flag = 0xAA55;
 
-       hdr->code32_start = (__u64)(unsigned long)image->image_base;
-
        hdr->type_of_loader = 0x21;
 
        /* Convert unicode cmdline to ascii */
index de9d4200d305ba86eb48bb60f3a852b210fb2649..cbed1407a5cdb7ead8fa0cae90d2e7902133aaa7 100644 (file)
@@ -59,6 +59,7 @@ ENTRY(efi_pe_entry)
        call    make_boot_params
        cmpl    $0, %eax
        je      fail
+       movl    %esi, BP_code32_start(%eax)
        popl    %ecx
        pushl   %eax
        pushl   %ecx
@@ -90,12 +91,7 @@ fail:
        hlt
        jmp     fail
 2:
-       call    3f
-3:
-       popl    %eax
-       subl    $3b, %eax
-       subl    BP_pref_address(%esi), %eax
-       add     BP_code32_start(%esi), %eax
+       movl    BP_code32_start(%esi), %eax
        leal    preferred_addr(%eax), %eax
        jmp     *%eax
 
index 57e58a5fa21073de1c86f4ceee6b76e674d87399..0d558ee899aec85cf3fce7f69691441691a41f93 100644 (file)
@@ -261,6 +261,8 @@ ENTRY(efi_pe_entry)
        cmpq    $0,%rax
        je      fail
        mov     %rax, %rsi
+       leaq    startup_32(%rip), %rax
+       movl    %eax, BP_code32_start(%rsi)
        jmp     2f              /* Skip the relocation */
 
 handover_entry:
@@ -284,12 +286,7 @@ fail:
        hlt
        jmp     fail
 2:
-       call    3f
-3:
-       popq    %rax
-       subq    $3b, %rax
-       subq    BP_pref_address(%rsi), %rax
-       add     BP_code32_start(%esi), %eax
+       movl    BP_code32_start(%esi), %eax
        leaq    preferred_addr(%rax), %rax
        jmp     *%rax