diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-23 17:45:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-10-23 17:45:09 -0400 |
commit | 8c81f48e16fbe103e682d7ee7b2f16d065c42954 (patch) | |
tree | 1eac3abf36ed9330b3d5f9e550d1ccbc0c174f9b /arch/x86 | |
parent | 5de551e0eeddf470928e9fee59825a3645641bc7 (diff) | |
parent | 75b128573b275d5a5a7210b98c4b8cb3b39c12e7 (diff) |
Merge branch 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 EFI updates from Peter Anvin:
"This patchset falls under the "maintainers that grovel" clause in the
v3.18-rc1 announcement. We had intended to push it late in the merge
window since we got it into the -tip tree relatively late.
Many of these are relatively simple things, but there are a couple of
key bits, especially Ard's and Matt's patches"
* 'x86-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
rtc: Disable EFI rtc for x86
efi: rtc-efi: Export platform:rtc-efi as module alias
efi: Delete the in_nmi() conditional runtime locking
efi: Provide a non-blocking SetVariable() operation
x86/efi: Adding efi_printks on memory allocationa and pci.reads
x86/efi: Mark initialization code as such
x86/efi: Update comment regarding required phys mapped EFI services
x86/efi: Unexport add_efi_memmap variable
x86/efi: Remove unused efi_call* macros
efi: Resolve some shadow warnings
arm64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
ia64: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
x86: efi: Format EFI memory type & attrs with efi_md_typeattr_format()
efi: Introduce efi_md_typeattr_format()
efi: Add macro for EFI_MEMORY_UCE memory attribute
x86/efi: Clear EFI_RUNTIME_SERVICES if failing to enter virtual mode
arm64/efi: Do not enter virtual mode if booting with efi=noruntime or noefi
arm64/efi: uefi_init error handling fix
efi: Add kernel param efi=noruntime
lib: Add a generic cmdline parse function parse_option_str
...
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 32 | ||||
-rw-r--r-- | arch/x86/include/asm/efi.h | 31 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi-bgrt.c | 36 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 52 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_32.c | 12 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_64.c | 6 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi_stub_32.S | 4 |
7 files changed, 100 insertions, 73 deletions
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c index de8eebd6f67c..1acf605a646d 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c | |||
@@ -330,8 +330,10 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) | |||
330 | size = pci->romsize + sizeof(*rom); | 330 | size = pci->romsize + sizeof(*rom); |
331 | 331 | ||
332 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); | 332 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); |
333 | if (status != EFI_SUCCESS) | 333 | if (status != EFI_SUCCESS) { |
334 | efi_printk(sys_table, "Failed to alloc mem for rom\n"); | ||
334 | return status; | 335 | return status; |
336 | } | ||
335 | 337 | ||
336 | memset(rom, 0, sizeof(*rom)); | 338 | memset(rom, 0, sizeof(*rom)); |
337 | 339 | ||
@@ -344,14 +346,18 @@ __setup_efi_pci32(efi_pci_io_protocol_32 *pci, struct pci_setup_rom **__rom) | |||
344 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 346 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
345 | PCI_VENDOR_ID, 1, &(rom->vendor)); | 347 | PCI_VENDOR_ID, 1, &(rom->vendor)); |
346 | 348 | ||
347 | if (status != EFI_SUCCESS) | 349 | if (status != EFI_SUCCESS) { |
350 | efi_printk(sys_table, "Failed to read rom->vendor\n"); | ||
348 | goto free_struct; | 351 | goto free_struct; |
352 | } | ||
349 | 353 | ||
350 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 354 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
351 | PCI_DEVICE_ID, 1, &(rom->devid)); | 355 | PCI_DEVICE_ID, 1, &(rom->devid)); |
352 | 356 | ||
353 | if (status != EFI_SUCCESS) | 357 | if (status != EFI_SUCCESS) { |
358 | efi_printk(sys_table, "Failed to read rom->devid\n"); | ||
354 | goto free_struct; | 359 | goto free_struct; |
360 | } | ||
355 | 361 | ||
356 | status = efi_early->call(pci->get_location, pci, &(rom->segment), | 362 | status = efi_early->call(pci->get_location, pci, &(rom->segment), |
357 | &(rom->bus), &(rom->device), &(rom->function)); | 363 | &(rom->bus), &(rom->device), &(rom->function)); |
@@ -432,8 +438,10 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) | |||
432 | size = pci->romsize + sizeof(*rom); | 438 | size = pci->romsize + sizeof(*rom); |
433 | 439 | ||
434 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); | 440 | status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); |
435 | if (status != EFI_SUCCESS) | 441 | if (status != EFI_SUCCESS) { |
442 | efi_printk(sys_table, "Failed to alloc mem for rom\n"); | ||
436 | return status; | 443 | return status; |
444 | } | ||
437 | 445 | ||
438 | rom->data.type = SETUP_PCI; | 446 | rom->data.type = SETUP_PCI; |
439 | rom->data.len = size - sizeof(struct setup_data); | 447 | rom->data.len = size - sizeof(struct setup_data); |
@@ -444,14 +452,18 @@ __setup_efi_pci64(efi_pci_io_protocol_64 *pci, struct pci_setup_rom **__rom) | |||
444 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 452 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
445 | PCI_VENDOR_ID, 1, &(rom->vendor)); | 453 | PCI_VENDOR_ID, 1, &(rom->vendor)); |
446 | 454 | ||
447 | if (status != EFI_SUCCESS) | 455 | if (status != EFI_SUCCESS) { |
456 | efi_printk(sys_table, "Failed to read rom->vendor\n"); | ||
448 | goto free_struct; | 457 | goto free_struct; |
458 | } | ||
449 | 459 | ||
450 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, | 460 | status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, |
451 | PCI_DEVICE_ID, 1, &(rom->devid)); | 461 | PCI_DEVICE_ID, 1, &(rom->devid)); |
452 | 462 | ||
453 | if (status != EFI_SUCCESS) | 463 | if (status != EFI_SUCCESS) { |
464 | efi_printk(sys_table, "Failed to read rom->devid\n"); | ||
454 | goto free_struct; | 465 | goto free_struct; |
466 | } | ||
455 | 467 | ||
456 | status = efi_early->call(pci->get_location, pci, &(rom->segment), | 468 | status = efi_early->call(pci->get_location, pci, &(rom->segment), |
457 | &(rom->bus), &(rom->device), &(rom->function)); | 469 | &(rom->bus), &(rom->device), &(rom->function)); |
@@ -538,8 +550,10 @@ static void setup_efi_pci(struct boot_params *params) | |||
538 | EFI_LOADER_DATA, | 550 | EFI_LOADER_DATA, |
539 | size, (void **)&pci_handle); | 551 | size, (void **)&pci_handle); |
540 | 552 | ||
541 | if (status != EFI_SUCCESS) | 553 | if (status != EFI_SUCCESS) { |
554 | efi_printk(sys_table, "Failed to alloc mem for pci_handle\n"); | ||
542 | return; | 555 | return; |
556 | } | ||
543 | 557 | ||
544 | status = efi_call_early(locate_handle, | 558 | status = efi_call_early(locate_handle, |
545 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, | 559 | EFI_LOCATE_BY_PROTOCOL, &pci_proto, |
@@ -1105,6 +1119,10 @@ struct boot_params *make_boot_params(struct efi_config *c) | |||
1105 | 1119 | ||
1106 | memset(sdt, 0, sizeof(*sdt)); | 1120 | memset(sdt, 0, sizeof(*sdt)); |
1107 | 1121 | ||
1122 | status = efi_parse_options(cmdline_ptr); | ||
1123 | if (status != EFI_SUCCESS) | ||
1124 | goto fail2; | ||
1125 | |||
1108 | status = handle_cmdline_files(sys_table, image, | 1126 | status = handle_cmdline_files(sys_table, image, |
1109 | (char *)(unsigned long)hdr->cmd_line_ptr, | 1127 | (char *)(unsigned long)hdr->cmd_line_ptr, |
1110 | "initrd=", hdr->initrd_addr_max, | 1128 | "initrd=", hdr->initrd_addr_max, |
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h index 0ec241ede5a2..9b11757975d0 100644 --- a/arch/x86/include/asm/efi.h +++ b/arch/x86/include/asm/efi.h | |||
@@ -81,24 +81,23 @@ extern u64 asmlinkage efi_call(void *fp, ...); | |||
81 | */ | 81 | */ |
82 | #define __efi_call_virt(f, args...) efi_call_virt(f, args) | 82 | #define __efi_call_virt(f, args...) efi_call_virt(f, args) |
83 | 83 | ||
84 | extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, | 84 | extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, |
85 | u32 type, u64 attribute); | 85 | u32 type, u64 attribute); |
86 | 86 | ||
87 | #endif /* CONFIG_X86_32 */ | 87 | #endif /* CONFIG_X86_32 */ |
88 | 88 | ||
89 | extern int add_efi_memmap; | ||
90 | extern struct efi_scratch efi_scratch; | 89 | extern struct efi_scratch efi_scratch; |
91 | extern void efi_set_executable(efi_memory_desc_t *md, bool executable); | 90 | extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); |
92 | extern int efi_memblock_x86_reserve_range(void); | 91 | extern int __init efi_memblock_x86_reserve_range(void); |
93 | extern void efi_call_phys_prelog(void); | 92 | extern void __init efi_call_phys_prolog(void); |
94 | extern void efi_call_phys_epilog(void); | 93 | extern void __init efi_call_phys_epilog(void); |
95 | extern void efi_unmap_memmap(void); | 94 | extern void __init efi_unmap_memmap(void); |
96 | extern void efi_memory_uc(u64 addr, unsigned long size); | 95 | extern void __init efi_memory_uc(u64 addr, unsigned long size); |
97 | extern void __init efi_map_region(efi_memory_desc_t *md); | 96 | extern void __init efi_map_region(efi_memory_desc_t *md); |
98 | extern void __init efi_map_region_fixed(efi_memory_desc_t *md); | 97 | extern void __init efi_map_region_fixed(efi_memory_desc_t *md); |
99 | extern void efi_sync_low_kernel_mappings(void); | 98 | extern void efi_sync_low_kernel_mappings(void); |
100 | extern int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); | 99 | extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); |
101 | extern void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); | 100 | extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); |
102 | extern void __init old_map_region(efi_memory_desc_t *md); | 101 | extern void __init old_map_region(efi_memory_desc_t *md); |
103 | extern void __init runtime_code_page_mkexec(void); | 102 | extern void __init runtime_code_page_mkexec(void); |
104 | extern void __init efi_runtime_mkexec(void); | 103 | extern void __init efi_runtime_mkexec(void); |
@@ -162,16 +161,6 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( | |||
162 | extern bool efi_reboot_required(void); | 161 | extern bool efi_reboot_required(void); |
163 | 162 | ||
164 | #else | 163 | #else |
165 | /* | ||
166 | * IF EFI is not configured, have the EFI calls return -ENOSYS. | ||
167 | */ | ||
168 | #define efi_call0(_f) (-ENOSYS) | ||
169 | #define efi_call1(_f, _a1) (-ENOSYS) | ||
170 | #define efi_call2(_f, _a1, _a2) (-ENOSYS) | ||
171 | #define efi_call3(_f, _a1, _a2, _a3) (-ENOSYS) | ||
172 | #define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS) | ||
173 | #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS) | ||
174 | #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS) | ||
175 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} | 164 | static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} |
176 | static inline bool efi_reboot_required(void) | 165 | static inline bool efi_reboot_required(void) |
177 | { | 166 | { |
diff --git a/arch/x86/platform/efi/efi-bgrt.c b/arch/x86/platform/efi/efi-bgrt.c index f15103dff4b4..d143d216d52b 100644 --- a/arch/x86/platform/efi/efi-bgrt.c +++ b/arch/x86/platform/efi/efi-bgrt.c | |||
@@ -40,20 +40,40 @@ void __init efi_bgrt_init(void) | |||
40 | if (ACPI_FAILURE(status)) | 40 | if (ACPI_FAILURE(status)) |
41 | return; | 41 | return; |
42 | 42 | ||
43 | if (bgrt_tab->header.length < sizeof(*bgrt_tab)) | 43 | if (bgrt_tab->header.length < sizeof(*bgrt_tab)) { |
44 | pr_err("Ignoring BGRT: invalid length %u (expected %zu)\n", | ||
45 | bgrt_tab->header.length, sizeof(*bgrt_tab)); | ||
44 | return; | 46 | return; |
45 | if (bgrt_tab->version != 1 || bgrt_tab->status != 1) | 47 | } |
48 | if (bgrt_tab->version != 1) { | ||
49 | pr_err("Ignoring BGRT: invalid version %u (expected 1)\n", | ||
50 | bgrt_tab->version); | ||
51 | return; | ||
52 | } | ||
53 | if (bgrt_tab->status != 1) { | ||
54 | pr_err("Ignoring BGRT: invalid status %u (expected 1)\n", | ||
55 | bgrt_tab->status); | ||
56 | return; | ||
57 | } | ||
58 | if (bgrt_tab->image_type != 0) { | ||
59 | pr_err("Ignoring BGRT: invalid image type %u (expected 0)\n", | ||
60 | bgrt_tab->image_type); | ||
46 | return; | 61 | return; |
47 | if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address) | 62 | } |
63 | if (!bgrt_tab->image_address) { | ||
64 | pr_err("Ignoring BGRT: null image address\n"); | ||
48 | return; | 65 | return; |
66 | } | ||
49 | 67 | ||
50 | image = efi_lookup_mapped_addr(bgrt_tab->image_address); | 68 | image = efi_lookup_mapped_addr(bgrt_tab->image_address); |
51 | if (!image) { | 69 | if (!image) { |
52 | image = early_memremap(bgrt_tab->image_address, | 70 | image = early_memremap(bgrt_tab->image_address, |
53 | sizeof(bmp_header)); | 71 | sizeof(bmp_header)); |
54 | ioremapped = true; | 72 | ioremapped = true; |
55 | if (!image) | 73 | if (!image) { |
74 | pr_err("Ignoring BGRT: failed to map image header memory\n"); | ||
56 | return; | 75 | return; |
76 | } | ||
57 | } | 77 | } |
58 | 78 | ||
59 | memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); | 79 | memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); |
@@ -61,14 +81,18 @@ void __init efi_bgrt_init(void) | |||
61 | early_iounmap(image, sizeof(bmp_header)); | 81 | early_iounmap(image, sizeof(bmp_header)); |
62 | bgrt_image_size = bmp_header.size; | 82 | bgrt_image_size = bmp_header.size; |
63 | 83 | ||
64 | bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL); | 84 | bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); |
65 | if (!bgrt_image) | 85 | if (!bgrt_image) { |
86 | pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", | ||
87 | bgrt_image_size); | ||
66 | return; | 88 | return; |
89 | } | ||
67 | 90 | ||
68 | if (ioremapped) { | 91 | if (ioremapped) { |
69 | image = early_memremap(bgrt_tab->image_address, | 92 | image = early_memremap(bgrt_tab->image_address, |
70 | bmp_header.size); | 93 | bmp_header.size); |
71 | if (!image) { | 94 | if (!image) { |
95 | pr_err("Ignoring BGRT: failed to map image memory\n"); | ||
72 | kfree(bgrt_image); | 96 | kfree(bgrt_image); |
73 | bgrt_image = NULL; | 97 | bgrt_image = NULL; |
74 | return; | 98 | return; |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 850da94fef30..dbc8627a5cdf 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -70,17 +70,7 @@ static efi_config_table_type_t arch_tables[] __initdata = { | |||
70 | 70 | ||
71 | u64 efi_setup; /* efi setup_data physical address */ | 71 | u64 efi_setup; /* efi setup_data physical address */ |
72 | 72 | ||
73 | static bool disable_runtime __initdata = false; | 73 | static int add_efi_memmap __initdata; |
74 | static int __init setup_noefi(char *arg) | ||
75 | { | ||
76 | disable_runtime = true; | ||
77 | return 0; | ||
78 | } | ||
79 | early_param("noefi", setup_noefi); | ||
80 | |||
81 | int add_efi_memmap; | ||
82 | EXPORT_SYMBOL(add_efi_memmap); | ||
83 | |||
84 | static int __init setup_add_efi_memmap(char *arg) | 74 | static int __init setup_add_efi_memmap(char *arg) |
85 | { | 75 | { |
86 | add_efi_memmap = 1; | 76 | add_efi_memmap = 1; |
@@ -96,7 +86,7 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
96 | { | 86 | { |
97 | efi_status_t status; | 87 | efi_status_t status; |
98 | 88 | ||
99 | efi_call_phys_prelog(); | 89 | efi_call_phys_prolog(); |
100 | status = efi_call_phys(efi_phys.set_virtual_address_map, | 90 | status = efi_call_phys(efi_phys.set_virtual_address_map, |
101 | memory_map_size, descriptor_size, | 91 | memory_map_size, descriptor_size, |
102 | descriptor_version, virtual_map); | 92 | descriptor_version, virtual_map); |
@@ -210,9 +200,12 @@ static void __init print_efi_memmap(void) | |||
210 | for (p = memmap.map, i = 0; | 200 | for (p = memmap.map, i = 0; |
211 | p < memmap.map_end; | 201 | p < memmap.map_end; |
212 | p += memmap.desc_size, i++) { | 202 | p += memmap.desc_size, i++) { |
203 | char buf[64]; | ||
204 | |||
213 | md = p; | 205 | md = p; |
214 | pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n", | 206 | pr_info("mem%02u: %s range=[0x%016llx-0x%016llx) (%lluMB)\n", |
215 | i, md->type, md->attribute, md->phys_addr, | 207 | i, efi_md_typeattr_format(buf, sizeof(buf), md), |
208 | md->phys_addr, | ||
216 | md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), | 209 | md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), |
217 | (md->num_pages >> (20 - EFI_PAGE_SHIFT))); | 210 | (md->num_pages >> (20 - EFI_PAGE_SHIFT))); |
218 | } | 211 | } |
@@ -344,9 +337,9 @@ static int __init efi_runtime_init32(void) | |||
344 | } | 337 | } |
345 | 338 | ||
346 | /* | 339 | /* |
347 | * We will only need *early* access to the following two | 340 | * We will only need *early* access to the SetVirtualAddressMap |
348 | * EFI runtime services before set_virtual_address_map | 341 | * EFI runtime service. All other runtime services will be called |
349 | * is invoked. | 342 | * via the virtual mapping. |
350 | */ | 343 | */ |
351 | efi_phys.set_virtual_address_map = | 344 | efi_phys.set_virtual_address_map = |
352 | (efi_set_virtual_address_map_t *) | 345 | (efi_set_virtual_address_map_t *) |
@@ -368,9 +361,9 @@ static int __init efi_runtime_init64(void) | |||
368 | } | 361 | } |
369 | 362 | ||
370 | /* | 363 | /* |
371 | * We will only need *early* access to the following two | 364 | * We will only need *early* access to the SetVirtualAddressMap |
372 | * EFI runtime services before set_virtual_address_map | 365 | * EFI runtime service. All other runtime services will be called |
373 | * is invoked. | 366 | * via the virtual mapping. |
374 | */ | 367 | */ |
375 | efi_phys.set_virtual_address_map = | 368 | efi_phys.set_virtual_address_map = |
376 | (efi_set_virtual_address_map_t *) | 369 | (efi_set_virtual_address_map_t *) |
@@ -492,7 +485,7 @@ void __init efi_init(void) | |||
492 | if (!efi_runtime_supported()) | 485 | if (!efi_runtime_supported()) |
493 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); | 486 | pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); |
494 | else { | 487 | else { |
495 | if (disable_runtime || efi_runtime_init()) | 488 | if (efi_runtime_disabled() || efi_runtime_init()) |
496 | return; | 489 | return; |
497 | } | 490 | } |
498 | if (efi_memmap_init()) | 491 | if (efi_memmap_init()) |
@@ -537,7 +530,7 @@ void __init runtime_code_page_mkexec(void) | |||
537 | } | 530 | } |
538 | } | 531 | } |
539 | 532 | ||
540 | void efi_memory_uc(u64 addr, unsigned long size) | 533 | void __init efi_memory_uc(u64 addr, unsigned long size) |
541 | { | 534 | { |
542 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; | 535 | unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; |
543 | u64 npages; | 536 | u64 npages; |
@@ -732,6 +725,7 @@ static void __init kexec_enter_virtual_mode(void) | |||
732 | */ | 725 | */ |
733 | if (!efi_is_native()) { | 726 | if (!efi_is_native()) { |
734 | efi_unmap_memmap(); | 727 | efi_unmap_memmap(); |
728 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
735 | return; | 729 | return; |
736 | } | 730 | } |
737 | 731 | ||
@@ -805,6 +799,7 @@ static void __init __efi_enter_virtual_mode(void) | |||
805 | new_memmap = efi_map_regions(&count, &pg_shift); | 799 | new_memmap = efi_map_regions(&count, &pg_shift); |
806 | if (!new_memmap) { | 800 | if (!new_memmap) { |
807 | pr_err("Error reallocating memory, EFI runtime non-functional!\n"); | 801 | pr_err("Error reallocating memory, EFI runtime non-functional!\n"); |
802 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
808 | return; | 803 | return; |
809 | } | 804 | } |
810 | 805 | ||
@@ -812,8 +807,10 @@ static void __init __efi_enter_virtual_mode(void) | |||
812 | 807 | ||
813 | BUG_ON(!efi.systab); | 808 | BUG_ON(!efi.systab); |
814 | 809 | ||
815 | if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) | 810 | if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) { |
811 | clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); | ||
816 | return; | 812 | return; |
813 | } | ||
817 | 814 | ||
818 | efi_sync_low_kernel_mappings(); | 815 | efi_sync_low_kernel_mappings(); |
819 | efi_dump_pagetable(); | 816 | efi_dump_pagetable(); |
@@ -938,14 +935,11 @@ u64 efi_mem_attributes(unsigned long phys_addr) | |||
938 | return 0; | 935 | return 0; |
939 | } | 936 | } |
940 | 937 | ||
941 | static int __init parse_efi_cmdline(char *str) | 938 | static int __init arch_parse_efi_cmdline(char *str) |
942 | { | 939 | { |
943 | if (*str == '=') | 940 | if (parse_option_str(str, "old_map")) |
944 | str++; | ||
945 | |||
946 | if (!strncmp(str, "old_map", 7)) | ||
947 | set_bit(EFI_OLD_MEMMAP, &efi.flags); | 941 | set_bit(EFI_OLD_MEMMAP, &efi.flags); |
948 | 942 | ||
949 | return 0; | 943 | return 0; |
950 | } | 944 | } |
951 | early_param("efi", parse_efi_cmdline); | 945 | early_param("efi", arch_parse_efi_cmdline); |
diff --git a/arch/x86/platform/efi/efi_32.c b/arch/x86/platform/efi/efi_32.c index 9ee3491e31fb..40e7cda52936 100644 --- a/arch/x86/platform/efi/efi_32.c +++ b/arch/x86/platform/efi/efi_32.c | |||
@@ -33,7 +33,7 @@ | |||
33 | 33 | ||
34 | /* | 34 | /* |
35 | * To make EFI call EFI runtime service in physical addressing mode we need | 35 | * To make EFI call EFI runtime service in physical addressing mode we need |
36 | * prelog/epilog before/after the invocation to disable interrupt, to | 36 | * prolog/epilog before/after the invocation to disable interrupt, to |
37 | * claim EFI runtime service handler exclusively and to duplicate a memory in | 37 | * claim EFI runtime service handler exclusively and to duplicate a memory in |
38 | * low memory space say 0 - 3G. | 38 | * low memory space say 0 - 3G. |
39 | */ | 39 | */ |
@@ -41,11 +41,13 @@ static unsigned long efi_rt_eflags; | |||
41 | 41 | ||
42 | void efi_sync_low_kernel_mappings(void) {} | 42 | void efi_sync_low_kernel_mappings(void) {} |
43 | void __init efi_dump_pagetable(void) {} | 43 | void __init efi_dump_pagetable(void) {} |
44 | int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) | 44 | int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) |
45 | { | 45 | { |
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
48 | void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) {} | 48 | void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) |
49 | { | ||
50 | } | ||
49 | 51 | ||
50 | void __init efi_map_region(efi_memory_desc_t *md) | 52 | void __init efi_map_region(efi_memory_desc_t *md) |
51 | { | 53 | { |
@@ -55,7 +57,7 @@ void __init efi_map_region(efi_memory_desc_t *md) | |||
55 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} | 57 | void __init efi_map_region_fixed(efi_memory_desc_t *md) {} |
56 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} | 58 | void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} |
57 | 59 | ||
58 | void efi_call_phys_prelog(void) | 60 | void __init efi_call_phys_prolog(void) |
59 | { | 61 | { |
60 | struct desc_ptr gdt_descr; | 62 | struct desc_ptr gdt_descr; |
61 | 63 | ||
@@ -69,7 +71,7 @@ void efi_call_phys_prelog(void) | |||
69 | load_gdt(&gdt_descr); | 71 | load_gdt(&gdt_descr); |
70 | } | 72 | } |
71 | 73 | ||
72 | void efi_call_phys_epilog(void) | 74 | void __init efi_call_phys_epilog(void) |
73 | { | 75 | { |
74 | struct desc_ptr gdt_descr; | 76 | struct desc_ptr gdt_descr; |
75 | 77 | ||
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c index 290d397e1dd9..35aecb6042fb 100644 --- a/arch/x86/platform/efi/efi_64.c +++ b/arch/x86/platform/efi/efi_64.c | |||
@@ -79,7 +79,7 @@ static void __init early_code_mapping_set_exec(int executable) | |||
79 | } | 79 | } |
80 | } | 80 | } |
81 | 81 | ||
82 | void __init efi_call_phys_prelog(void) | 82 | void __init efi_call_phys_prolog(void) |
83 | { | 83 | { |
84 | unsigned long vaddress; | 84 | unsigned long vaddress; |
85 | int pgd; | 85 | int pgd; |
@@ -139,7 +139,7 @@ void efi_sync_low_kernel_mappings(void) | |||
139 | sizeof(pgd_t) * num_pgds); | 139 | sizeof(pgd_t) * num_pgds); |
140 | } | 140 | } |
141 | 141 | ||
142 | int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) | 142 | int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) |
143 | { | 143 | { |
144 | unsigned long text; | 144 | unsigned long text; |
145 | struct page *page; | 145 | struct page *page; |
@@ -192,7 +192,7 @@ int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) | |||
192 | return 0; | 192 | return 0; |
193 | } | 193 | } |
194 | 194 | ||
195 | void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) | 195 | void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) |
196 | { | 196 | { |
197 | pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); | 197 | pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); |
198 | 198 | ||
diff --git a/arch/x86/platform/efi/efi_stub_32.S b/arch/x86/platform/efi/efi_stub_32.S index fbe66e626c09..040192b50d02 100644 --- a/arch/x86/platform/efi/efi_stub_32.S +++ b/arch/x86/platform/efi/efi_stub_32.S | |||
@@ -27,13 +27,13 @@ ENTRY(efi_call_phys) | |||
27 | * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found | 27 | * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found |
28 | * the values of these registers are the same. And, the corresponding | 28 | * the values of these registers are the same. And, the corresponding |
29 | * GDT entries are identical. So I will do nothing about segment reg | 29 | * GDT entries are identical. So I will do nothing about segment reg |
30 | * and GDT, but change GDT base register in prelog and epilog. | 30 | * and GDT, but change GDT base register in prolog and epilog. |
31 | */ | 31 | */ |
32 | 32 | ||
33 | /* | 33 | /* |
34 | * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET. | 34 | * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET. |
35 | * But to make it smoothly switch from virtual mode to flat mode. | 35 | * But to make it smoothly switch from virtual mode to flat mode. |
36 | * The mapping of lower virtual memory has been created in prelog and | 36 | * The mapping of lower virtual memory has been created in prolog and |
37 | * epilog. | 37 | * epilog. |
38 | */ | 38 | */ |
39 | movl $1f, %edx | 39 | movl $1f, %edx |