Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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
...

+528 -123
+6 -2
Documentation/kernel-parameters.txt
··· 1015 1015 Format: {"off" | "on" | "skip[mbr]"} 1016 1016 1017 1017 efi= [EFI] 1018 - Format: { "old_map" } 1018 + Format: { "old_map", "nochunk", "noruntime" } 1019 1019 old_map [X86-64]: switch to the old ioremap-based EFI 1020 1020 runtime services mapping. 32-bit still uses this one by 1021 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 1027 efi_no_storage_paranoia [EFI; X86] 1024 1028 Using this parameter you can use more than 50% of ··· 2236 2232 2237 2233 nodsp [SH] Disable hardware DSP at boot time. 2238 2234 2239 - noefi [X86] Disable EFI runtime services support. 2235 + noefi Disable EFI runtime services support. 2240 2236 2241 2237 noexec [IA-64] 2242 2238
+18 -26
arch/arm64/kernel/efi.c
··· 89 89 */ 90 90 if (efi.systab->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) { 91 91 pr_err("System table signature incorrect\n"); 92 - return -EINVAL; 92 + retval = -EINVAL; 93 + goto out; 93 94 } 94 95 if ((efi.systab->hdr.revision >> 16) < 2) 95 96 pr_warn("Warning: EFI system table version %d.%02d, expected 2.00 or greater\n", ··· 104 103 for (i = 0; i < (int) sizeof(vendor) - 1 && *c16; ++i) 105 104 vendor[i] = c16[i]; 106 105 vendor[i] = '\0'; 106 + early_memunmap(c16, sizeof(vendor)); 107 107 } 108 108 109 109 pr_info("EFI v%u.%.02u by %s\n", ··· 115 113 if (retval == 0) 116 114 set_bit(EFI_CONFIG_TABLES, &efi.flags); 117 115 118 - early_memunmap(c16, sizeof(vendor)); 116 + out: 119 117 early_memunmap(efi.systab, sizeof(efi_system_table_t)); 120 - 121 118 return retval; 122 119 } 123 - 124 - static __initdata char memory_type_name[][32] = { 125 - {"Reserved"}, 126 - {"Loader Code"}, 127 - {"Loader Data"}, 128 - {"Boot Code"}, 129 - {"Boot Data"}, 130 - {"Runtime Code"}, 131 - {"Runtime Data"}, 132 - {"Conventional Memory"}, 133 - {"Unusable Memory"}, 134 - {"ACPI Reclaim Memory"}, 135 - {"ACPI Memory NVS"}, 136 - {"Memory Mapped I/O"}, 137 - {"MMIO Port Space"}, 138 - {"PAL Code"}, 139 - }; 140 120 141 121 /* 142 122 * Return true for RAM regions we want to permanently reserve. ··· 150 166 paddr = md->phys_addr; 151 167 npages = md->num_pages; 152 168 153 - if (uefi_debug) 154 - pr_info(" 0x%012llx-0x%012llx [%s]", 169 + if (uefi_debug) { 170 + char buf[64]; 171 + 172 + pr_info(" 0x%012llx-0x%012llx %s", 155 173 paddr, paddr + (npages << EFI_PAGE_SHIFT) - 1, 156 - memory_type_name[md->type]); 174 + efi_md_typeattr_format(buf, sizeof(buf), md)); 175 + } 157 176 158 177 memrange_efi_to_native(&paddr, &npages); 159 178 size = npages << PAGE_SHIFT; ··· 380 393 return -1; 381 394 } 382 395 383 - pr_info("Remapping and enabling EFI services.\n"); 384 - 385 - /* replace early memmap mapping with permanent mapping */ 386 396 mapsize = memmap.map_end - memmap.map; 387 397 early_memunmap(memmap.map, mapsize); 398 + 399 + if (efi_runtime_disabled()) { 400 + pr_info("EFI runtime services will be disabled.\n"); 401 + return -1; 402 + } 403 + 404 + pr_info("Remapping and enabling EFI services.\n"); 405 + /* replace early memmap mapping with permanent mapping */ 388 406 memmap.map = (__force void *)ioremap_cache((phys_addr_t)memmap.phys_map, 389 407 mapsize); 390 408 memmap.map_end = memmap.map + mapsize;
+4 -2
arch/ia64/kernel/efi.c
··· 568 568 { 569 569 const char *unit; 570 570 unsigned long size; 571 + char buf[64]; 571 572 572 573 md = p; 573 574 size = md->num_pages << EFI_PAGE_SHIFT; ··· 587 586 unit = "KB"; 588 587 } 589 588 590 - printk("mem%02d: type=%2u, attr=0x%016lx, " 589 + printk("mem%02d: %s " 591 590 "range=[0x%016lx-0x%016lx) (%4lu%s)\n", 592 - i, md->type, md->attribute, md->phys_addr, 591 + i, efi_md_typeattr_format(buf, sizeof(buf), md), 592 + md->phys_addr, 593 593 md->phys_addr + efi_md_size(md), size, unit); 594 594 } 595 595 }
+25 -7
arch/x86/boot/compressed/eboot.c
··· 330 330 size = pci->romsize + sizeof(*rom); 331 331 332 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 335 return status; 336 + } 335 337 336 338 memset(rom, 0, sizeof(*rom)); 337 339 ··· 346 344 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 347 345 PCI_VENDOR_ID, 1, &(rom->vendor)); 348 346 349 - if (status != EFI_SUCCESS) 347 + if (status != EFI_SUCCESS) { 348 + efi_printk(sys_table, "Failed to read rom->vendor\n"); 350 349 goto free_struct; 350 + } 351 351 352 352 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 353 353 PCI_DEVICE_ID, 1, &(rom->devid)); 354 354 355 - if (status != EFI_SUCCESS) 355 + if (status != EFI_SUCCESS) { 356 + efi_printk(sys_table, "Failed to read rom->devid\n"); 356 357 goto free_struct; 358 + } 357 359 358 360 status = efi_early->call(pci->get_location, pci, &(rom->segment), 359 361 &(rom->bus), &(rom->device), &(rom->function)); ··· 438 432 size = pci->romsize + sizeof(*rom); 439 433 440 434 status = efi_call_early(allocate_pool, EFI_LOADER_DATA, size, &rom); 441 - if (status != EFI_SUCCESS) 435 + if (status != EFI_SUCCESS) { 436 + efi_printk(sys_table, "Failed to alloc mem for rom\n"); 442 437 return status; 438 + } 443 439 444 440 rom->data.type = SETUP_PCI; 445 441 rom->data.len = size - sizeof(struct setup_data); ··· 452 444 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 453 445 PCI_VENDOR_ID, 1, &(rom->vendor)); 454 446 455 - if (status != EFI_SUCCESS) 447 + if (status != EFI_SUCCESS) { 448 + efi_printk(sys_table, "Failed to read rom->vendor\n"); 456 449 goto free_struct; 450 + } 457 451 458 452 status = efi_early->call(pci->pci.read, pci, EfiPciIoWidthUint16, 459 453 PCI_DEVICE_ID, 1, &(rom->devid)); 460 454 461 - if (status != EFI_SUCCESS) 455 + if (status != EFI_SUCCESS) { 456 + efi_printk(sys_table, "Failed to read rom->devid\n"); 462 457 goto free_struct; 458 + } 463 459 464 460 status = efi_early->call(pci->get_location, pci, &(rom->segment), 465 461 &(rom->bus), &(rom->device), &(rom->function)); ··· 550 538 EFI_LOADER_DATA, 551 539 size, (void **)&pci_handle); 552 540 553 - if (status != EFI_SUCCESS) 541 + if (status != EFI_SUCCESS) { 542 + efi_printk(sys_table, "Failed to alloc mem for pci_handle\n"); 554 543 return; 544 + } 555 545 556 546 status = efi_call_early(locate_handle, 557 547 EFI_LOCATE_BY_PROTOCOL, &pci_proto, ··· 1118 1104 memset(bi, 0, sizeof(*bi)); 1119 1105 1120 1106 memset(sdt, 0, sizeof(*sdt)); 1107 + 1108 + status = efi_parse_options(cmdline_ptr); 1109 + if (status != EFI_SUCCESS) 1110 + goto fail2; 1121 1111 1122 1112 status = handle_cmdline_files(sys_table, image, 1123 1113 (char *)(unsigned long)hdr->cmd_line_ptr,
+10 -21
arch/x86/include/asm/efi.h
··· 81 81 */ 82 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, 85 - u32 type, u64 attribute); 84 + extern void __iomem *__init efi_ioremap(unsigned long addr, unsigned long size, 85 + u32 type, u64 attribute); 86 86 87 87 #endif /* CONFIG_X86_32 */ 88 88 89 - extern int add_efi_memmap; 90 89 extern struct efi_scratch efi_scratch; 91 - extern void efi_set_executable(efi_memory_desc_t *md, bool executable); 92 - extern int efi_memblock_x86_reserve_range(void); 93 - extern void efi_call_phys_prelog(void); 94 - extern void efi_call_phys_epilog(void); 95 - extern void efi_unmap_memmap(void); 96 - extern void efi_memory_uc(u64 addr, unsigned long size); 90 + extern void __init efi_set_executable(efi_memory_desc_t *md, bool executable); 91 + extern int __init efi_memblock_x86_reserve_range(void); 92 + extern void __init efi_call_phys_prolog(void); 93 + extern void __init efi_call_phys_epilog(void); 94 + extern void __init efi_unmap_memmap(void); 95 + extern void __init efi_memory_uc(u64 addr, unsigned long size); 97 96 extern void __init efi_map_region(efi_memory_desc_t *md); 98 97 extern void __init efi_map_region_fixed(efi_memory_desc_t *md); 99 98 extern void efi_sync_low_kernel_mappings(void); 100 - extern int 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); 99 + extern int __init efi_setup_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 101 extern void __init old_map_region(efi_memory_desc_t *md); 103 102 extern void __init runtime_code_page_mkexec(void); 104 103 extern void __init efi_runtime_mkexec(void); ··· 161 162 extern bool efi_reboot_required(void); 162 163 163 164 #else 164 - /* 165 - * IF EFI is not configured, have the EFI calls return -ENOSYS. 166 - */ 167 - #define efi_call0(_f) (-ENOSYS) 168 - #define efi_call1(_f, _a1) (-ENOSYS) 169 - #define efi_call2(_f, _a1, _a2) (-ENOSYS) 170 - #define efi_call3(_f, _a1, _a2, _a3) (-ENOSYS) 171 - #define efi_call4(_f, _a1, _a2, _a3, _a4) (-ENOSYS) 172 - #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS) 173 - #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS) 174 165 static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} 175 166 static inline bool efi_reboot_required(void) 176 167 {
+30 -6
arch/x86/platform/efi/efi-bgrt.c
··· 40 40 if (ACPI_FAILURE(status)) 41 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 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); 46 51 return; 47 - if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address) 52 + } 53 + if (bgrt_tab->status != 1) { 54 + pr_err("Ignoring BGRT: invalid status %u (expected 1)\n", 55 + bgrt_tab->status); 48 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); 61 + return; 62 + } 63 + if (!bgrt_tab->image_address) { 64 + pr_err("Ignoring BGRT: null image address\n"); 65 + return; 66 + } 49 67 50 68 image = efi_lookup_mapped_addr(bgrt_tab->image_address); 51 69 if (!image) { 52 70 image = early_memremap(bgrt_tab->image_address, 53 71 sizeof(bmp_header)); 54 72 ioremapped = true; 55 - if (!image) 73 + if (!image) { 74 + pr_err("Ignoring BGRT: failed to map image header memory\n"); 56 75 return; 76 + } 57 77 } 58 78 59 79 memcpy_fromio(&bmp_header, image, sizeof(bmp_header)); ··· 81 61 early_iounmap(image, sizeof(bmp_header)); 82 62 bgrt_image_size = bmp_header.size; 83 63 84 - bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL); 85 - if (!bgrt_image) 64 + bgrt_image = kmalloc(bgrt_image_size, GFP_KERNEL | __GFP_NOWARN); 65 + if (!bgrt_image) { 66 + pr_err("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n", 67 + bgrt_image_size); 86 68 return; 69 + } 87 70 88 71 if (ioremapped) { 89 72 image = early_memremap(bgrt_tab->image_address, 90 73 bmp_header.size); 91 74 if (!image) { 75 + pr_err("Ignoring BGRT: failed to map image memory\n"); 92 76 kfree(bgrt_image); 93 77 bgrt_image = NULL; 94 78 return;
+23 -29
arch/x86/platform/efi/efi.c
··· 70 70 71 71 u64 efi_setup; /* efi setup_data physical address */ 72 72 73 - static bool disable_runtime __initdata = false; 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 - 73 + static int add_efi_memmap __initdata; 84 74 static int __init setup_add_efi_memmap(char *arg) 85 75 { 86 76 add_efi_memmap = 1; ··· 86 96 { 87 97 efi_status_t status; 88 98 89 - efi_call_phys_prelog(); 99 + efi_call_phys_prolog(); 90 100 status = efi_call_phys(efi_phys.set_virtual_address_map, 91 101 memory_map_size, descriptor_size, 92 102 descriptor_version, virtual_map); ··· 200 210 for (p = memmap.map, i = 0; 201 211 p < memmap.map_end; 202 212 p += memmap.desc_size, i++) { 213 + char buf[64]; 214 + 203 215 md = p; 204 - pr_info("mem%02u: type=%u, attr=0x%llx, range=[0x%016llx-0x%016llx) (%lluMB)\n", 205 - i, md->type, md->attribute, md->phys_addr, 216 + pr_info("mem%02u: %s range=[0x%016llx-0x%016llx) (%lluMB)\n", 217 + i, efi_md_typeattr_format(buf, sizeof(buf), md), 218 + md->phys_addr, 206 219 md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT), 207 220 (md->num_pages >> (20 - EFI_PAGE_SHIFT))); 208 221 } ··· 337 344 } 338 345 339 346 /* 340 - * We will only need *early* access to the following two 341 - * EFI runtime services before set_virtual_address_map 342 - * is invoked. 347 + * We will only need *early* access to the SetVirtualAddressMap 348 + * EFI runtime service. All other runtime services will be called 349 + * via the virtual mapping. 343 350 */ 344 351 efi_phys.set_virtual_address_map = 345 352 (efi_set_virtual_address_map_t *) ··· 361 368 } 362 369 363 370 /* 364 - * We will only need *early* access to the following two 365 - * EFI runtime services before set_virtual_address_map 366 - * is invoked. 371 + * We will only need *early* access to the SetVirtualAddressMap 372 + * EFI runtime service. All other runtime services will be called 373 + * via the virtual mapping. 367 374 */ 368 375 efi_phys.set_virtual_address_map = 369 376 (efi_set_virtual_address_map_t *) ··· 485 492 if (!efi_runtime_supported()) 486 493 pr_info("No EFI runtime due to 32/64-bit mismatch with kernel\n"); 487 494 else { 488 - if (disable_runtime || efi_runtime_init()) 495 + if (efi_runtime_disabled() || efi_runtime_init()) 489 496 return; 490 497 } 491 498 if (efi_memmap_init()) ··· 530 537 } 531 538 } 532 539 533 - void efi_memory_uc(u64 addr, unsigned long size) 540 + void __init efi_memory_uc(u64 addr, unsigned long size) 534 541 { 535 542 unsigned long page_shift = 1UL << EFI_PAGE_SHIFT; 536 543 u64 npages; ··· 725 732 */ 726 733 if (!efi_is_native()) { 727 734 efi_unmap_memmap(); 735 + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 728 736 return; 729 737 } 730 738 ··· 799 805 new_memmap = efi_map_regions(&count, &pg_shift); 800 806 if (!new_memmap) { 801 807 pr_err("Error reallocating memory, EFI runtime non-functional!\n"); 808 + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 802 809 return; 803 810 } 804 811 ··· 807 812 808 813 BUG_ON(!efi.systab); 809 814 810 - if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) 815 + if (efi_setup_page_tables(__pa(new_memmap), 1 << pg_shift)) { 816 + clear_bit(EFI_RUNTIME_SERVICES, &efi.flags); 811 817 return; 818 + } 812 819 813 820 efi_sync_low_kernel_mappings(); 814 821 efi_dump_pagetable(); ··· 935 938 return 0; 936 939 } 937 940 938 - static int __init parse_efi_cmdline(char *str) 941 + static int __init arch_parse_efi_cmdline(char *str) 939 942 { 940 - if (*str == '=') 941 - str++; 942 - 943 - if (!strncmp(str, "old_map", 7)) 943 + if (parse_option_str(str, "old_map")) 944 944 set_bit(EFI_OLD_MEMMAP, &efi.flags); 945 945 946 946 return 0; 947 947 } 948 - early_param("efi", parse_efi_cmdline); 948 + early_param("efi", arch_parse_efi_cmdline);
+7 -5
arch/x86/platform/efi/efi_32.c
··· 33 33 34 34 /* 35 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 37 * claim EFI runtime service handler exclusively and to duplicate a memory in 38 38 * low memory space say 0 - 3G. 39 39 */ ··· 41 41 42 42 void efi_sync_low_kernel_mappings(void) {} 43 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 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 52 void __init efi_map_region(efi_memory_desc_t *md) 51 53 { ··· 57 55 void __init efi_map_region_fixed(efi_memory_desc_t *md) {} 58 56 void __init parse_efi_setup(u64 phys_addr, u32 data_len) {} 59 57 60 - void efi_call_phys_prelog(void) 58 + void __init efi_call_phys_prolog(void) 61 59 { 62 60 struct desc_ptr gdt_descr; 63 61 ··· 71 69 load_gdt(&gdt_descr); 72 70 } 73 71 74 - void efi_call_phys_epilog(void) 72 + void __init efi_call_phys_epilog(void) 75 73 { 76 74 struct desc_ptr gdt_descr; 77 75
+3 -3
arch/x86/platform/efi/efi_64.c
··· 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 84 unsigned long vaddress; 85 85 int pgd; ··· 139 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 144 unsigned long text; 145 145 struct page *page; ··· 192 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 197 pgd_t *pgd = (pgd_t *)__va(real_mode_header->trampoline_pgd); 198 198
+2 -2
arch/x86/platform/efi/efi_stub_32.S
··· 27 27 * set to 0x0010, DS and SS have been set to 0x0018. In EFI, I found 28 28 * the values of these registers are the same. And, the corresponding 29 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 34 * 1. Now I am running with EIP = <physical address> + PAGE_OFFSET. 35 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 37 * epilog. 38 38 */ 39 39 movl $1f, %edx
+79
drivers/firmware/efi/efi.c
··· 41 41 }; 42 42 EXPORT_SYMBOL(efi); 43 43 44 + static bool disable_runtime; 45 + static int __init setup_noefi(char *arg) 46 + { 47 + disable_runtime = true; 48 + return 0; 49 + } 50 + early_param("noefi", setup_noefi); 51 + 52 + bool efi_runtime_disabled(void) 53 + { 54 + return disable_runtime; 55 + } 56 + 57 + static int __init parse_efi_cmdline(char *str) 58 + { 59 + if (parse_option_str(str, "noruntime")) 60 + disable_runtime = true; 61 + 62 + return 0; 63 + } 64 + early_param("efi", parse_efi_cmdline); 65 + 44 66 static struct kobject *efi_kobj; 45 67 static struct kobject *efivars_kobj; 46 68 ··· 445 423 return ret; 446 424 } 447 425 #endif /* CONFIG_EFI_PARAMS_FROM_FDT */ 426 + 427 + static __initdata char memory_type_name[][20] = { 428 + "Reserved", 429 + "Loader Code", 430 + "Loader Data", 431 + "Boot Code", 432 + "Boot Data", 433 + "Runtime Code", 434 + "Runtime Data", 435 + "Conventional Memory", 436 + "Unusable Memory", 437 + "ACPI Reclaim Memory", 438 + "ACPI Memory NVS", 439 + "Memory Mapped I/O", 440 + "MMIO Port Space", 441 + "PAL Code" 442 + }; 443 + 444 + char * __init efi_md_typeattr_format(char *buf, size_t size, 445 + const efi_memory_desc_t *md) 446 + { 447 + char *pos; 448 + int type_len; 449 + u64 attr; 450 + 451 + pos = buf; 452 + if (md->type >= ARRAY_SIZE(memory_type_name)) 453 + type_len = snprintf(pos, size, "[type=%u", md->type); 454 + else 455 + type_len = snprintf(pos, size, "[%-*s", 456 + (int)(sizeof(memory_type_name[0]) - 1), 457 + memory_type_name[md->type]); 458 + if (type_len >= size) 459 + return buf; 460 + 461 + pos += type_len; 462 + size -= type_len; 463 + 464 + attr = md->attribute; 465 + if (attr & ~(EFI_MEMORY_UC | EFI_MEMORY_WC | EFI_MEMORY_WT | 466 + EFI_MEMORY_WB | EFI_MEMORY_UCE | EFI_MEMORY_WP | 467 + EFI_MEMORY_RP | EFI_MEMORY_XP | EFI_MEMORY_RUNTIME)) 468 + snprintf(pos, size, "|attr=0x%016llx]", 469 + (unsigned long long)attr); 470 + else 471 + snprintf(pos, size, "|%3s|%2s|%2s|%2s|%3s|%2s|%2s|%2s|%2s]", 472 + attr & EFI_MEMORY_RUNTIME ? "RUN" : "", 473 + attr & EFI_MEMORY_XP ? "XP" : "", 474 + attr & EFI_MEMORY_RP ? "RP" : "", 475 + attr & EFI_MEMORY_WP ? "WP" : "", 476 + attr & EFI_MEMORY_UCE ? "UCE" : "", 477 + attr & EFI_MEMORY_WB ? "WB" : "", 478 + attr & EFI_MEMORY_WT ? "WT" : "", 479 + attr & EFI_MEMORY_WC ? "WC" : "", 480 + attr & EFI_MEMORY_UC ? "UC" : ""); 481 + return buf; 482 + }
+4
drivers/firmware/efi/libstub/arm-stub.c
··· 226 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 234 * Unauthenticated device tree data is a security hazard, so 231 235 * ignore 'dtb=' unless UEFI Secure Boot is disabled.
+60 -2
drivers/firmware/efi/libstub/efi-stub-helper.c
··· 15 15 16 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 31 #define EFI_READ_CHUNK_SIZE (1024 * 1024) 32 + 33 + static unsigned long __chunk_size = EFI_READ_CHUNK_SIZE; 19 34 20 35 struct file_info { 21 36 efi_file_handle_t *handle; ··· 296 281 efi_call_early(free_pages, addr, nr_pages); 297 282 } 298 283 284 + /* 285 + * Parse the ASCII string 'cmdline' for EFI options, denoted by the efi= 286 + * option, e.g. efi=nochunk. 287 + * 288 + * It should be noted that efi= is parsed in two very different 289 + * environments, first in the early boot environment of the EFI boot 290 + * stub, and subsequently during the kernel boot. 291 + */ 292 + efi_status_t efi_parse_options(char *cmdline) 293 + { 294 + char *str; 295 + 296 + /* 297 + * If no EFI parameters were specified on the cmdline we've got 298 + * nothing to do. 299 + */ 300 + str = strstr(cmdline, "efi="); 301 + if (!str) 302 + return EFI_SUCCESS; 303 + 304 + /* Skip ahead to first argument */ 305 + str += strlen("efi="); 306 + 307 + /* 308 + * Remember, because efi= is also used by the kernel we need to 309 + * skip over arguments we don't understand. 310 + */ 311 + while (*str) { 312 + if (!strncmp(str, "nochunk", 7)) { 313 + str += strlen("nochunk"); 314 + __chunk_size = -1UL; 315 + } 316 + 317 + /* Group words together, delimited by "," */ 318 + while (*str && *str != ',') 319 + str++; 320 + 321 + if (*str == ',') 322 + str++; 323 + } 324 + 325 + return EFI_SUCCESS; 326 + } 299 327 300 328 /* 301 329 * Check the cmdline for a LILO-style file= arguments. ··· 481 423 size = files[j].size; 482 424 while (size) { 483 425 unsigned long chunksize; 484 - if (size > EFI_READ_CHUNK_SIZE) 485 - chunksize = EFI_READ_CHUNK_SIZE; 426 + if (size > __chunk_size) 427 + chunksize = __chunk_size; 486 428 else 487 429 chunksize = size; 488 430
+154 -10
drivers/firmware/efi/runtime-wrappers.c
··· 14 14 * This file is released under the GPLv2. 15 15 */ 16 16 17 + #include <linux/bug.h> 17 18 #include <linux/efi.h> 18 - #include <linux/spinlock.h> /* spinlock_t */ 19 + #include <linux/mutex.h> 20 + #include <linux/spinlock.h> 19 21 #include <asm/efi.h> 22 + 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 + */ 62 + static 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 + */ 20 89 21 90 /* 22 91 * As per commit ef68c8f87ed1 ("x86: Serialize EFI time accesses on rtc_lock"), ··· 101 32 efi_status_t status; 102 33 103 34 spin_lock_irqsave(&rtc_lock, flags); 35 + spin_lock(&efi_runtime_lock); 104 36 status = efi_call_virt(get_time, tm, tc); 37 + spin_unlock(&efi_runtime_lock); 105 38 spin_unlock_irqrestore(&rtc_lock, flags); 106 39 return status; 107 40 } ··· 114 43 efi_status_t status; 115 44 116 45 spin_lock_irqsave(&rtc_lock, flags); 46 + spin_lock(&efi_runtime_lock); 117 47 status = efi_call_virt(set_time, tm); 48 + spin_unlock(&efi_runtime_lock); 118 49 spin_unlock_irqrestore(&rtc_lock, flags); 119 50 return status; 120 51 } ··· 129 56 efi_status_t status; 130 57 131 58 spin_lock_irqsave(&rtc_lock, flags); 59 + spin_lock(&efi_runtime_lock); 132 60 status = efi_call_virt(get_wakeup_time, enabled, pending, tm); 61 + spin_unlock(&efi_runtime_lock); 133 62 spin_unlock_irqrestore(&rtc_lock, flags); 134 63 return status; 135 64 } ··· 142 67 efi_status_t status; 143 68 144 69 spin_lock_irqsave(&rtc_lock, flags); 70 + spin_lock(&efi_runtime_lock); 145 71 status = efi_call_virt(set_wakeup_time, enabled, tm); 72 + spin_unlock(&efi_runtime_lock); 146 73 spin_unlock_irqrestore(&rtc_lock, flags); 147 74 return status; 148 75 } ··· 155 78 unsigned long *data_size, 156 79 void *data) 157 80 { 158 - return efi_call_virt(get_variable, name, vendor, attr, data_size, data); 81 + unsigned long flags; 82 + efi_status_t status; 83 + 84 + spin_lock_irqsave(&efi_runtime_lock, flags); 85 + status = efi_call_virt(get_variable, name, vendor, attr, data_size, 86 + data); 87 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 88 + return status; 159 89 } 160 90 161 91 static efi_status_t virt_efi_get_next_variable(unsigned long *name_size, 162 92 efi_char16_t *name, 163 93 efi_guid_t *vendor) 164 94 { 165 - return efi_call_virt(get_next_variable, name_size, name, vendor); 95 + unsigned long flags; 96 + efi_status_t status; 97 + 98 + spin_lock_irqsave(&efi_runtime_lock, flags); 99 + status = efi_call_virt(get_next_variable, name_size, name, vendor); 100 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 101 + return status; 166 102 } 167 103 168 104 static efi_status_t virt_efi_set_variable(efi_char16_t *name, ··· 184 94 unsigned long data_size, 185 95 void *data) 186 96 { 187 - return efi_call_virt(set_variable, name, vendor, attr, data_size, data); 97 + unsigned long flags; 98 + efi_status_t status; 99 + 100 + spin_lock_irqsave(&efi_runtime_lock, flags); 101 + status = efi_call_virt(set_variable, name, vendor, attr, data_size, 102 + data); 103 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 104 + return status; 188 105 } 106 + 107 + static efi_status_t 108 + virt_efi_set_variable_nonblocking(efi_char16_t *name, efi_guid_t *vendor, 109 + u32 attr, unsigned long data_size, 110 + void *data) 111 + { 112 + unsigned long flags; 113 + efi_status_t status; 114 + 115 + if (!spin_trylock_irqsave(&efi_runtime_lock, flags)) 116 + return EFI_NOT_READY; 117 + 118 + status = efi_call_virt(set_variable, name, vendor, attr, data_size, 119 + data); 120 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 121 + return status; 122 + } 123 + 189 124 190 125 static efi_status_t virt_efi_query_variable_info(u32 attr, 191 126 u64 *storage_space, 192 127 u64 *remaining_space, 193 128 u64 *max_variable_size) 194 129 { 130 + unsigned long flags; 131 + efi_status_t status; 132 + 195 133 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 196 134 return EFI_UNSUPPORTED; 197 135 198 - return efi_call_virt(query_variable_info, attr, storage_space, 199 - remaining_space, max_variable_size); 136 + spin_lock_irqsave(&efi_runtime_lock, flags); 137 + status = efi_call_virt(query_variable_info, attr, storage_space, 138 + remaining_space, max_variable_size); 139 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 140 + return status; 200 141 } 201 142 202 143 static efi_status_t virt_efi_get_next_high_mono_count(u32 *count) 203 144 { 204 - return efi_call_virt(get_next_high_mono_count, count); 145 + unsigned long flags; 146 + efi_status_t status; 147 + 148 + spin_lock_irqsave(&efi_runtime_lock, flags); 149 + status = efi_call_virt(get_next_high_mono_count, count); 150 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 151 + return status; 205 152 } 206 153 207 154 static void virt_efi_reset_system(int reset_type, ··· 246 119 unsigned long data_size, 247 120 efi_char16_t *data) 248 121 { 122 + unsigned long flags; 123 + 124 + spin_lock_irqsave(&efi_runtime_lock, flags); 249 125 __efi_call_virt(reset_system, reset_type, status, data_size, data); 126 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 250 127 } 251 128 252 129 static efi_status_t virt_efi_update_capsule(efi_capsule_header_t **capsules, 253 130 unsigned long count, 254 131 unsigned long sg_list) 255 132 { 133 + unsigned long flags; 134 + efi_status_t status; 135 + 256 136 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 257 137 return EFI_UNSUPPORTED; 258 138 259 - return efi_call_virt(update_capsule, capsules, count, sg_list); 139 + spin_lock_irqsave(&efi_runtime_lock, flags); 140 + status = efi_call_virt(update_capsule, capsules, count, sg_list); 141 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 142 + return status; 260 143 } 261 144 262 145 static efi_status_t virt_efi_query_capsule_caps(efi_capsule_header_t **capsules, ··· 274 137 u64 *max_size, 275 138 int *reset_type) 276 139 { 140 + unsigned long flags; 141 + efi_status_t status; 142 + 277 143 if (efi.runtime_version < EFI_2_00_SYSTEM_TABLE_REVISION) 278 144 return EFI_UNSUPPORTED; 279 145 280 - return efi_call_virt(query_capsule_caps, capsules, count, max_size, 281 - reset_type); 146 + spin_lock_irqsave(&efi_runtime_lock, flags); 147 + status = efi_call_virt(query_capsule_caps, capsules, count, max_size, 148 + reset_type); 149 + spin_unlock_irqrestore(&efi_runtime_lock, flags); 150 + return status; 282 151 } 283 152 284 153 void efi_native_runtime_setup(void) ··· 296 153 efi.get_variable = virt_efi_get_variable; 297 154 efi.get_next_variable = virt_efi_get_next_variable; 298 155 efi.set_variable = virt_efi_set_variable; 156 + efi.set_variable_nonblocking = virt_efi_set_variable_nonblocking; 299 157 efi.get_next_high_mono_count = virt_efi_get_next_high_mono_count; 300 158 efi.reset_system = virt_efi_reset_system; 301 159 efi.query_variable_info = virt_efi_query_variable_info;
+54 -7
drivers/firmware/efi/vars.c
··· 321 321 * Print a warning when duplicate EFI variables are encountered and 322 322 * disable the sysfs workqueue since the firmware is buggy. 323 323 */ 324 - static void dup_variable_bug(efi_char16_t *s16, efi_guid_t *vendor_guid, 324 + static void dup_variable_bug(efi_char16_t *str16, efi_guid_t *vendor_guid, 325 325 unsigned long len16) 326 326 { 327 327 size_t i, len8 = len16 / sizeof(efi_char16_t); 328 - char *s8; 328 + char *str8; 329 329 330 330 /* 331 331 * Disable the workqueue since the algorithm it uses for ··· 334 334 */ 335 335 efivar_wq_enabled = false; 336 336 337 - s8 = kzalloc(len8, GFP_KERNEL); 338 - if (!s8) 337 + str8 = kzalloc(len8, GFP_KERNEL); 338 + if (!str8) 339 339 return; 340 340 341 341 for (i = 0; i < len8; i++) 342 - s8[i] = s16[i]; 342 + str8[i] = str16[i]; 343 343 344 344 printk(KERN_WARNING "efivars: duplicate variable: %s-%pUl\n", 345 - s8, vendor_guid); 346 - kfree(s8); 345 + str8, vendor_guid); 346 + kfree(str8); 347 347 } 348 348 349 349 /** ··· 595 595 } 596 596 EXPORT_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 + */ 607 + static int 608 + efivar_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 632 * efivar_entry_set_safe - call set_variable() if enough space in firmware 600 633 * @name: buffer containing the variable name ··· 654 621 655 622 if (!ops->query_variable_store) 656 623 return -ENOSYS; 624 + 625 + /* 626 + * If the EFI variable backend provides a non-blocking 627 + * ->set_variable() operation and we're in a context where we 628 + * cannot block, then we need to use it to avoid live-locks, 629 + * since the implication is that the regular ->set_variable() 630 + * will block. 631 + * 632 + * If no ->set_variable_nonblocking() is provided then 633 + * ->set_variable() is assumed to be non-blocking. 634 + */ 635 + if (!block && ops->set_variable_nonblocking) 636 + return efivar_entry_set_nonblocking(name, vendor, attributes, 637 + size, data); 657 638 658 639 if (!block) { 659 640 if (!spin_trylock_irqsave(&__efivars->lock, flags))
+1 -1
drivers/rtc/Kconfig
··· 830 830 831 831 config RTC_DRV_EFI 832 832 tristate "EFI RTC" 833 - depends on EFI 833 + depends on EFI && !X86 834 834 help 835 835 If you say yes here you will get support for the EFI 836 836 Real Time Clock.
+1
drivers/rtc/rtc-efi.c
··· 236 236 MODULE_AUTHOR("dann frazier <dannf@hp.com>"); 237 237 MODULE_LICENSE("GPL"); 238 238 MODULE_DESCRIPTION("EFI RTC driver"); 239 + MODULE_ALIAS("platform:rtc-efi");
+17
include/linux/efi.h
··· 92 92 #define EFI_MEMORY_WC ((u64)0x0000000000000002ULL) /* write-coalescing */ 93 93 #define EFI_MEMORY_WT ((u64)0x0000000000000004ULL) /* write-through */ 94 94 #define EFI_MEMORY_WB ((u64)0x0000000000000008ULL) /* write-back */ 95 + #define EFI_MEMORY_UCE ((u64)0x0000000000000010ULL) /* uncached, exported */ 95 96 #define EFI_MEMORY_WP ((u64)0x0000000000001000ULL) /* write-protect */ 96 97 #define EFI_MEMORY_RP ((u64)0x0000000000002000ULL) /* read-protect */ 97 98 #define EFI_MEMORY_XP ((u64)0x0000000000004000ULL) /* execute-protect */ ··· 503 502 typedef efi_status_t efi_set_variable_t (efi_char16_t *name, efi_guid_t *vendor, 504 503 u32 attr, unsigned long data_size, 505 504 void *data); 505 + typedef efi_status_t 506 + efi_set_variable_nonblocking_t(efi_char16_t *name, efi_guid_t *vendor, 507 + u32 attr, unsigned long data_size, void *data); 508 + 506 509 typedef efi_status_t efi_get_next_high_mono_count_t (u32 *count); 507 510 typedef void efi_reset_system_t (int reset_type, efi_status_t status, 508 511 unsigned long data_size, efi_char16_t *data); ··· 826 821 efi_get_variable_t *get_variable; 827 822 efi_get_next_variable_t *get_next_variable; 828 823 efi_set_variable_t *set_variable; 824 + efi_set_variable_nonblocking_t *set_variable_nonblocking; 829 825 efi_query_variable_info_t *query_variable_info; 830 826 efi_update_capsule_t *update_capsule; 831 827 efi_query_capsule_caps_t *query_capsule_caps; ··· 891 885 for ((md) = (m)->map; \ 892 886 (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \ 893 887 (md) = (void *)(md) + (m)->desc_size) 888 + 889 + /* 890 + * Format an EFI memory descriptor's type and attributes to a user-provided 891 + * character buffer, as per snprintf(), and return the buffer. 892 + */ 893 + char * __init efi_md_typeattr_format(char *buf, size_t size, 894 + const efi_memory_desc_t *md); 894 895 895 896 /** 896 897 * efi_range_is_wc - check the WC bit on an address range ··· 1047 1034 efi_get_variable_t *get_variable; 1048 1035 efi_get_next_variable_t *get_next_variable; 1049 1036 efi_set_variable_t *set_variable; 1037 + efi_set_variable_nonblocking_t *set_variable_nonblocking; 1050 1038 efi_query_variable_store_t *query_variable_store; 1051 1039 }; 1052 1040 ··· 1241 1227 unsigned long *load_addr, 1242 1228 unsigned long *load_size); 1243 1229 1230 + efi_status_t efi_parse_options(char *cmdline); 1231 + 1232 + bool efi_runtime_disabled(void); 1244 1233 #endif /* _LINUX_EFI_H */
+1
include/linux/kernel.h
··· 403 403 extern int get_option(char **str, int *pint); 404 404 extern char *get_options(const char *str, int nints, int *ints); 405 405 extern unsigned long long memparse(const char *ptr, char **retptr); 406 + extern bool parse_option_str(const char *str, const char *option); 406 407 407 408 extern int core_kernel_text(unsigned long addr); 408 409 extern int core_kernel_data(unsigned long addr);
+29
lib/cmdline.c
··· 160 160 return ret; 161 161 } 162 162 EXPORT_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 + */ 174 + bool 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 + }