diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-09-25 10:40:08 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-09-25 10:40:08 -0400 |
commit | 29282ac0bd6c0b0c4c893fe2c31863e50fea69f8 (patch) | |
tree | c04181603b27833abea62e9f396b5f5c26b4067c | |
parent | 0cacbfbeb5077b63d5d3cf6df88b14ac12ad584b (diff) | |
parent | 115c6628a59044958c205f8468a1b3ba3d539e61 (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:
* Revert the static library changes from the merge window since they're
causing issues for Macbooks and Fedora + Grub2 (Matt Fleming)
* Delete the misleading "setup_efi_pci() failed!" message which some
people are seeing when booting EFI (Matt Fleming)
* Fix printing strings from the 32-bit EFI boot stub by only passing
32-bit addresses to the firmware (Matt Fleming)
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 44 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.h | 16 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 24 | ||||
-rw-r--r-- | drivers/firmware/efi/Makefile | 2 |
5 files changed, 44 insertions, 45 deletions
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 7a801a310e37..0fcd9133790c 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile | |||
@@ -33,8 +33,7 @@ VMLINUX_OBJS = $(obj)/vmlinux.lds $(obj)/head_$(BITS).o $(obj)/misc.o \ | |||
33 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone | 33 | $(obj)/eboot.o: KBUILD_CFLAGS += -fshort-wchar -mno-red-zone |
34 | 34 | ||
35 | ifeq ($(CONFIG_EFI_STUB), y) | 35 | ifeq ($(CONFIG_EFI_STUB), y) |
36 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o \ | 36 | VMLINUX_OBJS += $(obj)/eboot.o $(obj)/efi_stub_$(BITS).o |
37 | $(objtree)/drivers/firmware/efi/libstub/lib.a | ||
38 | endif | 37 | endif |
39 | 38 | ||
40 | $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE | 39 | $(obj)/vmlinux: $(VMLINUX_OBJS) FORCE |
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index dca9842d8f91..de8eebd6f67c 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -19,7 +19,10 @@ | |||
19 | 19 | ||
20 | static efi_system_table_t *sys_table; | 20 | static efi_system_table_t *sys_table; |
21 | 21 | ||
22 | struct efi_config *efi_early; | 22 | static struct efi_config *efi_early; |
23 | |||
24 | #define efi_call_early(f, ...) \ | ||
25 | efi_early->call(efi_early->f, __VA_ARGS__); | ||
23 | 26 | ||
24 | #define BOOT_SERVICES(bits) \ | 27 | #define BOOT_SERVICES(bits) \ |
25 | static void setup_boot_services##bits(struct efi_config *c) \ | 28 | static void setup_boot_services##bits(struct efi_config *c) \ |
@@ -265,21 +268,25 @@ void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) | |||
265 | 268 | ||
266 | offset = offsetof(typeof(*out), output_string); | 269 | offset = offsetof(typeof(*out), output_string); |
267 | output_string = efi_early->text_output + offset; | 270 | output_string = efi_early->text_output + offset; |
271 | out = (typeof(out))(unsigned long)efi_early->text_output; | ||
268 | func = (u64 *)output_string; | 272 | func = (u64 *)output_string; |
269 | 273 | ||
270 | efi_early->call(*func, efi_early->text_output, str); | 274 | efi_early->call(*func, out, str); |
271 | } else { | 275 | } else { |
272 | struct efi_simple_text_output_protocol_32 *out; | 276 | struct efi_simple_text_output_protocol_32 *out; |
273 | u32 *func; | 277 | u32 *func; |
274 | 278 | ||
275 | offset = offsetof(typeof(*out), output_string); | 279 | offset = offsetof(typeof(*out), output_string); |
276 | output_string = efi_early->text_output + offset; | 280 | output_string = efi_early->text_output + offset; |
281 | out = (typeof(out))(unsigned long)efi_early->text_output; | ||
277 | func = (u32 *)output_string; | 282 | func = (u32 *)output_string; |
278 | 283 | ||
279 | efi_early->call(*func, efi_early->text_output, str); | 284 | efi_early->call(*func, out, str); |
280 | } | 285 | } |
281 | } | 286 | } |
282 | 287 | ||
288 | #include "../../../../drivers/firmware/efi/libstub/efi-stub-helper.c" | ||
289 | |||
283 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) | 290 | static void find_bits(unsigned long mask, u8 *pos, u8 *size) |
284 | { | 291 | { |
285 | u8 first, len; | 292 | u8 first, len; |
@@ -360,7 +367,7 @@ free_struct: | |||
360 | return status; | 367 | return status; |
361 | } | 368 | } |
362 | 369 | ||
363 | static efi_status_t | 370 | static void |
364 | setup_efi_pci32(struct boot_params *params, void **pci_handle, | 371 | setup_efi_pci32(struct boot_params *params, void **pci_handle, |
365 | unsigned long size) | 372 | unsigned long size) |
366 | { | 373 | { |
@@ -403,8 +410,6 @@ setup_efi_pci32(struct boot_params *params, void **pci_handle, | |||
403 | data = (struct setup_data *)rom; | 410 | data = (struct setup_data *)rom; |
404 | 411 | ||
405 | } | 412 | } |
406 | |||
407 | return status; | ||
408 | } | 413 | } |
409 | 414 | ||
410 | static efi_status_t | 415 | static efi_status_t |
@@ -463,7 +468,7 @@ free_struct: | |||
463 | 468 | ||
464 | } | 469 | } |
465 | 470 | ||
466 | static efi_status_t | 471 | static void |
467 | setup_efi_pci64(struct boot_params *params, void **pci_handle, | 472 | setup_efi_pci64(struct boot_params *params, void **pci_handle, |
468 | unsigned long size) | 473 | unsigned long size) |
469 | { | 474 | { |
@@ -506,11 +511,18 @@ setup_efi_pci64(struct boot_params *params, void **pci_handle, | |||
506 | data = (struct setup_data *)rom; | 511 | data = (struct setup_data *)rom; |
507 | 512 | ||
508 | } | 513 | } |
509 | |||
510 | return status; | ||
511 | } | 514 | } |
512 | 515 | ||
513 | static efi_status_t setup_efi_pci(struct boot_params *params) | 516 | /* |
517 | * There's no way to return an informative status from this function, | ||
518 | * because any analysis (and printing of error messages) needs to be | ||
519 | * done directly at the EFI function call-site. | ||
520 | * | ||
521 | * For example, EFI_INVALID_PARAMETER could indicate a bug or maybe we | ||
522 | * just didn't find any PCI devices, but there's no way to tell outside | ||
523 | * the context of the call. | ||
524 | */ | ||
525 | static void setup_efi_pci(struct boot_params *params) | ||
514 | { | 526 | { |
515 | efi_status_t status; | 527 | efi_status_t status; |
516 | void **pci_handle = NULL; | 528 | void **pci_handle = NULL; |
@@ -527,7 +539,7 @@ static efi_status_t setup_efi_pci(struct boot_params *params) | |||
527 | size, (void **)&pci_handle); | 539 | size, (void **)&pci_handle); |
528 | 540 | ||
529 | if (status != EFI_SUCCESS) | 541 | if (status != EFI_SUCCESS) |
530 | return status; | 542 | return; |
531 | 543 | ||
532 | status = efi_call_early(locate_handle, | 544 | status = efi_call_early(locate_handle, |
533 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | 545 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, |
@@ -538,13 +550,12 @@ static efi_status_t setup_efi_pci(struct boot_params *params) | |||
538 | goto free_handle; | 550 | goto free_handle; |
539 | 551 | ||
540 | if (efi_early->is64) | 552 | if (efi_early->is64) |
541 | status = setup_efi_pci64(params, pci_handle, size); | 553 | setup_efi_pci64(params, pci_handle, size); |
542 | else | 554 | else |
543 | status = setup_efi_pci32(params, pci_handle, size); | 555 | setup_efi_pci32(params, pci_handle, size); |
544 | 556 | ||
545 | free_handle: | 557 | free_handle: |
546 | efi_call_early(free_pool, pci_handle); | 558 | efi_call_early(free_pool, pci_handle); |
547 | return status; | ||
548 | } | 559 | } |
549 | 560 | ||
550 | static void | 561 | static void |
@@ -1380,10 +1391,7 @@ struct boot_params *efi_main(struct efi_config *c, | |||
1380 | 1391 | ||
1381 | setup_graphics(boot_params); | 1392 | setup_graphics(boot_params); |
1382 | 1393 | ||
1383 | status = setup_efi_pci(boot_params); | 1394 | setup_efi_pci(boot_params); |
1384 | if (status != EFI_SUCCESS) { | ||
1385 | efi_printk(sys_table, "setup_efi_pci() failed!\n"); | ||
1386 | } | ||
1387 | 1395 | ||
1388 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, | 1396 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, |
1389 | sizeof(*gdt), (void **)&gdt); | 1397 | sizeof(*gdt), (void **)&gdt); |
diff --git a/arch/x86/boot/compressed/eboot.h b/arch/x86/boot/compressed/eboot.h index d487e727f1ec..c88c31ecad12 100644 --- a/arch/x86/boot/compressed/eboot.h +++ b/arch/x86/boot/compressed/eboot.h | |||
@@ -103,4 +103,20 @@ struct efi_uga_draw_protocol { | |||
103 | void *blt; | 103 | void *blt; |
104 | }; | 104 | }; |
105 | 105 | ||
106 | struct efi_config { | ||
107 | u64 image_handle; | ||
108 | u64 table; | ||
109 | u64 allocate_pool; | ||
110 | u64 allocate_pages; | ||
111 | u64 get_memory_map; | ||
112 | u64 free_pool; | ||
113 | u64 free_pages; | ||
114 | u64 locate_handle; | ||
115 | u64 handle_protocol; | ||
116 | u64 exit_boot_services; | ||
117 | u64 text_output; | ||
118 | efi_status_t (*call)(unsigned long, ...); | ||
119 | bool is64; | ||
120 | } __packed; | ||
121 | |||
106 | #endif /* BOOT_COMPRESSED_EBOOT_H */ | 122 | #endif /* BOOT_COMPRESSED_EBOOT_H */ |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 044a2fd3c5fe..0ec241ede5a2 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -159,30 +159,6 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( | |||
159 | } | 159 | } |
160 | #endif /* CONFIG_EFI_MIXED */ | 160 | #endif /* CONFIG_EFI_MIXED */ |
161 | 161 | ||
162 | |||
163 | /* arch specific definitions used by the stub code */ | ||
164 | |||
165 | struct efi_config { | ||
166 | u64 image_handle; | ||
167 | u64 table; | ||
168 | u64 allocate_pool; | ||
169 | u64 allocate_pages; | ||
170 | u64 get_memory_map; | ||
171 | u64 free_pool; | ||
172 | u64 free_pages; | ||
173 | u64 locate_handle; | ||
174 | u64 handle_protocol; | ||
175 | u64 exit_boot_services; | ||
176 | u64 text_output; | ||
177 | efi_status_t (*call)(unsigned long, ...); | ||
178 | bool is64; | ||
179 | } __packed; | ||
180 | |||
181 | extern struct efi_config *efi_early; | ||
182 | |||
183 | #define efi_call_early(f, ...) \ | ||
184 | efi_early->call(efi_early->f, __VA_ARGS__); | ||
185 | |||
186 | extern bool efi_reboot_required(void); | 162 | extern bool efi_reboot_required(void); |
187 | 163 | ||
188 | #else | 164 | #else |
diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile index d8be608a9f3b..aef6a95adef5 100644 --- a/drivers/firmware/efi/Makefile +++ b/drivers/firmware/efi/Makefile | |||
@@ -7,4 +7,4 @@ obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o | |||
7 | obj-$(CONFIG_UEFI_CPER) += cper.o | 7 | obj-$(CONFIG_UEFI_CPER) += cper.o |
8 | obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o | 8 | obj-$(CONFIG_EFI_RUNTIME_MAP) += runtime-map.o |
9 | obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o | 9 | obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o |
10 | obj-$(CONFIG_EFI_STUB) += libstub/ | 10 | obj-$(CONFIG_EFI_ARM_STUB) += libstub/ |