aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/boot
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2014-09-05 09:52:26 -0400
committerMatt Fleming <matt.fleming@intel.com>2014-09-08 15:52:02 -0400
commit9cb0e394234d244fe5a97e743ec9dd7ddff7e64b (patch)
tree4828f610aab906bd7f4190ac32da0f777271480c /arch/x86/boot
parent47226ad4f4cfd1e91ded7f2ec42f83ff1c624663 (diff)
x86/efi: Fixup GOT in all boot code paths
Maarten reported that his Macbook pro 8.2 stopped booting after commit f23cf8bd5c1f49 ("efi/x86: efistub: Move shared dependencies to <asm/efi.h>"), the main feature of which is changing the visibility of symbol 'efi_early' from local to global. By making 'efi_early' global we end up requiring an entry in the Global Offset Table. Unfortunately, while we do include code to fixup GOT entries in the early boot code, it's only called after we've executed the EFI boot stub. What this amounts to is that references to 'efi_early' in the EFI boot stub don't point to the correct place. Since we've got multiple boot entry points we need to be prepared to fixup the GOT in multiple places, while ensuring that we never do it more than once, otherwise the GOT entries will still point to the wrong place. Reported-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Tested-by: Maarten Lankhorst <maarten.lankhorst@canonical.com> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Matt Fleming <matt.fleming@intel.com>
Diffstat (limited to 'arch/x86/boot')
-rw-r--r--arch/x86/boot/compressed/head_32.S54
-rw-r--r--arch/x86/boot/compressed/head_64.S56
2 files changed, 81 insertions, 29 deletions
diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S
index cbed1407a5cd..d6b8aa4c986c 100644
--- a/arch/x86/boot/compressed/head_32.S
+++ b/arch/x86/boot/compressed/head_32.S
@@ -30,6 +30,33 @@
30#include <asm/boot.h> 30#include <asm/boot.h>
31#include <asm/asm-offsets.h> 31#include <asm/asm-offsets.h>
32 32
33/*
34 * Adjust our own GOT
35 *
36 * The relocation base must be in %ebx
37 *
38 * It is safe to call this macro more than once, because in some of the
39 * code paths multiple invocations are inevitable, e.g. via the efi*
40 * entry points.
41 *
42 * Relocation is only performed the first time.
43 */
44.macro FIXUP_GOT
45 cmpb $1, got_fixed(%ebx)
46 je 2f
47
48 leal _got(%ebx), %edx
49 leal _egot(%ebx), %ecx
501:
51 cmpl %ecx, %edx
52 jae 2f
53 addl %ebx, (%edx)
54 addl $4, %edx
55 jmp 1b
562:
57 movb $1, got_fixed(%ebx)
58.endm
59
33 __HEAD 60 __HEAD
34ENTRY(startup_32) 61ENTRY(startup_32)
35#ifdef CONFIG_EFI_STUB 62#ifdef CONFIG_EFI_STUB
@@ -56,6 +83,9 @@ ENTRY(efi_pe_entry)
56 add %esi, 88(%eax) 83 add %esi, 88(%eax)
57 pushl %eax 84 pushl %eax
58 85
86 movl %esi, %ebx
87 FIXUP_GOT
88
59 call make_boot_params 89 call make_boot_params
60 cmpl $0, %eax 90 cmpl $0, %eax
61 je fail 91 je fail
@@ -81,6 +111,10 @@ ENTRY(efi32_stub_entry)
81 leal efi32_config(%esi), %eax 111 leal efi32_config(%esi), %eax
82 add %esi, 88(%eax) 112 add %esi, 88(%eax)
83 pushl %eax 113 pushl %eax
114
115 movl %esi, %ebx
116 FIXUP_GOT
117
842: 1182:
85 call efi_main 119 call efi_main
86 cmpl $0, %eax 120 cmpl $0, %eax
@@ -190,19 +224,7 @@ relocated:
190 shrl $2, %ecx 224 shrl $2, %ecx
191 rep stosl 225 rep stosl
192 226
193/* 227 FIXUP_GOT
194 * Adjust our own GOT
195 */
196 leal _got(%ebx), %edx
197 leal _egot(%ebx), %ecx
1981:
199 cmpl %ecx, %edx
200 jae 2f
201 addl %ebx, (%edx)
202 addl $4, %edx
203 jmp 1b
2042:
205
206/* 228/*
207 * Do the decompression, and jump to the new kernel.. 229 * Do the decompression, and jump to the new kernel..
208 */ 230 */
@@ -225,8 +247,12 @@ relocated:
225 xorl %ebx, %ebx 247 xorl %ebx, %ebx
226 jmp *%eax 248 jmp *%eax
227 249
228#ifdef CONFIG_EFI_STUB
229 .data 250 .data
251/* Have we relocated the GOT? */
252got_fixed:
253 .byte 0
254
255#ifdef CONFIG_EFI_STUB
230efi32_config: 256efi32_config:
231 .fill 11,8,0 257 .fill 11,8,0
232 .long efi_call_phys 258 .long efi_call_phys
diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S
index 2884e0c3e8a5..50f69c7eaaf4 100644
--- a/arch/x86/boot/compressed/head_64.S
+++ b/arch/x86/boot/compressed/head_64.S
@@ -32,6 +32,33 @@
32#include <asm/processor-flags.h> 32#include <asm/processor-flags.h>
33#include <asm/asm-offsets.h> 33#include <asm/asm-offsets.h>
34 34
35/*
36 * Adjust our own GOT
37 *
38 * The relocation base must be in %rbx
39 *
40 * It is safe to call this macro more than once, because in some of the
41 * code paths multiple invocations are inevitable, e.g. via the efi*
42 * entry points.
43 *
44 * Relocation is only performed the first time.
45 */
46.macro FIXUP_GOT
47 cmpb $1, got_fixed(%rip)
48 je 2f
49
50 leaq _got(%rip), %rdx
51 leaq _egot(%rip), %rcx
521:
53 cmpq %rcx, %rdx
54 jae 2f
55 addq %rbx, (%rdx)
56 addq $8, %rdx
57 jmp 1b
582:
59 movb $1, got_fixed(%rip)
60.endm
61
35 __HEAD 62 __HEAD
36 .code32 63 .code32
37ENTRY(startup_32) 64ENTRY(startup_32)
@@ -252,10 +279,13 @@ ENTRY(efi_pe_entry)
252 subq $1b, %rbp 279 subq $1b, %rbp
253 280
254 /* 281 /*
255 * Relocate efi_config->call(). 282 * Relocate efi_config->call() and the GOT entries.
256 */ 283 */
257 addq %rbp, efi64_config+88(%rip) 284 addq %rbp, efi64_config+88(%rip)
258 285
286 movq %rbp, %rbx
287 FIXUP_GOT
288
259 movq %rax, %rdi 289 movq %rax, %rdi
260 call make_boot_params 290 call make_boot_params
261 cmpq $0,%rax 291 cmpq $0,%rax
@@ -271,10 +301,13 @@ handover_entry:
271 subq $1b, %rbp 301 subq $1b, %rbp
272 302
273 /* 303 /*
274 * Relocate efi_config->call(). 304 * Relocate efi_config->call() and the GOT entries.
275 */ 305 */
276 movq efi_config(%rip), %rax 306 movq efi_config(%rip), %rax
277 addq %rbp, 88(%rax) 307 addq %rbp, 88(%rax)
308
309 movq %rbp, %rbx
310 FIXUP_GOT
2782: 3112:
279 movq efi_config(%rip), %rdi 312 movq efi_config(%rip), %rdi
280 call efi_main 313 call efi_main
@@ -385,19 +418,8 @@ relocated:
385 shrq $3, %rcx 418 shrq $3, %rcx
386 rep stosq 419 rep stosq
387 420
388/* 421 FIXUP_GOT
389 * Adjust our own GOT 422
390 */
391 leaq _got(%rip), %rdx
392 leaq _egot(%rip), %rcx
3931:
394 cmpq %rcx, %rdx
395 jae 2f
396 addq %rbx, (%rdx)
397 addq $8, %rdx
398 jmp 1b
3992:
400
401/* 423/*
402 * Do the decompression, and jump to the new kernel.. 424 * Do the decompression, and jump to the new kernel..
403 */ 425 */
@@ -437,6 +459,10 @@ gdt:
437 .quad 0x0000000000000000 /* TS continued */ 459 .quad 0x0000000000000000 /* TS continued */
438gdt_end: 460gdt_end:
439 461
462/* Have we relocated the GOT? */
463got_fixed:
464 .byte 0
465
440#ifdef CONFIG_EFI_STUB 466#ifdef CONFIG_EFI_STUB
441efi_config: 467efi_config:
442 .quad 0 468 .quad 0