summaryrefslogtreecommitdiff
path: root/arch/x86/boot/compressed/head_64.S
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-04-15 16:06:04 +0100
committerH. Peter Anvin <hpa@linux.intel.com>2012-04-16 11:41:44 -0700
commitb1994304fc399f5d3a5368c81111d713490c4799 (patch)
treefda4b1fa900378abddf71bc8d815543a49783fee /arch/x86/boot/compressed/head_64.S
parentd7de8649f34d45041409d1af4ba4a521971a9075 (diff)
x86, efi: Add dedicated EFI stub entry point
The method used to work out whether we were booted by EFI firmware or via a boot loader is broken. Because efi_main() is always executed when booting from a boot loader we will dereference invalid pointers either on the stack (CONFIG_X86_32) or contained in %rdx (CONFIG_X86_64) when searching for an EFI System Table signature. Instead of dereferencing these invalid system table pointers, add a new entry point that is only used when booting from EFI firmware, when we know the pointer arguments will be valid. With this change legacy boot loaders will no longer execute efi_main(), but will instead skip EFI stub initialisation completely. [ hpa: Marking this for urgent/stable since it is a regression when the option is enabled; without the option the patch has no effect ] Signed-off-by: Matt Fleming <matt.hfleming@intel.com> Link: http://lkml.kernel.org/r/1334584744.26997.14.camel@mfleming-mobl1.ger.corp.intel.com Reported-by: Jordan Justen <jordan.l.justen@intel.com> Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Cc: <stable@vger.kernel.org> v3.3
Diffstat (limited to 'arch/x86/boot/compressed/head_64.S')
-rw-r--r--arch/x86/boot/compressed/head_64.S22
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 558d76ce23bc..87e03a13d8e3 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -200,18 +200,28 @@ ENTRY(startup_64)
* entire text+data+bss and hopefully all of memory.
*/
#ifdef CONFIG_EFI_STUB
- pushq %rsi
+ /*
+ * The entry point for the PE/COFF executable is 0x210, so only
+ * legacy boot loaders will execute this jmp.
+ */
+ jmp preferred_addr
+
+ .org 0x210
mov %rcx, %rdi
mov %rdx, %rsi
call efi_main
- popq %rsi
- cmpq $0,%rax
- je preferred_addr
movq %rax,%rsi
- call 1f
+ cmpq $0,%rax
+ jne 2f
1:
+ /* EFI init failed, so hang. */
+ hlt
+ jmp 1b
+2:
+ call 3f
+3:
popq %rax
- subq $1b, %rax
+ subq $3b, %rax
subq BP_pref_address(%rsi), %rax
add BP_code32_start(%esi), %eax
leaq preferred_addr(%rax), %rax