diff options
author | Matt Fleming <matt.fleming@intel.com> | 2012-04-15 19:06:04 +0400 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2012-04-16 22:41:44 +0400 |
commit | b1994304fc399f5d3a5368c81111d713490c4799 (patch) | |
tree | fda4b1fa900378abddf71bc8d815543a49783fee /arch/x86/boot/compressed/head_32.S | |
parent | d7de8649f34d45041409d1af4ba4a521971a9075 (diff) | |
download | linux-b1994304fc399f5d3a5368c81111d713490c4799.tar.xz |
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_32.S')
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S index a0559930a180..c85e3ac99bba 100644 --- a/arch/x86/boot/compressed/head_32.S +++ b/arch/x86/boot/compressed/head_32.S @@ -33,6 +33,9 @@ __HEAD ENTRY(startup_32) #ifdef CONFIG_EFI_STUB + jmp preferred_addr + + .balign 0x10 /* * We don't need the return address, so set up the stack so * efi_main() can find its arugments. @@ -41,12 +44,17 @@ ENTRY(startup_32) call efi_main cmpl $0, %eax - je preferred_addr movl %eax, %esi - call 1f + jne 2f 1: + /* EFI init failed, so hang. */ + hlt + jmp 1b +2: + call 3f +3: popl %eax - subl $1b, %eax + subl $3b, %eax subl BP_pref_address(%esi), %eax add BP_code32_start(%esi), %eax leal preferred_addr(%eax), %eax |