diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-27 17:23:13 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-09-27 17:23:13 -0400 |
commit | cd40fab6dbf4173c1617557be720dcec89657866 (patch) | |
tree | 7fa56728521ddff6fd2fd6eae6c88968459e61de /arch | |
parent | c6ff6486e5b306f76bf60b0dbfc63a6ed70d0a78 (diff) | |
parent | 29282ac0bd6c0b0c4c893fe2c31863e50fea69f8 (diff) |
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar:
"This has:
- EFI revert to fix a boot regression
- early_ioremap() fix for boot failure
- KASLR fix for possible boot failures
- EFI fix for corrupted string printing
- remove a misleading EFI bootup 'failed!' error message
Unfortunately it's all rather close to the merge window"
* 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
x86/efi: Truncate 64-bit values when calling 32-bit OutputString()
x86/efi: Delete misleading efi_printk() error message
Revert "efi/x86: efistub: Move shared dependencies to <asm/efi.h>"
x86/kaslr: Avoid the setup_data area when picking location
x86 early_ioremap: Increase FIX_BTMAPS_SLOTS to 8
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/boot/compressed/Makefile | 3 | ||||
-rw-r--r-- | arch/x86/boot/compressed/aslr.c | 15 | ||||
-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-- | arch/x86/include/asm/fixmap.h | 6 |
6 files changed, 61 insertions, 47 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/aslr.c b/arch/x86/boot/compressed/aslr.c index fc6091abedb7..d39189ba7f8e 100644 --- a/arch/x86/boot/compressed/aslr.c +++ b/arch/x86/boot/compressed/aslr.c | |||
@@ -183,12 +183,27 @@ static void mem_avoid_init(unsigned long input, unsigned long input_size, | |||
183 | static bool mem_avoid_overlap(struct mem_vector *img) | 183 | static bool mem_avoid_overlap(struct mem_vector *img) |
184 | { | 184 | { |
185 | int i; | 185 | int i; |
186 | struct setup_data *ptr; | ||
186 | 187 | ||
187 | for (i = 0; i < MEM_AVOID_MAX; i++) { | 188 | for (i = 0; i < MEM_AVOID_MAX; i++) { |
188 | if (mem_overlaps(img, &mem_avoid[i])) | 189 | if (mem_overlaps(img, &mem_avoid[i])) |
189 | return true; | 190 | return true; |
190 | } | 191 | } |
191 | 192 | ||
193 | /* Avoid all entries in the setup_data linked list. */ | ||
194 | ptr = (struct setup_data *)(unsigned long)real_mode->hdr.setup_data; | ||
195 | while (ptr) { | ||
196 | struct mem_vector avoid; | ||
197 | |||
198 | avoid.start = (u64)ptr; | ||
199 | avoid.size = sizeof(*ptr) + ptr->len; | ||
200 | |||
201 | if (mem_overlaps(img, &avoid)) | ||
202 | return true; | ||
203 | |||
204 | ptr = (struct setup_data *)(unsigned long)ptr->next; | ||
205 | } | ||
206 | |||
192 | return false; | 207 | return false; |
193 | } | 208 | } |
194 | 209 | ||
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/arch/x86/include/asm/fixmap.h b/arch/x86/include/asm/fixmap.h index b0910f97a3ea..ffb1733ac91f 100644 --- a/arch/x86/include/asm/fixmap.h +++ b/arch/x86/include/asm/fixmap.h | |||
@@ -106,14 +106,14 @@ enum fixed_addresses { | |||
106 | __end_of_permanent_fixed_addresses, | 106 | __end_of_permanent_fixed_addresses, |
107 | 107 | ||
108 | /* | 108 | /* |
109 | * 256 temporary boot-time mappings, used by early_ioremap(), | 109 | * 512 temporary boot-time mappings, used by early_ioremap(), |
110 | * before ioremap() is functional. | 110 | * before ioremap() is functional. |
111 | * | 111 | * |
112 | * If necessary we round it up to the next 256 pages boundary so | 112 | * If necessary we round it up to the next 512 pages boundary so |
113 | * that we can have a single pgd entry and a single pte table: | 113 | * that we can have a single pgd entry and a single pte table: |
114 | */ | 114 | */ |
115 | #define NR_FIX_BTMAPS 64 | 115 | #define NR_FIX_BTMAPS 64 |
116 | #define FIX_BTMAPS_SLOTS 4 | 116 | #define FIX_BTMAPS_SLOTS 8 |
117 | #define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) | 117 | #define TOTAL_FIX_BTMAPS (NR_FIX_BTMAPS * FIX_BTMAPS_SLOTS) |
118 | FIX_BTMAP_END = | 118 | FIX_BTMAP_END = |
119 | (__end_of_permanent_fixed_addresses ^ | 119 | (__end_of_permanent_fixed_addresses ^ |