aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-10-23 17:45:09 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-10-23 17:45:09 -0400
commit8c81f48e16fbe103e682d7ee7b2f16d065c42954 (patch)
tree1eac3abf36ed9330b3d5f9e550d1ccbc0c174f9b
parent5de551e0eeddf470928e9fee59825a3645641bc7 (diff)
parent75b128573b275d5a5a7210b98c4b8cb3b39c12e7 (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 ...
-rw-r--r--Documentation/kernel-parameters.txt8
-rw-r--r--arch/arm64/kernel/efi.c44
-rw-r--r--arch/ia64/kernel/efi.c6
-rw-r--r--arch/x86/boot/compressed/eboot.c32
-rw-r--r--arch/x86/include/asm/efi.h31
-rw-r--r--arch/x86/platform/efi/efi-bgrt.c36
-rw-r--r--arch/x86/platform/efi/efi.c52
-rw-r--r--arch/x86/platform/efi/efi_32.c12
-rw-r--r--arch/x86/platform/efi/efi_64.c6
-rw-r--r--arch/x86/platform/efi/efi_stub_32.S4
-rw-r--r--drivers/firmware/efi/efi.c79
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c4
-rw-r--r--drivers/firmware/efi/libstub/efi-stub-helper.c62
-rw-r--r--drivers/firmware/efi/runtime-wrappers.c164
-rw-r--r--drivers/firmware/efi/vars.c61
-rw-r--r--drivers/rtc/Kconfig2
-rw-r--r--drivers/rtc/rtc-efi.c1
-rw-r--r--include/linux/efi.h17
-rw-r--r--include/linux/kernel.h1
-rw-r--r--lib/cmdline.c29
20 files changed, 528 insertions, 123 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 988160a4ad31..74339c57b914 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1015,10 +1015,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
1015 Format: {"off" | "on" | "skip[mbr]"} 1015 Format: {"off" | "on" | "skip[mbr]"}
1016 1016
1017 efi= [EFI] 1017 efi= [EFI]
1018 Format: { "old_map" } 1018 Format: { "old_map", "nochunk", "noruntime" }
1019 old_map [X86-64]: switch to the old ioremap-based EFI 1019 old_map [X86-64]: switch to the old ioremap-based EFI
1020 runtime services mapping. 32-bit still uses this one by 1020 runtime services mapping. 32-bit still uses this one by
1021 default. 1021 default.
1022 nochunk: disable reading files in "chunks" in the EFI
1023 boot stub, as chunking can cause problems with some
1024 firmware implementations.
1025 noruntime : disable EFI runtime services support
1022 1026
1023 efi_no_storage_paranoia [EFI; X86] 1027 efi_no_storage_paranoia [EFI; X86]
1024 Using this parameter you can use more than 50% of 1028 Using this parameter you can use more than 50% of
@@ -2232,7 +2236,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
2232 2236
2233 nodsp [SH] Disable hardware DSP at boot time. 2237 nodsp [SH] Disable hardware DSP at boot time.
2234 2238
2235 noefi [X86] Disable EFI runtime services support. 2239 noefi Disable EFI runtime services support.
2236 2240
2237 noexec [IA-64] 2241 noexec [IA-64]
2238 2242
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index 03aaa99e1ea0..95c49ebc660d 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -89,7 +89,8 @@ static int __init uefi_init(void)
89 */ 89 */
90 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { 90 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) {
91 pr_err("System table signature incorrect\n"); 91 pr_err("System table signature incorrect\n");
92 return -EINVAL; 92 retval = -EINVAL;
93 goto out;
93 } 94 }
94 if ((efi.systab->hdr.revision >> 16) < 2) 95 if ((efi.systab->hdr.revision >> 16) < 2)
95 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n", 96 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n",
@@ -103,6 +104,7 @@ static int __init uefi_init(void)
103 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) 104 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i)
104 vendor[i] = c16[i]; 105 vendor[i] = c16[i];
105 vendor[i] = '\0'; 106 vendor[i] = '\0';
107 early_memunmap(c16, sizeof(vendor));
106 } 108 }
107 109
108 pr_info("EFI v%u.%.02u by %s\n", 110 pr_info("EFI v%u.%.02u by %s\n",
@@ -113,29 +115,11 @@ static int __init uefi_init(void)
113 if (retval == 0) 115 if (retval == 0)
114 set_bit(EFI_CONFIG_TABLES, &efi.flags); 116 set_bit(EFI_CONFIG_TABLES, &efi.flags);
115 117
116 early_memunmap(c16, sizeof(vendor)); 118out:
117 early_memunmap(efi.systab, sizeof(efi_system_table_t)); 119 early_memunmap(efi.systab, sizeof(efi_system_table_t));
118
119 return retval; 120 return retval;
120} 121}
121 122
122static __initdata char memory_type_name[][32] = {
123 {"Reserved"},
124 {"Loader Code"},
125 {"Loader Data"},
126 {"Boot Code"},
127 {"Boot Data"},
128 {"Runtime Code"},
129 {"Runtime Data"},
130 {"Conventional Memory"},
131 {"Unusable Memory"},
132 {"ACPI Reclaim Memory"},
133 {"ACPI Memory NVS"},
134 {"Memory Mapped I/O"},
135 {"MMIO Port Space"},
136 {"PAL Code"},
137};
138
139/* 123/*
140 * Return true for RAM regions we want to permanently reserve. 124 * Return true for RAM regions we want to permanently reserve.
141 */ 125 */
@@ -166,10 +150,13 @@ static __init void reserve_regions(void)
166 paddr = md->phys_addr; 150 paddr = md->phys_addr;
167 npages = md->num_pages; 151 npages = md->num_pages;
168 152
169 if (uefi_debug) 153 if (uefi_debug) {
170 pr_info(" 0x%012llx-0x%012llx [%s]", 154 char buf[64];
155
156 pr_info(" 0x%012llx-0x%012llx %s",
171 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1, 157 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1,
172 memory_type_name[md->type]); 158 efi_md_typeattr_format(buf, sizeof(buf), md));
159 }
173 160
174 memrange_efi_to_native(&paddr, &npages); 161 memrange_efi_to_native(&paddr, &npages);
175 size = npages << PAGE_SHIFT; 162 size = npages << PAGE_SHIFT;
@@ -393,11 +380,16 @@ static int __init arm64_enter_virtual_mode(void)
393 return -1; 380 return -1;
394 } 381 }
395 382
396 pr_info("Remapping and enabling EFI services.\n");
397
398 /* replace early memmap mapping with permanent mapping */
399 mapsize = memmap.map_end - memmap.map; 383 mapsize = memmap.map_end - memmap.map;
400 early_memunmap(memmap.map, mapsize); 384 early_memunmap(memmap.map, mapsize);
385
386 if (efi_runtime_disabled()) {
387 pr_info("EFI runtime services will be disabled.\n");
388 return -1;
389 }
390
391 pr_info("Remapping and enabling EFI services.\n");
392 /* replace early memmap mapping with permanent mapping */
401 memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map, 393 memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map,
402 mapsize); 394 mapsize);
403 memmap.map_end = memmap.map + mapsize; 395 memmap.map_end = memmap.map + mapsize;
diff --git a/arch/ia64/kernel/efi.c b/arch/ia64/kernel/efi.c
index 741b99c1a0b1..c52d7540dc05 100644
--- a/arch/ia64/kernel/efi.c
+++ b/arch/ia64/kernel/efi.c
@@ -568,6 +568,7 @@ efi_init (void)
568 { 568 {
569 const char *unit; 569 const char *unit;
570 unsigned long size; 570 unsigned long size;
571 char buf[64];
571 572
572 md = p; 573 md = p;
573 size = md->num_pages << EFI_PAGE_SHIFT; 574 size = md->num_pages << EFI_PAGE_SHIFT;
@@ -586,9 +587,10 @@ efi_init (void)
586 unit = "KB"; 587 unit = "KB";
587 } 588 }
588 589
589 printk("mem%02d: type=%2u, attr=0x%016lx, " 590 printk("mem%02d: %s "
590 "range=[0x%016lx-0x%016lx) (%4lu%s)\n", 591 "range=[0x%016lx-0x%016lx) (%4lu%s)\n",
591 i, md->type, md->attribute, md->phys_addr, 592 i, efi_md_typeattr_format(buf, sizeof(buf), md),
593 md->phys_addr,
592 md->phys_addr + efi_md_size(md), size, unit); 594 md->phys_addr + efi_md_size(md), size, unit);
593 } 595 }
594 } 596 }
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
84extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size, 84extern 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
89extern int add_efi_memmap;
90extern struct efi_scratch efi_scratch; 89extern struct efi_scratch efi_scratch;
91extern void efi_set_executable(efi_memory_desc_t *md, bool executable); 90extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable);
92extern int efi_memblock_x86_reserve_range(void); 91extern int __init efi_memblock_x86_reserve_range(void);
93extern void efi_call_phys_prelog(void); 92extern void __init efi_call_phys_prolog(void);
94extern void efi_call_phys_epilog(void); 93extern void __init efi_call_phys_epilog(void);
95extern void efi_unmap_memmap(void); 94extern void __init efi_unmap_memmap(void);
96extern void efi_memory_uc(u64 addr, unsigned long size); 95extern void __init efi_memory_uc(u64 addr, unsigned long size);
97extern void __init efi_map_region(efi_memory_desc_t *md); 96extern void __init efi_map_region(efi_memory_desc_t *md);
98extern void __init efi_map_region_fixed(efi_memory_desc_t *md); 97extern void __init efi_map_region_fixed(efi_memory_desc_t *md);
99extern void efi_sync_low_kernel_mappings(void); 98extern void efi_sync_low_kernel_mappings(void);
100extern int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages); 99extern int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages);
101extern void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages); 100extern void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages);
102extern void __init old_map_region(efi_memory_desc_t *md); 101extern void __init old_map_region(efi_memory_desc_t *md);
103extern void __init runtime_code_page_mkexec(void); 102extern void __init runtime_code_page_mkexec(void);
104extern void __init efi_runtime_mkexec(void); 103extern void __init efi_runtime_mkexec(void);
@@ -162,16 +161,6 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(
162extern bool efi_reboot_required(void); 161extern 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)
175static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} 164static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {}
176static inline bool efi_reboot_required(void) 165static 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
71u64 efi_setup; /* efi setup_data physical address */ 71u64 efi_setup; /* efi setup_data physical address */
72 72
73static bool disable_runtime __initdata = false; 73static int add_efi_memmap __initdata;
74static int __init setup_noefi(char *arg)
75{
76 disable_runtime = true;
77 return 0;
78}
79early_param("noefi", setup_noefi);
80
81int add_efi_memmap;
82EXPORT_SYMBOL(add_efi_memmap);
83
84static int __init setup_add_efi_memmap(char *arg) 74static 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
540void efi_memory_uc(u64 addr, unsigned long size) 533void __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
941static int __init parse_efi_cmdline(char *str) 938static 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}
951early_param("efi", parse_efi_cmdline); 945early_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
42void efi_sync_low_kernel_mappings(void) {} 42void efi_sync_low_kernel_mappings(void) {}
43void __init efi_dump_pagetable(void) {} 43void __init efi_dump_pagetable(void) {}
44int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) 44int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
45{ 45{
46 return 0; 46 return 0;
47} 47}
48void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) {} 48void __init efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages)
49{
50}
49 51
50void __init efi_map_region(efi_memory_desc_t *md) 52void __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)
55void __init efi_map_region_fixed(efi_memory_desc_t *md) {} 57void __init efi_map_region_fixed(efi_memory_desc_t *md) {}
56void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} 58void __init parse_efi_setup(u64 phys_addr, u32 data_len) {}
57 59
58void efi_call_phys_prelog(void) 60void __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
72void efi_call_phys_epilog(void) 74void __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
82void __init efi_call_phys_prelog(void) 82void __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
142int efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages) 142int __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
195void efi_cleanup_page_tables(unsigned long pa_memmap, unsigned num_pages) 195void __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
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 64ecbb501c50..8590099ac148 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -41,6 +41,28 @@ struct efi __read_mostly efi = {
41}; 41};
42EXPORT_SYMBOL(efi); 42EXPORT_SYMBOL(efi);
43 43
44static bool disable_runtime;
45static int __init setup_noefi(char *arg)
46{
47 disable_runtime = true;
48 return 0;
49}
50early_param("noefi", setup_noefi);
51
52bool efi_runtime_disabled(void)
53{
54 return disable_runtime;
55}
56
57static int __init parse_efi_cmdline(char *str)
58{
59 if (parse_option_str(str, "noruntime"))
60 disable_runtime = true;
61
62 return 0;
63}
64early_param("efi", parse_efi_cmdline);
65
44static struct kobject *efi_kobj; 66static struct kobject *efi_kobj;
45static struct kobject *efivars_kobj; 67static struct kobject *efivars_kobj;
46 68
@@ -423,3 +445,60 @@ int __init efi_get_fdt_params(struct efi_fdt_params *params, int verbose)
423 return ret; 445 return ret;
424} 446}
425#endif /* CONFIG_EFI_PARAMS_FROM_FDT */ 447#endif /* CONFIG_EFI_PARAMS_FROM_FDT */
448
449static __initdata char memory_type_name[][20] = {
450 "Reserved",
451 "Loader Code",
452 "Loader Data",
453 "Boot Code",
454 "Boot Data",
455 "Runtime Code",
456 "Runtime Data",
457 "Conventional Memory",
458 "Unusable Memory",
459 "ACPI Reclaim Memory",
460 "ACPI Memory NVS",
461 "Memory Mapped I/O",
462 "MMIO Port Space",
463 "PAL Code"
464};
465
466char * __init efi_md_typeattr_format(char *buf, size_t size,
467 const efi_memory_desc_t *md)
468{
469 char *pos;
470 int type_len;
471 u64 attr;
472
473 pos = buf;
474 if (md->type >= ARRAY_SIZE(memory_type_name))
475 type_len = snprintf(pos, size, "[type=%u", md->type);
476 else
477 type_len = snprintf(pos, size, "[%-*s",
478 (int)(sizeof(memory_type_name[0]) - 1),
479 memory_type_name[md->type]);
480 if (type_len >= size)
481 return buf;
482
483 pos += type_len;
484 size -= type_len;
485
486 attr = md->attribute;
487 if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT |
488 EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP |
489 EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME))
490 snprintf(pos, size, "|attr=0x%016llx]",
491 (unsigned long long)attr);
492 else
493 snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]",
494 attr & EFI_MEMORY_RUNTIME ? "RUN" : "",
495 attr & EFI_MEMORY_XP ? "XP" : "",
496 attr & EFI_MEMORY_RP ? "RP" : "",
497 attr & EFI_MEMORY_WP ? "WP" : "",
498 attr & EFI_MEMORY_UCE ? "UCE" : "",
499 attr & EFI_MEMORY_WB ? "WB" : "",
500 attr & EFI_MEMORY_WT ? "WT" : "",
501 attr & EFI_MEMORY_WC ? "WC" : "",
502 attr & EFI_MEMORY_UC ? "UC" : "");
503 return buf;
504}
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 480339b6b110..75ee05964cbc 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -226,6 +226,10 @@ unsigned long __init efi_entry(void *handle, efi_system_table_t *sys_table,
226 goto fail_free_image; 226 goto fail_free_image;
227 } 227 }
228 228
229 status = efi_parse_options(cmdline_ptr);
230 if (status != EFI_SUCCESS)
231 pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n");
232
229 /* 233 /*
230 * Unauthenticated device tree data is a security hazard, so 234 * Unauthenticated device tree data is a security hazard, so
231 * ignore 'dtb=' unless UEFI Secure Boot is disabled. 235 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c
index 32d5cca30f49..a920fec8fe88 100644
--- a/drivers/firmware/efi/libstub/efi-stub-helper.c
+++ b/drivers/firmware/efi/libstub/efi-stub-helper.c
@@ -15,8 +15,23 @@
15 15
16#include "efistub.h" 16#include "efistub.h"
17 17
18/*
19 * Some firmware implementations have problems reading files in one go.
20 * A read chunk size of 1MB seems to work for most platforms.
21 *
22 * Unfortunately, reading files in chunks triggers *other* bugs on some
23 * platforms, so we provide a way to disable this workaround, which can
24 * be done by passing "efi=nochunk" on the EFI boot stub command line.
25 *
26 * If you experience issues with initrd images being corrupt it's worth
27 * trying efi=nochunk, but chunking is enabled by default because there
28 * are far more machines that require the workaround than those that
29 * break with it enabled.
30 */
18#define EFI_READ_CHUNK_SIZE (1024 * 1024) 31#define EFI_READ_CHUNK_SIZE (1024 * 1024)
19 32
33static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE;
34
20struct file_info { 35struct file_info {
21 efi_file_handle_t *handle; 36 efi_file_handle_t *handle;
22 u64 size; 37 u64 size;
@@ -281,6 +296,49 @@ void efi_free(efi_system_table_t *sys_table_arg, unsigned long size,
281 efi_call_early(free_pages, addr, nr_pages); 296 efi_call_early(free_pages, addr, nr_pages);
282} 297}
283 298
299/*
300 * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi=
301 * option, e.g. efi=nochunk.
302 *
303 * It should be noted that efi= is parsed in two very different
304 * environments, first in the early boot environment of the EFI boot
305 * stub, and subsequently during the kernel boot.
306 */
307efi_status_t efi_parse_options(char *cmdline)
308{
309 char *str;
310
311 /*
312 * If no EFI parameters were specified on the cmdline we've got
313 * nothing to do.
314 */
315 str = strstr(cmdline, "efi=");
316 if (!str)
317 return EFI_SUCCESS;
318
319 /* Skip ahead to first argument */
320 str += strlen("efi=");
321
322 /*
323 * Remember, because efi= is also used by the kernel we need to
324 * skip over arguments we don't understand.
325 */
326 while (*str) {
327 if (!strncmp(str, "nochunk", 7)) {
328 str += strlen("nochunk");
329 __chunk_size = -1UL;
330 }
331
332 /* Group words together, delimited by "," */
333 while (*str && *str != ',')
334 str++;
335
336 if (*str == ',')
337 str++;
338 }
339
340 return EFI_SUCCESS;
341}
284 342
285/* 343/*
286 * Check the cmdline for a LILO-style file= arguments. 344 * Check the cmdline for a LILO-style file= arguments.
@@ -423,8 +481,8 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
423 size = files[j].size; 481 size = files[j].size;
424 while (size) { 482 while (size) {
425 unsigned long chunksize; 483 unsigned long chunksize;
426 if (size > EFI_READ_CHUNK_SIZE) 484 if (size > __chunk_size)
427 chunksize = EFI_READ_CHUNK_SIZE; 485 chunksize = __chunk_size;
428 else 486 else
429 chunksize = size; 487 chunksize = size;
430 488
diff --git a/drivers/firmware/efi/runtime-wrappers.c b/drivers/firmware/efi/runtime-wrappers.c
index 10daa4bbb258..228bbf910461 100644
--- a/drivers/firmware/efi/runtime-wrappers.c
+++ b/drivers/firmware/efi/runtime-wrappers.c
@@ -14,11 +14,80 @@
14 * This file is released under the GPLv2. 14 * This file is released under the GPLv2.
15 */ 15 */
16 16
17#include <linux/bug.h>
17#include <linux/efi.h> 18#include <linux/efi.h>
18#include <linux/spinlock.h> /* spinlock_t */ 19#include <linux/mutex.h>
20#include <linux/spinlock.h>
19#include <asm/efi.h> 21#include <asm/efi.h>
20 22
21/* 23/*
24 * According to section 7.1 of the UEFI spec, Runtime Services are not fully
25 * reentrant, and there are particular combinations of calls that need to be
26 * serialized. (source: UEFI Specification v2.4A)
27 *
28 * Table 31. Rules for Reentry Into Runtime Services
29 * +------------------------------------+-------------------------------+
30 * | If previous call is busy in | Forbidden to call |
31 * +------------------------------------+-------------------------------+
32 * | Any | SetVirtualAddressMap() |
33 * +------------------------------------+-------------------------------+
34 * | ConvertPointer() | ConvertPointer() |
35 * +------------------------------------+-------------------------------+
36 * | SetVariable() | ResetSystem() |
37 * | UpdateCapsule() | |
38 * | SetTime() | |
39 * | SetWakeupTime() | |
40 * | GetNextHighMonotonicCount() | |
41 * +------------------------------------+-------------------------------+
42 * | GetVariable() | GetVariable() |
43 * | GetNextVariableName() | GetNextVariableName() |
44 * | SetVariable() | SetVariable() |
45 * | QueryVariableInfo() | QueryVariableInfo() |
46 * | UpdateCapsule() | UpdateCapsule() |
47 * | QueryCapsuleCapabilities() | QueryCapsuleCapabilities() |
48 * | GetNextHighMonotonicCount() | GetNextHighMonotonicCount() |
49 * +------------------------------------+-------------------------------+
50 * | GetTime() | GetTime() |
51 * | SetTime() | SetTime() |
52 * | GetWakeupTime() | GetWakeupTime() |
53 * | SetWakeupTime() | SetWakeupTime() |
54 * +------------------------------------+-------------------------------+
55 *
56 * Due to the fact that the EFI pstore may write to the variable store in
57 * interrupt context, we need to use a spinlock for at least the groups that
58 * contain SetVariable() and QueryVariableInfo(). That leaves little else, as
59 * none of the remaining functions are actually ever called at runtime.
60 * So let's just use a single spinlock to serialize all Runtime Services calls.
61 */
62static DEFINE_SPINLOCK(efi_runtime_lock);
63
64/*
65 * Some runtime services calls can be reentrant under NMI, even if the table
66 * above says they are not. (source: UEFI Specification v2.4A)
67 *
68 * Table 32. Functions that may be called after Machine Check, INIT and NMI
69 * +----------------------------+------------------------------------------+
70 * | Function | Called after Machine Check, INIT and NMI |
71 * +----------------------------+------------------------------------------+
72 * | GetTime() | Yes, even if previously busy. |
73 * | GetVariable() | Yes, even if previously busy |
74 * | GetNextVariableName() | Yes, even if previously busy |
75 * | QueryVariableInfo() | Yes, even if previously busy |
76 * | SetVariable() | Yes, even if previously busy |
77 * | UpdateCapsule() | Yes, even if previously busy |
78 * | QueryCapsuleCapabilities() | Yes, even if previously busy |
79 * | ResetSystem() | Yes, even if previously busy |
80 * +----------------------------+------------------------------------------+
81 *
82 * In order to prevent deadlocks under NMI, the wrappers for these functions
83 * may only grab the efi_runtime_lock or rtc_lock spinlocks if !efi_in_nmi().
84 * However, not all of the services listed are reachable through NMI code paths,
85 * so the the special handling as suggested by the UEFI spec is only implemented
86 * for QueryVariableInfo() and SetVariable(), as these can be reached in NMI
87 * context through efi_pstore_write().
88 */
89
90/*
22 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), 91 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"),
23 * the EFI specification requires that callers of the time related runtime 92 * the EFI specification requires that callers of the time related runtime
24 * functions serialize with other CMOS accesses in the kernel, as the EFI time 93 * functions serialize with other CMOS accesses in the kernel, as the EFI time
@@ -32,7 +101,9 @@ static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc)
32 efi_status_t status; 101 efi_status_t status;
33 102
34 spin_lock_irqsave(&rtc_lock, flags); 103 spin_lock_irqsave(&rtc_lock, flags);
104 spin_lock(&efi_runtime_lock);
35 status = efi_call_virt(get_time, tm, tc); 105 status = efi_call_virt(get_time, tm, tc);
106 spin_unlock(&efi_runtime_lock);
36 spin_unlock_irqrestore(&rtc_lock, flags); 107 spin_unlock_irqrestore(&rtc_lock, flags);
37 return status; 108 return status;
38} 109}
@@ -43,7 +114,9 @@ static efi_status_t virt_efi_set_time(efi_time_t *tm)
43 efi_status_t status; 114 efi_status_t status;
44 115
45 spin_lock_irqsave(&rtc_lock, flags); 116 spin_lock_irqsave(&rtc_lock, flags);
117 spin_lock(&efi_runtime_lock);
46 status = efi_call_virt(set_time, tm); 118 status = efi_call_virt(set_time, tm);
119 spin_unlock(&efi_runtime_lock);
47 spin_unlock_irqrestore(&rtc_lock, flags); 120 spin_unlock_irqrestore(&rtc_lock, flags);
48 return status; 121 return status;
49} 122}
@@ -56,7 +129,9 @@ static efi_status_t virt_efi_get_wakeup_time(efi_bool_t *enabled,
56 efi_status_t status; 129 efi_status_t status;
57 130
58 spin_lock_irqsave(&rtc_lock, flags); 131 spin_lock_irqsave(&rtc_lock, flags);
132 spin_lock(&efi_runtime_lock);
59 status = efi_call_virt(get_wakeup_time, enabled, pending, tm); 133 status = efi_call_virt(get_wakeup_time, enabled, pending, tm);
134 spin_unlock(&efi_runtime_lock);
60 spin_unlock_irqrestore(&rtc_lock, flags); 135 spin_unlock_irqrestore(&rtc_lock, flags);
61 return status; 136 return status;
62} 137}
@@ -67,7 +142,9 @@ static efi_status_t virt_efi_set_wakeup_time(efi_bool_t enabled, efi_time_t *tm)
67 efi_status_t status; 142 efi_status_t status;
68 143
69 spin_lock_irqsave(&rtc_lock, flags); 144 spin_lock_irqsave(&rtc_lock, flags);
145 spin_lock(&efi_runtime_lock);
70 status = efi_call_virt(set_wakeup_time, enabled, tm); 146 status = efi_call_virt(set_wakeup_time, enabled, tm);
147 spin_unlock(&efi_runtime_lock);
71 spin_unlock_irqrestore(&rtc_lock, flags); 148 spin_unlock_irqrestore(&rtc_lock, flags);
72 return status; 149 return status;
73} 150}
@@ -78,14 +155,27 @@ static efi_status_t virt_efi_get_variable(efi_char16_t *name,
78 unsigned long *data_size, 155 unsigned long *data_size,
79 void *data) 156 void *data)
80{ 157{
81 return efi_call_virt(get_variable, name, vendor, attr, data_size, data); 158 unsigned long flags;
159 efi_status_t status;
160
161 spin_lock_irqsave(&efi_runtime_lock, flags);
162 status = efi_call_virt(get_variable, name, vendor, attr, data_size,
163 data);
164 spin_unlock_irqrestore(&efi_runtime_lock, flags);
165 return status;
82} 166}
83 167
84static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, 168static efi_status_t virt_efi_get_next_variable(unsigned long *name_size,
85 efi_char16_t *name, 169 efi_char16_t *name,
86 efi_guid_t *vendor) 170 efi_guid_t *vendor)
87{ 171{
88 return efi_call_virt(get_next_variable, name_size, name, vendor); 172 unsigned long flags;
173 efi_status_t status;
174
175 spin_lock_irqsave(&efi_runtime_lock, flags);
176 status = efi_call_virt(get_next_variable, name_size, name, vendor);
177 spin_unlock_irqrestore(&efi_runtime_lock, flags);
178 return status;
89} 179}
90 180
91static efi_status_t virt_efi_set_variable(efi_char16_t *name, 181static efi_status_t virt_efi_set_variable(efi_char16_t *name,
@@ -94,24 +184,61 @@ static efi_status_t virt_efi_set_variable(efi_char16_t *name,
94 unsigned long data_size, 184 unsigned long data_size,
95 void *data) 185 void *data)
96{ 186{
97 return efi_call_virt(set_variable, name, vendor, attr, data_size, data); 187 unsigned long flags;
188 efi_status_t status;
189
190 spin_lock_irqsave(&efi_runtime_lock, flags);
191 status = efi_call_virt(set_variable, name, vendor, attr, data_size,
192 data);
193 spin_unlock_irqrestore(&efi_runtime_lock, flags);
194 return status;
98} 195}
99 196
197static efi_status_t
198virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor,
199 u32 attr, unsigned long data_size,
200 void *data)
201{
202 unsigned long flags;
203 efi_status_t status;
204
205 if (!spin_trylock_irqsave(&efi_runtime_lock, flags))
206 return EFI_NOT_READY;
207
208 status = efi_call_virt(set_variable, name, vendor, attr, data_size,
209 data);
210 spin_unlock_irqrestore(&efi_runtime_lock, flags);
211 return status;
212}
213
214
100static efi_status_t virt_efi_query_variable_info(u32 attr, 215static efi_status_t virt_efi_query_variable_info(u32 attr,
101 u64 *storage_space, 216 u64 *storage_space,
102 u64 *remaining_space, 217 u64 *remaining_space,
103 u64 *max_variable_size) 218 u64 *max_variable_size)
104{ 219{
220 unsigned long flags;
221 efi_status_t status;
222
105 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 223 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
106 return EFI_UNSUPPORTED; 224 return EFI_UNSUPPORTED;
107 225
108 return efi_call_virt(query_variable_info, attr, storage_space, 226 spin_lock_irqsave(&efi_runtime_lock, flags);
109 remaining_space, max_variable_size); 227 status = efi_call_virt(query_variable_info, attr, storage_space,
228 remaining_space, max_variable_size);
229 spin_unlock_irqrestore(&efi_runtime_lock, flags);
230 return status;
110} 231}
111 232
112static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) 233static efi_status_t virt_efi_get_next_high_mono_count(u32 *count)
113{ 234{
114 return efi_call_virt(get_next_high_mono_count, count); 235 unsigned long flags;
236 efi_status_t status;
237
238 spin_lock_irqsave(&efi_runtime_lock, flags);
239 status = efi_call_virt(get_next_high_mono_count, count);
240 spin_unlock_irqrestore(&efi_runtime_lock, flags);
241 return status;
115} 242}
116 243
117static void virt_efi_reset_system(int reset_type, 244static void virt_efi_reset_system(int reset_type,
@@ -119,17 +246,27 @@ static void virt_efi_reset_system(int reset_type,
119 unsigned long data_size, 246 unsigned long data_size,
120 efi_char16_t *data) 247 efi_char16_t *data)
121{ 248{
249 unsigned long flags;
250
251 spin_lock_irqsave(&efi_runtime_lock, flags);
122 __efi_call_virt(reset_system, reset_type, status, data_size, data); 252 __efi_call_virt(reset_system, reset_type, status, data_size, data);
253 spin_unlock_irqrestore(&efi_runtime_lock, flags);
123} 254}
124 255
125static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, 256static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules,
126 unsigned long count, 257 unsigned long count,
127 unsigned long sg_list) 258 unsigned long sg_list)
128{ 259{
260 unsigned long flags;
261 efi_status_t status;
262
129 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 263 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
130 return EFI_UNSUPPORTED; 264 return EFI_UNSUPPORTED;
131 265
132 return efi_call_virt(update_capsule, capsules, count, sg_list); 266 spin_lock_irqsave(&efi_runtime_lock, flags);
267 status = efi_call_virt(update_capsule, capsules, count, sg_list);
268 spin_unlock_irqrestore(&efi_runtime_lock, flags);
269 return status;
133} 270}
134 271
135static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, 272static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
@@ -137,11 +274,17 @@ static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules,
137 u64 *max_size, 274 u64 *max_size,
138 int *reset_type) 275 int *reset_type)
139{ 276{
277 unsigned long flags;
278 efi_status_t status;
279
140 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 280 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION)
141 return EFI_UNSUPPORTED; 281 return EFI_UNSUPPORTED;
142 282
143 return efi_call_virt(query_capsule_caps, capsules, count, max_size, 283 spin_lock_irqsave(&efi_runtime_lock, flags);
144 reset_type); 284 status = efi_call_virt(query_capsule_caps, capsules, count, max_size,
285 reset_type);
286 spin_unlock_irqrestore(&efi_runtime_lock, flags);
287 return status;
145} 288}
146 289
147void efi_native_runtime_setup(void) 290void efi_native_runtime_setup(void)
@@ -153,6 +296,7 @@ void efi_native_runtime_setup(void)
153 efi.get_variable = virt_efi_get_variable; 296 efi.get_variable = virt_efi_get_variable;
154 efi.get_next_variable = virt_efi_get_next_variable; 297 efi.get_next_variable = virt_efi_get_next_variable;
155 efi.set_variable = virt_efi_set_variable; 298 efi.set_variable = virt_efi_set_variable;
299 efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking;
156 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; 300 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count;
157 efi.reset_system = virt_efi_reset_system; 301 efi.reset_system = virt_efi_reset_system;
158 efi.query_variable_info = virt_efi_query_variable_info; 302 efi.query_variable_info = virt_efi_query_variable_info;
diff --git a/drivers/firmware/efi/vars.c b/drivers/firmware/efi/vars.c
index 5abe943e3404..70a0fb10517f 100644
--- a/drivers/firmware/efi/vars.c
+++ b/drivers/firmware/efi/vars.c
@@ -321,11 +321,11 @@ static unsigned long var_name_strnsize(efi_char16_t *variable_name,
321 * Print a warning when duplicate EFI variables are encountered and 321 * Print a warning when duplicate EFI variables are encountered and
322 * disable the sysfs workqueue since the firmware is buggy. 322 * disable the sysfs workqueue since the firmware is buggy.
323 */ 323 */
324static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid, 324static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid,
325 unsigned long len16) 325 unsigned long len16)
326{ 326{
327 size_t i, len8 = len16 / sizeof(efi_char16_t); 327 size_t i, len8 = len16 / sizeof(efi_char16_t);
328 char *s8; 328 char *str8;
329 329
330 /* 330 /*
331 * Disable the workqueue since the algorithm it uses for 331 * Disable the workqueue since the algorithm it uses for
@@ -334,16 +334,16 @@ static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid,
334 */ 334 */
335 efivar_wq_enabled = false; 335 efivar_wq_enabled = false;
336 336
337 s8 = kzalloc(len8, GFP_KERNEL); 337 str8 = kzalloc(len8, GFP_KERNEL);
338 if (!s8) 338 if (!str8)
339 return; 339 return;
340 340
341 for (i = 0; i < len8; i++) 341 for (i = 0; i < len8; i++)
342 s8[i] = s16[i]; 342 str8[i] = str16[i];
343 343
344 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", 344 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n",
345 s8, vendor_guid); 345 str8, vendor_guid);
346 kfree(s8); 346 kfree(str8);
347} 347}
348 348
349/** 349/**
@@ -595,6 +595,39 @@ int efivar_entry_set(struct efivar_entry *entry, u32 attributes,
595} 595}
596EXPORT_SYMBOL_GPL(efivar_entry_set); 596EXPORT_SYMBOL_GPL(efivar_entry_set);
597 597
598/*
599 * efivar_entry_set_nonblocking - call set_variable_nonblocking()
600 *
601 * This function is guaranteed to not block and is suitable for calling
602 * from crash/panic handlers.
603 *
604 * Crucially, this function will not block if it cannot acquire
605 * __efivars->lock. Instead, it returns -EBUSY.
606 */
607static int
608efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,
609 u32 attributes, unsigned long size, void *data)
610{
611 const struct efivar_operations *ops = __efivars->ops;
612 unsigned long flags;
613 efi_status_t status;
614
615 if (!spin_trylock_irqsave(&__efivars->lock, flags))
616 return -EBUSY;
617
618 status = check_var_size(attributes, size + ucs2_strsize(name, 1024));
619 if (status != EFI_SUCCESS) {
620 spin_unlock_irqrestore(&__efivars->lock, flags);
621 return -ENOSPC;
622 }
623
624 status = ops->set_variable_nonblocking(name, &vendor, attributes,
625 size, data);
626
627 spin_unlock_irqrestore(&__efivars->lock, flags);
628 return efi_status_to_err(status);
629}
630
598/** 631/**
599 * efivar_entry_set_safe - call set_variable() if enough space in firmware 632 * efivar_entry_set_safe - call set_variable() if enough space in firmware
600 * @name: buffer containing the variable name 633 * @name: buffer containing the variable name
@@ -622,6 +655,20 @@ int efivar_entry_set_safe(efi_char16_t *name, efi_guid_t vendor, u32 attributes,
622 if (!ops->query_variable_store) 655 if (!ops->query_variable_store)
623 return -ENOSYS; 656 return -ENOSYS;
624 657
658 /*
659 * If the EFI variable backend provides a non-blocking
660 * ->set_variable() operation and we're in a context where we
661 * cannot block, then we need to use it to avoid live-locks,
662 * since the implication is that the regular ->set_variable()
663 * will block.
664 *
665 * If no ->set_variable_nonblocking() is provided then
666 * ->set_variable() is assumed to be non-blocking.
667 */
668 if (!block && ops->set_variable_nonblocking)
669 return efivar_entry_set_nonblocking(name, vendor, attributes,
670 size, data);
671
625 if (!block) { 672 if (!block) {
626 if (!spin_trylock_irqsave(&__efivars->lock, flags)) 673 if (!spin_trylock_irqsave(&__efivars->lock, flags))
627 return -EBUSY; 674 return -EBUSY;
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 8cd0beebdc3f..94ae1798d48a 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -830,7 +830,7 @@ config RTC_DRV_DA9063
830 830
831config RTC_DRV_EFI 831config RTC_DRV_EFI
832 tristate "EFI RTC" 832 tristate "EFI RTC"
833 depends on EFI 833 depends on EFI && !X86
834 help 834 help
835 If you say yes here you will get support for the EFI 835 If you say yes here you will get support for the EFI
836 Real Time Clock. 836 Real Time Clock.
diff --git a/drivers/rtc/rtc-efi.c b/drivers/rtc/rtc-efi.c
index c384fec6d173..53b589dc34eb 100644
--- a/drivers/rtc/rtc-efi.c
+++ b/drivers/rtc/rtc-efi.c
@@ -236,3 +236,4 @@ MODULE_ALIAS("platform:rtc-efi");
236MODULE_AUTHOR("dann frazier <dannf@hp.com>"); 236MODULE_AUTHOR("dann frazier <dannf@hp.com>");
237MODULE_LICENSE("GPL"); 237MODULE_LICENSE("GPL");
238MODULE_DESCRIPTION("EFI RTC driver"); 238MODULE_DESCRIPTION("EFI RTC driver");
239MODULE_ALIAS("platform:rtc-efi");
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 45cb4ffdea62..0949f9c7e872 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -92,6 +92,7 @@ typedef struct {
92#define EFI_MEMORY_WC ((u64)0x0000000000000002ULL) /* write-coalescing */ 92#define EFI_MEMORY_WC ((u64)0x0000000000000002ULL) /* write-coalescing */
93#define EFI_MEMORY_WT ((u64)0x0000000000000004ULL) /* write-through */ 93#define EFI_MEMORY_WT ((u64)0x0000000000000004ULL) /* write-through */
94#define EFI_MEMORY_WB ((u64)0x0000000000000008ULL) /* write-back */ 94#define EFI_MEMORY_WB ((u64)0x0000000000000008ULL) /* write-back */
95#define EFI_MEMORY_UCE ((u64)0x0000000000000010ULL) /* uncached, exported */
95#define EFI_MEMORY_WP ((u64)0x0000000000001000ULL) /* write-protect */ 96#define EFI_MEMORY_WP ((u64)0x0000000000001000ULL) /* write-protect */
96#define EFI_MEMORY_RP ((u64)0x0000000000002000ULL) /* read-protect */ 97#define EFI_MEMORY_RP ((u64)0x0000000000002000ULL) /* read-protect */
97#define EFI_MEMORY_XP ((u64)0x0000000000004000ULL) /* execute-protect */ 98#define EFI_MEMORY_XP ((u64)0x0000000000004000ULL) /* execute-protect */
@@ -502,6 +503,10 @@ typedef efi_status_t efi_get_next_variable_t (unsigned long *name_size, efi_char
502typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, 503typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor,
503 u32 attr, unsigned long data_size, 504 u32 attr, unsigned long data_size,
504 void *data); 505 void *data);
506typedef efi_status_t
507efi_set_variable_nonblocking_t(efi_char16_t *name, efi_guid_t *vendor,
508 u32 attr, unsigned long data_size, void *data);
509
505typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); 510typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count);
506typedef void efi_reset_system_t (int reset_type, efi_status_t status, 511typedef void efi_reset_system_t (int reset_type, efi_status_t status,
507 unsigned long data_size, efi_char16_t *data); 512 unsigned long data_size, efi_char16_t *data);
@@ -821,6 +826,7 @@ extern struct efi {
821 efi_get_variable_t *get_variable; 826 efi_get_variable_t *get_variable;
822 efi_get_next_variable_t *get_next_variable; 827 efi_get_next_variable_t *get_next_variable;
823 efi_set_variable_t *set_variable; 828 efi_set_variable_t *set_variable;
829 efi_set_variable_nonblocking_t *set_variable_nonblocking;
824 efi_query_variable_info_t *query_variable_info; 830 efi_query_variable_info_t *query_variable_info;
825 efi_update_capsule_t *update_capsule; 831 efi_update_capsule_t *update_capsule;
826 efi_query_capsule_caps_t *query_capsule_caps; 832 efi_query_capsule_caps_t *query_capsule_caps;
@@ -886,6 +892,13 @@ extern bool efi_poweroff_required(void);
886 (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \ 892 (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \
887 (md) = (void *)(md) + (m)->desc_size) 893 (md) = (void *)(md) + (m)->desc_size)
888 894
895/*
896 * Format an EFI memory descriptor's type and attributes to a user-provided
897 * character buffer, as per snprintf(), and return the buffer.
898 */
899char * __init efi_md_typeattr_format(char *buf, size_t size,
900 const efi_memory_desc_t *md);
901
889/** 902/**
890 * efi_range_is_wc - check the WC bit on an address range 903 * efi_range_is_wc - check the WC bit on an address range
891 * @start: starting kvirt address 904 * @start: starting kvirt address
@@ -1034,6 +1047,7 @@ struct efivar_operations {
1034 efi_get_variable_t *get_variable; 1047 efi_get_variable_t *get_variable;
1035 efi_get_next_variable_t *get_next_variable; 1048 efi_get_next_variable_t *get_next_variable;
1036 efi_set_variable_t *set_variable; 1049 efi_set_variable_t *set_variable;
1050 efi_set_variable_nonblocking_t *set_variable_nonblocking;
1037 efi_query_variable_store_t *query_variable_store; 1051 efi_query_variable_store_t *query_variable_store;
1038}; 1052};
1039 1053
@@ -1227,4 +1241,7 @@ efi_status_t handle_cmdline_files(efi_system_table_t *sys_table_arg,
1227 unsigned long *load_addr, 1241 unsigned long *load_addr,
1228 unsigned long *load_size); 1242 unsigned long *load_size);
1229 1243
1244efi_status_t efi_parse_options(char *cmdline);
1245
1246bool efi_runtime_disabled(void);
1230#endif /* _LINUX_EFI_H */ 1247#endif /* _LINUX_EFI_H */
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 40728cf1c452..3d770f5564b8 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -403,6 +403,7 @@ int vsscanf(const char *, const char *, va_list);
403extern int get_option(char **str, int *pint); 403extern int get_option(char **str, int *pint);
404extern char *get_options(const char *str, int nints, int *ints); 404extern char *get_options(const char *str, int nints, int *ints);
405extern unsigned long long memparse(const char *ptr, char **retptr); 405extern unsigned long long memparse(const char *ptr, char **retptr);
406extern bool parse_option_str(const char *str, const char *option);
406 407
407extern int core_kernel_text(unsigned long addr); 408extern int core_kernel_text(unsigned long addr);
408extern int core_kernel_data(unsigned long addr); 409extern int core_kernel_data(unsigned long addr);
diff --git a/lib/cmdline.c b/lib/cmdline.c
index 76a712e6e20e..8f13cf73c2ec 100644
--- a/lib/cmdline.c
+++ b/lib/cmdline.c
@@ -160,3 +160,32 @@ unsigned long long memparse(const char *ptr, char **retptr)
160 return ret; 160 return ret;
161} 161}
162EXPORT_SYMBOL(memparse); 162EXPORT_SYMBOL(memparse);
163
164/**
165 * parse_option_str - Parse a string and check an option is set or not
166 * @str: String to be parsed
167 * @option: option name
168 *
169 * This function parses a string containing a comma-separated list of
170 * strings like a=b,c.
171 *
172 * Return true if there's such option in the string, or return false.
173 */
174bool parse_option_str(const char *str, const char *option)
175{
176 while (*str) {
177 if (!strncmp(str, option, strlen(option))) {
178 str += strlen(option);
179 if (!*str || *str == ',')
180 return true;
181 }
182
183 while (*str && *str != ',')
184 str++;
185
186 if (*str == ',')
187 str++;
188 }
189
190 return false;
191}