105 lines
3.1 KiB
Diff
105 lines
3.1 KiB
Diff
From 7e8213c1f3acc064aef37813a39f13cbfe7c3ce7 Mon Sep 17 00:00:00 2001
|
|
From: Matt Fleming <matt@console-pimps.org>
|
|
Date: Tue, 8 Apr 2014 13:14:00 +0100
|
|
Subject: [PATCH 2/3] x86/efi: Correct EFI boot stub use of code32_start
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
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 | 5 +++--
|
|
arch/x86/boot/compressed/head_32.S | 8 ++------
|
|
arch/x86/boot/compressed/head_64.S | 9 +++------
|
|
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)
|
|
* 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 */
|
|
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)
|
|
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
|
|
|
|
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)
|
|
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
|
|
|
|
--
|
|
1.9.0
|
|
|