aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-09-27 17:23:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-09-27 17:23:13 -0400
commitcd40fab6dbf4173c1617557be720dcec89657866 (patch)
tree7fa56728521ddff6fd2fd6eae6c88968459e61de /arch
parentc6ff6486e5b306f76bf60b0dbfc63a6ed70d0a78 (diff)
parent29282ac0bd6c0b0c4c893fe2c31863e50fea69f8 (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/Makefile3
-rw-r--r--arch/x86/boot/compressed/aslr.c15
-rw-r--r--arch/x86/boot/compressed/eboot.c44
-rw-r--r--arch/x86/boot/compressed/eboot.h16
-rw-r--r--arch/x86/include/asm/efi.h24
-rw-r--r--arch/x86/include/asm/fixmap.h6
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
35ifeq ($(CONFIG_EFI_STUB), y) 35ifeq ($(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
38endif 37endif
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,
183static bool mem_avoid_overlap(struct mem_vector *img) 183static 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
20static efi_system_table_t *sys_table; 20static efi_system_table_t *sys_table;
21 21
22struct efi_config *efi_early; 22static 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) \
25static void setup_boot_services##bits(struct efi_config *c) \ 28static 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
283static void find_bits(unsigned long mask, u8 *pos, u8 *size) 290static 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
363static efi_status_t 370static void
364setup_efi_pci32(struct boot_params *params, void **pci_handle, 371setup_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
410static efi_status_t 415static efi_status_t
@@ -463,7 +468,7 @@ free_struct:
463 468
464} 469}
465 470
466static efi_status_t 471static void
467setup_efi_pci64(struct boot_params *params, void **pci_handle, 472setup_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
513static 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 */
525static 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
545free_handle: 557free_handle:
546 efi_call_early(free_pool, pci_handle); 558 efi_call_early(free_pool, pci_handle);
547 return status;
548} 559}
549 560
550static void 561static 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
106struct 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
165struct 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
181extern struct efi_config *efi_early;
182
183#define efi_call_early(f, ...) \
184 efi_early->call(efi_early->f, __VA_ARGS__);
185
186extern bool efi_reboot_required(void); 162extern 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 ^