diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-09-09 10:56:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-09-09 10:56:12 -0400 |
commit | 5ac385d83525fb8924ef87c18a4dc49998366394 (patch) | |
tree | 68748bd20b197309abeeea2698cd0ccffcd15717 /arch/x86 | |
parent | cc99535eb4049c730cac421d403d079593cb31ae (diff) | |
parent | 0ceac9e094b065fe3fec19669740f338d3480498 (diff) |
Merge tag 'efi-urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into x86/urgent
Pull EFI fixes from Matt Fleming:
* Fix early boot regression affecting x86 EFI boot stub when loading
initrds above 4GB - Yinghai Lu
* Relocate GOT entries in the x86 EFI boot stub now that we have
symbols with global visibility - Matt Fleming
* fdt memory reservation fix for arm64 - Mark Salter
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 18 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_32.S | 54 | ||||
-rw-r--r-- | arch/x86/boot/compressed/head_64.S | 56 |
3 files changed, 92 insertions, 36 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index f277184e2ac1..dca9842d8f91 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -1032,7 +1032,6 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1032 | int i; | 1032 | int i; |
1033 | unsigned long ramdisk_addr; | 1033 | unsigned long ramdisk_addr; |
1034 | unsigned long ramdisk_size; | 1034 | unsigned long ramdisk_size; |
1035 | unsigned long initrd_addr_max; | ||
1036 | 1035 | ||
1037 | efi_early = c; | 1036 | efi_early = c; |
1038 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; | 1037 | sys_table = (efi_system_table_t *)(unsigned long)efi_early->table; |
@@ -1095,15 +1094,20 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1095 | 1094 | ||
1096 | memset(sdt, 0, sizeof(*sdt)); | 1095 | memset(sdt, 0, sizeof(*sdt)); |
1097 | 1096 | ||
1098 | if (hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) | ||
1099 | initrd_addr_max = -1UL; | ||
1100 | else | ||
1101 | initrd_addr_max = hdr->initrd_addr_max; | ||
1102 | |||
1103 | status = handle_cmdline_files(sys_table, image, | 1097 | status = handle_cmdline_files(sys_table, image, |
1104 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1098 | (char *)(unsigned long)hdr->cmd_line_ptr, |
1105 | "initrd=", initrd_addr_max, | 1099 | "initrd=", hdr->initrd_addr_max, |
1106 | &ramdisk_addr, &ramdisk_size); | 1100 | &ramdisk_addr, &ramdisk_size); |
1101 | |||
1102 | if (status != EFI_SUCCESS && | ||
1103 | hdr->xloadflags & XLF_CAN_BE_LOADED_ABOVE_4G) { | ||
1104 | efi_printk(sys_table, "Trying to load files to higher address\n"); | ||
1105 | status = handle_cmdline_files(sys_table, image, | ||
1106 | (char *)(unsigned long)hdr->cmd_line_ptr, | ||
1107 | "initrd=", -1UL, | ||
1108 | &ramdisk_addr, &ramdisk_size); | ||
1109 | } | ||
1110 | |||
1107 | if (status != EFI_SUCCESS) | 1111 | if (status != EFI_SUCCESS) |
1108 | goto fail2; | 1112 | goto fail2; |
1109 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; | 1113 | hdr->ramdisk_image = ramdisk_addr & 0xffffffff; |
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 | ||
50 | 1: | ||
51 | cmpl %ecx, %edx | ||
52 | jae 2f | ||
53 | addl %ebx, (%edx) | ||
54 | addl $4, %edx | ||
55 | jmp 1b | ||
56 | 2: | ||
57 | movb $1, got_fixed(%ebx) | ||
58 | .endm | ||
59 | |||
33 | __HEAD | 60 | __HEAD |
34 | ENTRY(startup_32) | 61 | ENTRY(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 | |||
84 | 2: | 118 | 2: |
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 | ||
198 | 1: | ||
199 | cmpl %ecx, %edx | ||
200 | jae 2f | ||
201 | addl %ebx, (%edx) | ||
202 | addl $4, %edx | ||
203 | jmp 1b | ||
204 | 2: | ||
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? */ | ||
252 | got_fixed: | ||
253 | .byte 0 | ||
254 | |||
255 | #ifdef CONFIG_EFI_STUB | ||
230 | efi32_config: | 256 | efi32_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 | ||
52 | 1: | ||
53 | cmpq %rcx, %rdx | ||
54 | jae 2f | ||
55 | addq %rbx, (%rdx) | ||
56 | addq $8, %rdx | ||
57 | jmp 1b | ||
58 | 2: | ||
59 | movb $1, got_fixed(%rip) | ||
60 | .endm | ||
61 | |||
35 | __HEAD | 62 | __HEAD |
36 | .code32 | 63 | .code32 |
37 | ENTRY(startup_32) | 64 | ENTRY(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 | ||
278 | 2: | 311 | 2: |
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 | ||
393 | 1: | ||
394 | cmpq %rcx, %rdx | ||
395 | jae 2f | ||
396 | addq %rbx, (%rdx) | ||
397 | addq $8, %rdx | ||
398 | jmp 1b | ||
399 | 2: | ||
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 */ |
438 | gdt_end: | 460 | gdt_end: |
439 | 461 | ||
462 | /* Have we relocated the GOT? */ | ||
463 | got_fixed: | ||
464 | .byte 0 | ||
465 | |||
440 | #ifdef CONFIG_EFI_STUB | 466 | #ifdef CONFIG_EFI_STUB |
441 | efi_config: | 467 | efi_config: |
442 | .quad 0 | 468 | .quad 0 |