EFI changes for v4.9
Subsystems (6)
Linus,
Please pull the latest efi-core-for-linus git tree from:
git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git efi-core-for-linus
# HEAD: 2ab78a724b1fd885b65199707b8e053677745457 Merge tag 'efi-next' of git://git.kernel.org/pub/scm/linux/kernel/git/mfleming/efi into efi/core
Main changes in this cycle were:
- Refactor the EFI memory map code into architecture neutral files and allow drivers to permanently reserve EFI boot services regions on x86, as well as ARM/arm64. (Matt Fleming)
- Add ARM support for the EFI ESRT driver. (Ard Biesheuvel)
- Make the EFI runtime services and efivar API interruptible by swapping spinlocks for semaphores. (Sylvain Chouleur)
- Provide the EFI identity mapping for kexec which allows kexec to work on SGI/UV platforms with requiring the "noefi" kernel command line parameter. (Alex Thorlton)
- Add debugfs node to dump EFI page tables on arm64. (Ard Biesheuvel)
- Merge the EFI test driver being carried out of tree until now in the FWTS project. (Ivan Hu)
- Expand the list of flags for classifying EFI regions as "RAM" on arm64 so we align with the UEFI spec. (Ard Biesheuvel)
- Optimise out the EFI mixed mode if it's unsupported (CONFIG_X86_32) or disabled (CONFIG_EFI_MIXED=n) and switch the early EFI boot services function table for direct calls, alleviating us from having to maintain the custom function table. (Lukas Wunner)
- Miscellaneous cleanups and fixes
Thanks,
Ingo
------------------>
Alex Thorlton (1):
x86/efi: Map in physical addresses in efi_map_region_fixed
Ard Biesheuvel (5):
efi/esrt: Use memremap not ioremap to access ESRT table in memory efi/arm*: esrt: Add missing call to efi_esrt_init()
efi: Replace runtime services spinlock with semaphore efi/arm64: Add debugfs node to dump UEFI runtime page tables efi/arm64: Treat regions with WT/WC set but WB cleared as memory
Colin Ian King (1):
x86/efi: Initialize status to ensure garbage is not returned on small size
Ivan Hu (1):
efi: Add efi_test driver for exporting UEFI runtime service interfaces
Lukas Wunner (4):
lib/ucs2_string: Speed up ucs2_utf8size() x86/efi: Remove unused find_bits() function x86/efi: Optimize away setup_gop32/64 if unused x86/efi: Allow invocation of arbitrary boot services
Markus Elfring (2):
firmware-gsmi: Delete an unnecessary check before the function call "dma_pool_destroy" x86/efi: Use kmalloc_array() in efi_call_phys_prolog()
Matt Fleming (13):
x86/efi: Test for EFI_MEMMAP functionality when iterating EFI memmap x86/efi: Consolidate region mapping logic
efi: Refactor efi_memmap_init_early() into arch-neutral code
efi: Add efi_memmap_init_late() for permanent EFI memmap efi/fake_mem: Refactor main two code chunks into functions
efi: Split out EFI memory map functions into new file
efi: Add efi_memmap_install() for installing new EFI memory maps
efi: Allow drivers to reserve boot services forever efi/runtime-map: Use efi.memmap directly instead of a copy efi/esrt: Use efi_mem_reserve() and avoid a kmalloc() x86/efi-bgrt: Use efi_mem_reserve() to avoid copying image data fs/efivarfs: Fix double kfree() in error path
x86/efi: Round EFI memmap reservations to EFI_PAGE_SIZE
Ricardo Neri (1):
x86/efi: Defer efi_esrt_init until after memblock_x86_fill
Sylvain Chouleur (2):
efi: Use a file local lock for efivars
efi: Don't use spinlocks for efi vars
MAINTAINERS | 7 + arch/x86/boot/compressed/eboot.c | 40 +- arch/x86/boot/compressed/head_32.S | 6 +- arch/x86/boot/compressed/head_64.S | 8 +- arch/x86/include/asm/efi.h | 29 +- arch/x86/kernel/setup.c | 18 +- arch/x86/platform/efi/efi-bgrt.c | 13 +- arch/x86/platform/efi/efi.c | 198 ++++----- arch/x86/platform/efi/efi_64.c | 23 +- arch/x86/platform/efi/quirks.c | 127 +++++- drivers/firmware/efi/Kconfig | 17 + drivers/firmware/efi/Makefile | 3 +- drivers/firmware/efi/arm-init.c | 50 ++- drivers/firmware/efi/arm-runtime.c | 26 +- drivers/firmware/efi/efi-pstore.c | 36 +- drivers/firmware/efi/efi.c | 67 +-- drivers/firmware/efi/efivars.c | 22 +- drivers/firmware/efi/esrt.c | 23 +- drivers/firmware/efi/fake_mem.c | 125 +----- drivers/firmware/efi/memmap.c | 303 +++++++++++++ drivers/firmware/efi/runtime-map.c | 35 +- drivers/firmware/efi/runtime-wrappers.c | 81 ++-- drivers/firmware/efi/test/Makefile | 1 + drivers/firmware/efi/test/efi_test.c | 749 ++++++++++++++++++++++++++++++++ drivers/firmware/efi/test/efi_test.h | 110 +++++ drivers/firmware/efi/vars.c | 142 +++--- drivers/firmware/google/gsmi.c | 3 +- fs/efivarfs/inode.c | 5 +- fs/efivarfs/super.c | 13 +- include/linux/efi.h | 47 +- lib/ucs2_string.c | 2 +- 31 files changed, 1782 insertions(+), 547 deletions(-) create mode 100644 drivers/firmware/efi/memmap.c create mode 100644 drivers/firmware/efi/test/Makefile create mode 100644 drivers/firmware/efi/test/efi_test.c create mode 100644 drivers/firmware/efi/test/efi_test.h
MAINTAINERS +7 -0
@@ -4584,6 +4584,13 @@ M: Peter Jones <[email protected]> S: Maintained F: drivers/video/fbdev/efifb.c +EFI TEST DRIVER +L: [email protected] +M: Ivan Hu <[email protected]> +M: Matt Fleming <[email protected]> +S: Maintained +F: drivers/firmware/efi/test/ + EFS FILESYSTEM W: http://aeschi.ch.eu.org/efs/ S: Orphan
arch/x86/boot/compressed/eboot.c +3 -37
@@ -29,22 +29,11 @@ __pure const struct efi_config *__efi_early(void) static void setup_boot_services##bits(struct efi_config *c) \ { \ efi_system_table_##bits##_t *table; \ - efi_boot_services_##bits##_t *bt; \ \ table = (typeof(table))sys_table; \ \ + c->boot_services = table->boottime; \ c->text_output = table->con_out; \ - \ - bt = (typeof(bt))(unsigned long)(table->boottime); \ - \ - c->allocate_pool = bt->allocate_pool; \ - c->allocate_pages = bt->allocate_pages; \ - c->get_memory_map = bt->get_memory_map; \ - c->free_pool = bt->free_pool; \ - c->free_pages = bt->free_pages; \ - c->locate_handle = bt->locate_handle; \ - c->handle_protocol = bt->handle_protocol; \ - c->exit_boot_services = bt->exit_boot_services; \ }BOOT_SERVICES (32 );BOOT_SERVICES (64 );
@@ -286,29 +275,6 @@ void efi_char16_printk(efi_system_table_t *table, efi_char16_t *str) } } -static void find_bits (unsigned long mask,u8 *pos,u8 *size) -{ -u8 first, len; - - first =0 ; - len =0 ; - -if (mask) { -while (!(mask &0x1 )) { - mask = mask >>1 ; - first++; - } - -while (mask &0x1 ) { - mask = mask >>1 ; - len++; - } - } - - *pos = first; - *size = len; -} -static efi_status_t __setup_efi_pci32 (efi_pci_io_protocol_32 *pci,struct pci_setup_rom **__rom) {
@@ -578,7 +544,7 @@ setup_uga32(void **uga_handle, unsigned long size, u32 *width, u32 *height)efi_guid_t uga_proto =EFI_UGA_PROTOCOL_GUID ;unsigned long nr_ugas;u32 *handles = (u32 *)uga_handle;; -efi_status_t status; +efi_status_t status =EFI_INVALID_PARAMETER ;int i; first_uga =NULL ;
@@ -623,7 +589,7 @@ setup_uga64(void **uga_handle, unsigned long size, u32 *width, u32 *height)efi_guid_t uga_proto =EFI_UGA_PROTOCOL_GUID ;unsigned long nr_ugas;u64 *handles = (u64 *)uga_handle;; -efi_status_t status; +efi_status_t status =EFI_INVALID_PARAMETER ;int i; first_uga =NULL ;
arch/x86/boot/compressed/head_32.S +3 -3
@@ -82,7 +82,7 @@ ENTRY(efi_pe_entry) /* Relocate efi_config->call() */ leal efi32_config(%esi), %eax - add %esi, 88(%eax) + add %esi, 32(%eax) pushl %eax call make_boot_params
@@ -108,7 +108,7 @@ ENTRY(efi32_stub_entry) /* Relocate efi_config->call() */ leal efi32_config(%esi), %eax - add %esi, 88(%eax) + add %esi, 32(%eax) pushl %eax 2: call efi_main
@@ -264,7 +264,7 @@ ENDPROC(startup_32) #ifdef CONFIG_EFI_STUB .data efi32_config: - .fill 11,8,0 + .fill 4,8,0 .long efi_call_phys .long 0 .byte 0
arch/x86/boot/compressed/head_64.S +4 -4
@@ -265,7 +265,7 @@ ENTRY(efi_pe_entry) /* * Relocate efi_config->call(). */ - addq %rbp, efi64_config+88(%rip) + addq %rbp, efi64_config+32(%rip) movq %rax, %rdi call make_boot_params
@@ -285,7 +285,7 @@ ENTRY(efi_pe_entry) * Relocate efi_config->call(). */ movq efi_config(%rip), %rax - addq %rbp, 88(%rax) + addq %rbp, 32(%rax) 2: movq efi_config(%rip), %rdi call efi_main
@@ -457,14 +457,14 @@ ENDPROC(efi64_stub_entry) #ifdef CONFIG_EFI_MIXED .global efi32_config efi32_config: - .fill 11,8,0 + .fill 4,8,0 .quad efi64_thunk .byte 0 #endif .global efi64_config efi64_config: - .fill 11,8,0 + .fill 4,8,0 .quad efi_call .byte 1 #endif /* CONFIG_EFI_STUB */
arch/x86/include/asm/efi.h +17 -12
@@ -117,7 +117,6 @@ extern int __init efi_memblock_x86_reserve_range(void);extern pgd_t *__init efi_call_phys_prolog (void );extern void __init efi_call_phys_epilog (pgd_t *save_pgd);extern void __init efi_print_memmap (void ); -extern void __init efi_unmap_memmap (void );extern void __init efi_memory_uc (u64 addr,unsigned long size);extern void __init efi_map_region (efi_memory_desc_t *md);extern void __init efi_map_region_fixed (efi_memory_desc_t *md);
@@ -192,14 +191,7 @@ static inline efi_status_t efi_thunk_set_virtual_address_map(struct efi_config {u64 image_handle;u64 table; -u64 allocate_pool; -u64 allocate_pages; -u64 get_memory_map; -u64 free_pool; -u64 free_pages; -u64 locate_handle; -u64 handle_protocol; -u64 exit_boot_services; +u64 boot_services;u64 text_output;efi_status_t (*call)(unsigned long , ...);bool is64;
@@ -207,14 +199,27 @@ struct efi_config {__pure const struct efi_config *__efi_early (void ); +static inline bool efi_is_64bit (void ) +{ +if (!IS_ENABLED (CONFIG_X86_64 )) +return false; + +if (!IS_ENABLED (CONFIG_EFI_MIXED )) +return true; + +return __efi_early ()->is64; +} +#define efi_call_early (f, ...) \ - __efi_early()->call(__efi_early()->f, __VA_ARGS__); + __efi_early()->call(efi_is_64bit() ? \ + ((efi_boot_services_64_t *)(unsigned long) \ + __efi_early()->boot_services)->f : \ + ((efi_boot_services_32_t *)(unsigned long) \ + __efi_early()->boot_services)->f, __VA_ARGS__)#define __efi_call_early (f, ...) \ __efi_early()->call((unsigned long)f, __VA_ARGS__); -#define efi_is_64bit () __efi_early()->is64 -extern bool efi_reboot_required (void );#else
arch/x86/kernel/setup.c +9 -9
@@ -1096,19 +1096,19 @@ void __init setup_arch(char **cmdline_p)memblock_set_current_limit (ISA_END_ADDRESS );memblock_x86_fill (); -if (efi_enabled (EFI_BOOT )) { +reserve_bios_regions (); + +if (efi_enabled (EFI_MEMMAP )) {efi_fake_memmap ();efi_find_mirror (); - } - -reserve_bios_regions (); +efi_esrt_init (); -/* -* The EFI specification says that boot service code won't be called -* after ExitBootServices(). This is, in fact, a lie. -*/ -if (efi_enabled (EFI_MEMMAP )) +/* +* The EFI specification says that boot service code won't be +* called after ExitBootServices(). This is, in fact, a lie. +*/ efi_reserve_boot_services (); + }/* preallocate 4k for mptable mpc */ early_reserve_e820_mpc_new ();
arch/x86/platform/efi/efi-bgrt.c +2 -11
@@ -82,21 +82,12 @@ void __init efi_bgrt_init(void) } bgrt_image_size = bmp_header.size; - bgrt_image =kmalloc (bgrt_image_size,GFP_KERNEL | __GFP_NOWARN); + bgrt_image =memremap (bgrt_tab->image_address, bmp_header.size,MEMREMAP_WB );if (!bgrt_image) { -pr_notice ("Ignoring BGRT: failed to allocate memory for image (wanted %zu bytes)\n" , - bgrt_image_size); -return ; - } - - image =memremap (bgrt_tab->image_address, bmp_header.size,MEMREMAP_WB ); -if (!image) {pr_notice ("Ignoring BGRT: failed to map image memory\n" ); -kfree (bgrt_image); bgrt_image =NULL ;return ; } -memcpy (bgrt_image, image, bgrt_image_size); -memunmap (image); +efi_mem_reserve (bgrt_tab->image_address, bgrt_image_size); }
arch/x86/platform/efi/efi.c +90 -108
297 lines not on this page · raw message
arch/x86/platform/efi/efi_64.c +2 -21
@@ -85,7 +85,7 @@ pgd_t * __init efi_call_phys_prolog(void)early_code_mapping_set_exec (1 ); n_pgds =DIV_ROUND_UP ((max_pfn <<PAGE_SHIFT ),PGDIR_SIZE ); - save_pgd =kmalloc (n_pgds *sizeof (pgd_t),GFP_KERNEL ); + save_pgd =kmalloc_array (n_pgds,sizeof (*save_pgd),GFP_KERNEL );for (pgd =0 ; pgd < n_pgds; pgd++) { save_pgd[pgd] = *pgd_offset_k (pgd *PGDIR_SIZE );
@@ -214,7 +214,6 @@ void efi_sync_low_kernel_mappings(void)int __init efi_setup_page_tables (unsigned long pa_memmap,unsigned num_pages) {unsigned long pfn, text; -efi_memory_desc_t *md;struct page *page;unsigned npages;pgd_t *pgd;
@@ -248,25 +247,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)if (!IS_ENABLED (CONFIG_EFI_MIXED ) ||efi_is_native ())return 0 ; -/* -* Map all of RAM so that we can access arguments in the 1:1 -* mapping when making EFI runtime calls. -*/ -for_each_efi_memory_desc (md) { -if (md->type !=EFI_CONVENTIONAL_MEMORY && - md->type !=EFI_LOADER_DATA && - md->type !=EFI_LOADER_CODE ) -continue ; - - pfn = md->phys_addr >>PAGE_SHIFT ; - npages = md->num_pages; - -if (kernel_map_pages_in_pgd (pgd, pfn, md->phys_addr, npages, _PAGE_RW)) { -pr_err ("Failed to map 1:1 memory\n" ); -return 1 ; - } - } - page =alloc_page (GFP_KERNEL |__GFP_DMA32);if (!page)panic ("Unable to allocate EFI runtime stack < 4GB\n" );
@@ -359,6 +339,7 @@ void __init efi_map_region(efi_memory_desc_t *md)*/ void __init efi_map_region_fixed (efi_memory_desc_t *md) { +__map_region (md, md->phys_addr);__map_region (md, md->virt_addr); }
arch/x86/platform/efi/quirks.c +114 -13
168 lines not on this page · raw message
drivers/firmware/efi/Kconfig +17 -0
@@ -112,6 +112,23 @@ config EFI_CAPSULE_LOADER Most users should say N. +config EFI_TEST + tristate "EFI Runtime Service Tests Support" + depends on EFI + default n + help + This driver uses the efi.<service> function pointers directly instead + of going through the efivar API, because it is not trying to test the + kernel subsystem, just for testing the UEFI runtime service + interfaces which are provided by the firmware. This driver is used + by the Firmware Test Suite (FWTS) for testing the UEFI runtime + interfaces readiness of the firmware. + Details for FWTS are available from: + <https://wiki.ubuntu.com/FirmwareTestSuite> + + Say Y here to enable the runtime services support via /dev/efi_test. + If unsure, say N. + endmenu config UEFI_CPER
drivers/firmware/efi/Makefile +2 -1
@@ -10,7 +10,7 @@ KASAN_SANITIZE_runtime-wrappers.o := n obj-$(CONFIG_EFI) += efi.o vars.o reboot.o memattr.o -obj-$(CONFIG_EFI) += capsule.o +obj-$(CONFIG_EFI) += capsule.o memmap.o obj-$(CONFIG_EFI_VARS) += efivars.o obj-$(CONFIG_EFI_ESRT) += esrt.o obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o
@@ -20,6 +20,7 @@ obj-$(CONFIG_EFI_RUNTIME_WRAPPERS) += runtime-wrappers.o obj-$(CONFIG_EFI_STUB) += libstub/ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_mem.o obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o +obj-$(CONFIG_EFI_TEST) += test/ arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o obj-$(CONFIG_ARM) += $(arm-obj-y)
drivers/firmware/efi/arm-init.c +26 -24
119 lines not on this page · raw message
drivers/firmware/efi/arm-runtime.c +22 -4
@@ -39,6 +39,26 @@ static struct mm_struct efi_mm = { .mmlist = LIST_HEAD_INIT(efi_mm.mmlist), }; +#ifdef CONFIG_ARM64_PTDUMP +#include <asm/ptdump.h> + +static struct ptdump_info efi_ptdump_info = { + .mm = &efi_mm, + .markers = (struct addr_marker []){ + {0 ,"UEFI runtime start" }, + {TASK_SIZE_64 ,"UEFI runtime end" } + }, + .base_addr =0 , +}; + +static int __init ptdump_init (void ) +{ +return ptdump_register (&efi_ptdump_info,"efi_page_tables" ); +} +device_initcall (ptdump_init); + +#endif +static bool __init efi_virtmap_init (void ) {efi_memory_desc_t *md;
@@ -114,14 +134,12 @@ static int __init arm_enable_runtime_services(void)pr_info ("Remapping and enabling EFI services.\n" ); - mapsize = efi.memmap.map_end - efi.memmap.map; + mapsize = efi.memmap.desc_size * efi.memmap.nr_map; - efi.memmap.map =memremap (efi.memmap.phys_map, mapsize,MEMREMAP_WB ); -if (!efi.memmap.map) { +if (efi_memmap_init_late (efi.memmap.phys_map, mapsize)) {pr_err ("Failed to remap EFI memory map\n" );return -ENOMEM ; } - efi.memmap.map_end = efi.memmap.map + mapsize;if (!efi_virtmap_init ()) {pr_err ("UEFI virtual mapping missing or invalid -- runtime services will not be available\n" );
drivers/firmware/efi/efi-pstore.c +27 -9
@@ -125,16 +125,19 @@ static void efi_pstore_scan_sysfs_enter(struct efivar_entry *pos,* @entry: deleting entry * @turn_off_scanning: Check if a scanning flag should be turned off */ -static inline void __efi_pstore_scan_sysfs_exit (struct efivar_entry *entry, +static inline int __efi_pstore_scan_sysfs_exit (struct efivar_entry *entry,bool turn_off_scanning) {if (entry->deleting) {list_del (&entry->list);efivar_entry_iter_end ();efivar_unregister (entry); -efivar_entry_iter_begin (); +if (efivar_entry_iter_begin ()) +return -EINTR ; }else if (turn_off_scanning) entry->scanning = false; + +return 0 ; }/**
@@ -144,13 +147,18 @@ static inline void __efi_pstore_scan_sysfs_exit(struct efivar_entry *entry,* @head: list head * @stop: a flag checking if scanning will stop */ -static void efi_pstore_scan_sysfs_exit (struct efivar_entry *pos, +static int efi_pstore_scan_sysfs_exit (struct efivar_entry *pos,struct efivar_entry *next,struct list_head *head,bool stop) { -__efi_pstore_scan_sysfs_exit (pos, true); +int ret =__efi_pstore_scan_sysfs_exit (pos, true); + +if (ret) +return ret; +if (stop) -__efi_pstore_scan_sysfs_exit (next, &next->list != head); + ret =__efi_pstore_scan_sysfs_exit (next, &next->list != head); +return ret; }/**
@@ -172,13 +180,17 @@ static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)struct efivar_entry *entry, *n;struct list_head *head = &efivar_sysfs_list;int size =0 ; +int ret;if (!*pos) {list_for_each_entry_safe (entry, n, head, list) {efi_pstore_scan_sysfs_enter (entry, n, head); size =efi_pstore_read_func (entry, data); -efi_pstore_scan_sysfs_exit (entry, n, head, size <0 ); + ret =efi_pstore_scan_sysfs_exit (entry, n, head, + size <0 ); +if (ret) +return ret;if (size)break ; }
@@ -190,7 +202,9 @@ static int efi_pstore_sysfs_entry_iter(void *data, struct efivar_entry **pos)efi_pstore_scan_sysfs_enter ((*pos), n, head); size =efi_pstore_read_func ((*pos), data); -efi_pstore_scan_sysfs_exit ((*pos), n, head, size <0 ); + ret =efi_pstore_scan_sysfs_exit ((*pos), n, head, size <0 ); +if (ret) +return ret;if (size)break ; }
@@ -232,7 +246,10 @@ static ssize_t efi_pstore_read(u64 *id, enum pstore_type_id *type,if (!*data.buf)return -ENOMEM ; -efivar_entry_iter_begin (); +if (efivar_entry_iter_begin ()) { +kfree (*data.buf); +return -EINTR ; + } size =efi_pstore_sysfs_entry_iter (&data, (struct efivar_entry **)&psi->data);efivar_entry_iter_end ();
@@ -347,7 +364,8 @@ static int efi_pstore_erase(enum pstore_type_id type, u64 id, int count, edata.time = time; edata.name = efi_name; -efivar_entry_iter_begin (); +if (efivar_entry_iter_begin ()) +return -EINTR ; found =__efivar_entry_iter (efi_pstore_erase_func, &efivar_sysfs_list, &edata, &entry);if (found && !entry->scanning) {
drivers/firmware/efi/efi.c +36 -31
121 lines not on this page · raw message
drivers/firmware/efi/efivars.c +18 -4
@@ -510,7 +510,8 @@ static ssize_t efivar_delete(struct file *filp, struct kobject *kobj, vendor = del_var->VendorGuid; } -efivar_entry_iter_begin (); +if (efivar_entry_iter_begin ()) +return -EINTR ; entry =efivar_entry_find (name, vendor, &efivar_sysfs_list, true);if (!entry) err = -EINVAL ;
@@ -575,7 +576,10 @@ efivar_create_sysfs_entry(struct efivar_entry *new_var)return ret;kobject_uevent (&new_var->kobj,KOBJ_ADD ); -efivar_entry_add (new_var, &efivar_sysfs_list); +if (efivar_entry_add (new_var, &efivar_sysfs_list)) { +efivar_unregister (new_var); +return -EINTR ; + }return 0 ; }
@@ -690,7 +694,10 @@ static int efivars_sysfs_callback(efi_char16_t *name, efi_guid_t vendor,static int efivar_sysfs_destroy (struct efivar_entry *entry,void *data) { -efivar_entry_remove (entry); +int err =efivar_entry_remove (entry); + +if (err) +return err;efivar_unregister (entry);return 0 ; }
@@ -698,7 +705,14 @@ static int efivar_sysfs_destroy(struct efivar_entry *entry, void *data)static void efivars_sysfs_exit (void ) {/* Remove all entries and destroy */ -__efivar_entry_iter (efivar_sysfs_destroy, &efivar_sysfs_list,NULL ,NULL ); +int err; + + err =__efivar_entry_iter (efivar_sysfs_destroy, &efivar_sysfs_list, +NULL ,NULL ); +if (err) { +pr_err ("efivars: Failed to destroy sysfs entries\n" ); +return ; + }if (efivars_new_var)sysfs_remove_bin_file (&efivars_kset->kobj, efivars_new_var);
drivers/firmware/efi/esrt.c +6 -17
@@ -16,6 +16,7 @@#include <linux/device.h> #include <linux/efi.h> #include <linux/init.h> +#include <linux/io.h> #include <linux/kernel.h> #include <linux/kobject.h> #include <linux/list.h>
@@ -235,7 +236,7 @@ static struct attribute_group esrt_attr_group = { };/* -* remap the table, copy it to kmalloced pages, and unmap it. +* remap the table, validate it, mark it reserved and unmap it. */ void __init efi_esrt_init (void ) {
@@ -335,7 +336,7 @@ void __init efi_esrt_init(void) end = esrt_data + size;pr_info ("Reserving ESRT space from %pa to %pa.\n" , &esrt_data, &end); -memblock_reserve (esrt_data, esrt_data_size); +efi_mem_reserve (esrt_data, esrt_data_size);pr_debug ("esrt-init: loaded.\n" ); err_memunmap:
@@ -382,28 +383,18 @@ static void cleanup_entry_list(void)static int __init esrt_sysfs_init (void ) {int error; -struct efi_system_resource_table __iomem *ioesrt;pr_debug ("esrt-sysfs: loading.\n" );if (!esrt_data || !esrt_data_size)return -ENOSYS ; - ioesrt =ioremap (esrt_data, esrt_data_size); -if (!ioesrt) { -pr_err ("ioremap(%pa, %zu) failed.\n" , &esrt_data, - esrt_data_size); -return -ENOMEM ; - } - - esrt =kmalloc (esrt_data_size,GFP_KERNEL ); + esrt =memremap (esrt_data, esrt_data_size,MEMREMAP_WB );if (!esrt) { -pr_err ("kmalloc failed. (wanted %zu bytes)\n" , esrt_data_size); -iounmap (ioesrt); +pr_err ("memremap(%pa, %zu) failed.\n" , &esrt_data, + esrt_data_size);return -ENOMEM ; } -memcpy_fromio (esrt, ioesrt, esrt_data_size); - esrt_kobj =kobject_create_and_add ("esrt" , efi_kobj);if (!esrt_kobj) {pr_err ("Firmware table registration failed.\n" );
@@ -429,8 +420,6 @@ static int __init esrt_sysfs_init(void)if (error) goto err_cleanup_list; -memblock_remove (esrt_data, esrt_data_size); -pr_debug ("esrt-sysfs: loaded.\n" );return 0 ;
drivers/firmware/efi/fake_mem.c +15 -110
164 lines not on this page · raw message
drivers/firmware/efi/memmap.c new file +303 -0
303 lines not on this page · raw message
drivers/firmware/efi/runtime-map.c +13 -22
@@ -14,10 +14,6 @@#include <asm/setup.h> -static void *efi_runtime_map; -static int nr_efi_runtime_map; -static u32 efi_memdesc_size; -struct efi_runtime_map_entry {efi_memory_desc_t md;struct kobject kobj;/* kobject for each entry */
@@ -106,7 +102,8 @@ static struct kobj_type __refdata map_ktype = {static struct kset *map_kset;static struct efi_runtime_map_entry * -add_sysfs_runtime_map_entry (struct kobject *kobj,int nr) +add_sysfs_runtime_map_entry (struct kobject *kobj,int nr, +efi_memory_desc_t *md) {int ret;struct efi_runtime_map_entry *entry;
@@ -124,8 +121,7 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)return ERR_PTR (-ENOMEM ); } -memcpy (&entry->md, efi_runtime_map + nr * efi_memdesc_size, -sizeof (efi_memory_desc_t)); +memcpy (&entry->md, md,sizeof (efi_memory_desc_t));kobject_init (&entry->kobj, &map_ktype); entry->kobj.kset = map_kset;
@@ -142,12 +138,12 @@ add_sysfs_runtime_map_entry(struct kobject *kobj, int nr)int efi_get_runtime_map_size (void ) { -return nr_efi_runtime_map * efi_memdesc_size; +return efi.memmap.nr_map * efi.memmap.desc_size; }int efi_get_runtime_map_desc_size (void ) { -return efi_memdesc_size; +return efi.memmap.desc_size; }int efi_runtime_map_copy (void *buf,size_t bufsz)
@@ -157,38 +153,33 @@ int efi_runtime_map_copy(void *buf, size_t bufsz)if (sz > bufsz) sz = bufsz; -memcpy (buf, efi_runtime_map, sz); +memcpy (buf, efi.memmap.map, sz);return 0 ; } -void efi_runtime_map_setup (void *map,int nr_entries,u32 desc_size) -{ - efi_runtime_map = map; - nr_efi_runtime_map = nr_entries; - efi_memdesc_size = desc_size; -} -int __init efi_runtime_map_init (struct kobject *efi_kobj) {int i, j, ret =0 ;struct efi_runtime_map_entry *entry; +efi_memory_desc_t *md; -if (!efi_runtime_map) +if (!efi_enabled (EFI_MEMMAP ))return 0 ; - map_entries =kzalloc (nr_efi_runtime_map *sizeof (entry),GFP_KERNEL ); + map_entries =kzalloc (efi.memmap.nr_map *sizeof (entry),GFP_KERNEL );if (!map_entries) { ret = -ENOMEM ; goto out; } -for (i =0 ; i < nr_efi_runtime_map; i++) { - entry =add_sysfs_runtime_map_entry (efi_kobj, i); + i =0 ; +for_each_efi_memory_desc (md) { + entry =add_sysfs_runtime_map_entry (efi_kobj, i, md);if (IS_ERR (entry)) { ret =PTR_ERR (entry); goto out_add_entry; } - *(map_entries + i) = entry; + *(map_entries + i++) = entry; }return 0 ;
drivers/firmware/efi/runtime-wrappers.c +49 -32
207 lines not on this page · raw message
drivers/firmware/efi/test/Makefile new file +1 -0
@@ -0,0 +1 @@ +obj-$(CONFIG_EFI_TEST) += efi_test.o
drivers/firmware/efi/test/efi_test.c new file +749 -0
749 lines not on this page · raw message
drivers/firmware/efi/test/efi_test.h new file +110 -0
110 lines not on this page · raw message
drivers/firmware/efi/vars.c +88 -54
108 lines not on this page · raw message
include/linux/efi.h +34 -13
47 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Part of the diff is not shown here. View the raw message.