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 | |
| 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
| -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 | ||||
| -rw-r--r-- | drivers/firmware/efi/Makefile | 2 |
7 files changed, 62 insertions, 48 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); | ||
