EFI changes for v4.6
Subsystems (5)
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: d367cef0a7f0c6ee86e997c0cb455b21b3c6b9ba x86/mm/pat: Fix boot crash when 1GB pages are not supported by the CPU
The main changes are:
- Use separate EFI page tables when executing EFI firmware code. This isolates the EFI context from the rest of the kernel, which has security and general robustness advantages. (Matt Fleming)
- Run regular UEFI firmware with interrupts enabled. This is already the status quo under other OSs. (Ard Biesheuvel)
- Various x86 EFI enhancements, such as the use of non-executable attributes for EFI memory mappings. (Sai Praneeth Prakhya)
- Various arm64 UEFI enhancements. (Ard Biesheuvel)
- ... various fixes and cleanups.
The separate EFI page tables feature got delayed twice already, because it's an intrusive change and we didn't feel confident about it - third time's the charm we hope!
Thanks,
Ingo
------------------>
Alan Ott (1):
doc: efi-stub.txt: Fix arm64 paths
Ard Biesheuvel (14):
efi: Expose non-blocking set_variable() wrapper to efivars
efi: Remove redundant efi_set_variable_nonblocking() prototype efi/runtime-wrappers: Add a nonblocking version of QueryVariableInfo()
efi: Add nonblocking option to efi_query_variable_store() efi/runtime-wrappers: Remove out of date comment regarding in_nmi()
efi: Runtime-wrapper: Get rid of the rtc_lock spinlock efi/runtime-wrappers: Run UEFI Runtime Services with interrupts enabled efi/arm64: Drop __init annotation from handle_kernel_image() arm64/vmlinux.lds.S: Handle .init.rodata.xxx and .init.bss sections efi/efistub: Prevent __init annotations from being used efi/arm-init: Use read-only early mappings
efi/arm: Check for LPAE support before booting a LPAE kernel efi/arm64: Check for h/w support before booting a >4 KB granular kernel efi/arm*: Perform hardware compatibility check
Geliang Tang (1):
efivars: Use to_efivar_entry
Matt Fleming (10):
x86/mm: Page align the '_end' symbol to avoid pfn conversion bugs x86/mm/pat: Ensure cpa->pfn only contains page frame numbers x86/efi: Map RAM into the identity page table for mixed mode x86/efi: Hoist page table switching code into efi_call_virt() x86/efi: Build our own page table structures Documentation/x86: Update EFI memory region description x86/efi: Preface all print statements with efi* tag x86/efi-bgrt: Replace early_memremap() with memremap() x86/efi: Setup separate EFI page tables in kexec paths x86/mm/pat: Fix boot crash when 1GB pages are not supported by the CPU
Môshe van der Sterre (1):
x86/efi/bgrt: Don't ignore the BGRT if the 'valid' bit is 0
Peter Jones (1):
efi: Reformat GUID tables to follow the format in UEFI spec
Rasmus Villemoes (1):
efi/esrt: Don't preformat name
Robert Elliott (3):
x86/efi: Show actual ending addresses in efi_print_memmap
efi: Add NV memory attribute
efi: Add Persistent Memory type name
Sai Praneeth (5):
x86/efi-bgrt: Fix kernel panic when mapping BGRT data x86/mm/pat: Use _PAGE_GLOBAL bit for EFI page table mappings x86/mm/pat: Don't implicitly allow _PAGE_RW in kernel_map_pages_in_pgd() x86/efi: Map EFI_MEMORY_{XP,RO} memory region bits to EFI page tables x86/efi: Only map kernel text for EFI mixed mode
Documentation/efi-stub.txt | 4 +- Documentation/x86/x86_64/mm.txt | 12 +- arch/arm64/kernel/vmlinux.lds.S | 1 + arch/x86/include/asm/efi.h | 28 +++- arch/x86/kernel/vmlinux.lds.S | 1 + arch/x86/mm/pageattr.c | 34 +++-- arch/x86/platform/efi/efi-bgrt.c | 52 ++++---- arch/x86/platform/efi/efi.c | 67 +++++----- arch/x86/platform/efi/efi_32.c | 7 +- arch/x86/platform/efi/efi_64.c | 206 ++++++++++++++++++++++++------ arch/x86/platform/efi/efi_stub_64.S | 43 ------- arch/x86/platform/efi/quirks.c | 37 +++++- drivers/firmware/efi/arm-init.c | 14 +- drivers/firmware/efi/efi.c | 41 +----- drivers/firmware/efi/efivars.c | 2 +- drivers/firmware/efi/esrt.c | 5 +- drivers/firmware/efi/libstub/arm-stub.c | 4 + drivers/firmware/efi/libstub/arm32-stub.c | 17 +++ drivers/firmware/efi/libstub/arm64-stub.c | 34 ++++- drivers/firmware/efi/libstub/efistub.h | 12 ++ drivers/firmware/efi/runtime-wrappers.c | 113 ++++++---------- drivers/firmware/efi/vars.c | 16 ++- include/linux/efi.h | 85 +++++++----- 23 files changed, 512 insertions(+), 323 deletions(-)
Documentation/efi-stub.txt +2 -2
@@ -10,12 +10,12 @@ arch/x86/boot/header.S and arch/x86/boot/compressed/eboot.c, respectively. For ARM the EFI stub is implemented in arch/arm/boot/compressed/efi-header.S and arch/arm/boot/compressed/efi-stub.c. EFI stub code that is shared -between architectures is in drivers/firmware/efi/efi-stub-helper.c. +between architectures is in drivers/firmware/efi/libstub. For arm64, there is no compressed kernel support, so the Image itself masquerades as a PE/COFF image and the EFI stub is linked into the kernel. The arm64 EFI stub lives in arch/arm64/kernel/efi-entry.S -and arch/arm64/kernel/efi-stub.c. +and drivers/firmware/efi/libstub/arm64-stub.c. By using the EFI boot stub it's possible to boot a Linux kernel without the use of a conventional EFI boot loader, such as grub or
Documentation/x86/x86_64/mm.txt +6 -6
@@ -16,6 +16,8 @@ ffffec0000000000 - fffffc0000000000 (=44 bits) kasan shadow memory (16TB) ... unused hole ... ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks ... unused hole ... +ffffffef00000000 - ffffffff00000000 (=64 GB) EFI region mapping space +... unused hole ... ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0 ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
@@ -32,11 +34,9 @@ reference. Current X86-64 implementations only support 40 bits of address space, but we support up to 46 bits. This expands into MBZ space in the page tables. -->trampoline_pgd: - -We map EFI runtime services in the aforementioned PGD in the virtual -range of 64Gb (arbitrarily set, can be raised if needed) - -0xffffffef00000000 - 0xffffffff00000000 +We map EFI runtime services in the 'efi_pgd' PGD in a 64Gb large virtual +memory window (this size is arbitrary, it can be raised later if needed). +The mappings are not part of any other kernel PGD and are only available +during EFI runtime calls. -Andi Kleen, Jul 2004
arch/arm64/kernel/vmlinux.lds.S +1 -0
@@ -134,6 +134,7 @@ SECTIONS CON_INITCALL SECURITY_INITCALL INIT_RAM_FS + *(.init.rodata.* .init.bss) /* from the EFI stub */ } .exit.data : { ARM_EXIT_KEEP(EXIT_DATA)
arch/x86/include/asm/efi.h +27 -1
@@ -3,6 +3,7 @@#include <asm/fpu/api.h> #include <asm/pgtable.h> +#include <asm/tlb.h> /* * We map the EFI regions needed for runtime services non-contiguously,
@@ -64,6 +65,17 @@ extern u64 asmlinkage efi_call(void *fp, ...); #define efi_call_phys(f, args...) efi_call((f), args) +/* +* Scratch space used for switching the pagetable in the EFI stub +*/ +struct efi_scratch { +u64 r15; +u64 prev_cr3; +pgd_t *efi_pgt; +bool use_pgd; +u64 phys_stack; +} __packed; +#define efi_call_virt (f, ...) \ ({ \ efi_status_t __s; \
@@ -71,7 +83,20 @@ extern u64 asmlinkage efi_call(void *fp, ...);efi_sync_low_kernel_mappings (); \preempt_disable (); \__kernel_fpu_begin (); \ + \ +if (efi_scratch.use_pgd) { \ + efi_scratch.prev_cr3 =read_cr3 (); \ +write_cr3 ((unsigned long )efi_scratch.efi_pgt); \ +__flush_tlb_all (); \ + } \ + \ __s =efi_call ((void *)efi.systab->runtime->f, __VA_ARGS__); \ + \ +if (efi_scratch.use_pgd) { \ +write_cr3 (efi_scratch.prev_cr3); \ +__flush_tlb_all (); \ + } \ + \__kernel_fpu_end (); \preempt_enable (); \ __s; \
@@ -111,11 +136,12 @@ 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);extern void efi_sync_low_kernel_mappings (void ); +extern int __init efi_alloc_page_tables (void );extern int __init efi_setup_page_tables (unsigned long pa_memmap,unsigned num_pages);extern void __init efi_cleanup_page_tables (unsigned long pa_memmap,unsigned num_pages);extern void __init old_map_region (efi_memory_desc_t *md);extern void __init runtime_code_page_mkexec (void ); -extern void __init efi_runtime_mkexec (void ); +extern void __init efi_runtime_update_mappings (void );extern void __init efi_dump_pagetable (void );extern void __init efi_apply_memmap_quirks (void );extern int __init efi_reuse_config (u64 tables,int nr_tables);
arch/x86/kernel/vmlinux.lds.S +1 -0
@@ -325,6 +325,7 @@ SECTIONS __brk_limit = .; } + . = ALIGN(PAGE_SIZE); _end = .; STABS_DEBUG
arch/x86/mm/pageattr.c +23 -11
@@ -909,16 +909,25 @@ static void populate_pte(struct cpa_data *cpa, pte =pte_offset_kernel (pmd, start); -while (num_pages-- && start < end) { +/* +* Set the GLOBAL flags only if the PRESENT flag is +* set otherwise pte_present will return true even on +* a non present pte. The canon_pgprot will clear +* _PAGE_GLOBAL for the ancient hardware that doesn't +* support it. +*/ +if (pgprot_val (pgprot) & _PAGE_PRESENT) +pgprot_val (pgprot) |= _PAGE_GLOBAL; +else +pgprot_val (pgprot) &= ~_PAGE_GLOBAL; -/* deal with the NX bit */ -if (!(pgprot_val (pgprot) & _PAGE_NX)) - cpa->pfn &= ~_PAGE_NX; + pgprot =canon_pgprot (pgprot); -set_pte (pte,pfn_pte (cpa->pfn >>PAGE_SHIFT , pgprot)); +while (num_pages-- && start < end) { +set_pte (pte,pfn_pte (cpa->pfn, pgprot)); start +=PAGE_SIZE ; - cpa->pfn +=PAGE_SIZE ; + cpa->pfn++; pte++; } }
@@ -974,11 +983,11 @@ static int populate_pmd(struct cpa_data *cpa, pmd =pmd_offset (pud, start); -set_pmd (pmd,__pmd (cpa->pfn | _PAGE_PSE | +set_pmd (pmd,__pmd (cpa->pfn <<PAGE_SHIFT | _PAGE_PSE |massage_pgprot (pmd_pgprot))); start +=PMD_SIZE ; - cpa->pfn +=PMD_SIZE ; + cpa->pfn +=PMD_SIZE >>PAGE_SHIFT ; cur_pages +=PMD_SIZE >>PAGE_SHIFT ; }
@@ -1046,12 +1055,12 @@ static int populate_pud(struct cpa_data *cpa, unsigned long start, pgd_t *pgd,/* * Map everything starting from the Gb boundary, possibly with 1G pages */ -while (end - start >=PUD_SIZE ) { -set_pud (pud,__pud (cpa->pfn | _PAGE_PSE | +while (cpu_has_gbpages && end - start >=PUD_SIZE ) { +set_pud (pud,__pud (cpa->pfn <<PAGE_SHIFT | _PAGE_PSE |massage_pgprot (pud_pgprot))); start +=PUD_SIZE ; - cpa->pfn +=PUD_SIZE ; + cpa->pfn +=PUD_SIZE >>PAGE_SHIFT ; cur_pages +=PUD_SIZE >>PAGE_SHIFT ; pud++; }
@@ -1962,6 +1971,9 @@ int kernel_map_pages_in_pgd(pgd_t *pgd, u64 pfn, unsigned long address,if (!(page_flags & _PAGE_NX)) cpa.mask_clr =__pgprot (_PAGE_NX); +if (!(page_flags & _PAGE_RW)) + cpa.mask_clr =__pgprot (_PAGE_RW); + cpa.mask_set =__pgprot (_PAGE_PRESENT | page_flags); retval =__change_page_attr_set_clr (&cpa,0 );
arch/x86/platform/efi/efi-bgrt.c +22 -30
85 lines not on this page · raw message
arch/x86/platform/efi/efi.c +38 -29
125 lines not on this page · raw message
arch/x86/platform/efi/efi_32.c +6 -1
@@ -38,6 +38,11 @@* say 0 - 3G. */ +int __init efi_alloc_page_tables (void ) +{ +return 0 ; +} +void efi_sync_low_kernel_mappings (void ) {}void __init efi_dump_pagetable (void ) {}int __init efi_setup_page_tables (unsigned long pa_memmap,unsigned num_pages)
@@ -85,7 +90,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)__flush_tlb_all (); } -void __init efi_runtime_mkexec (void ) +void __init efi_runtime_update_mappings (void ) {if (__supported_pte_mask & _PAGE_NX)runtime_code_page_mkexec ();
arch/x86/platform/efi/efi_64.c +167 -39
316 lines not on this page · raw message
arch/x86/platform/efi/efi_stub_64.S +0 -43
57 lines not on this page · raw message
arch/x86/platform/efi/quirks.c +35 -2
@@ -1,3 +1,5 @@ +#define pr_fmt (fmt) "efi: " fmt +#include <linux/init.h> #include <linux/kernel.h> #include <linux/string.h>
@@ -55,13 +57,41 @@ void efi_delete_dummy_variable(void) }/* +* In the nonblocking case we do not attempt to perform garbage +* collection if we do not have enough free space. Rather, we do the +* bare minimum check and give up immediately if the available space +* is below EFI_MIN_RESERVE. +* +* This function is intended to be small and simple because it is +* invoked from crash handler paths. +*/ +static efi_status_t +query_variable_store_nonblocking (u32 attributes,unsigned long size) +{ +efi_status_t status; +u64 storage_size, remaining_size, max_size; + + status = efi.query_variable_info_nonblocking (attributes, &storage_size, + &remaining_size, + &max_size); +if (status !=EFI_SUCCESS ) +return status; + +if (remaining_size - size <EFI_MIN_RESERVE ) +return EFI_OUT_OF_RESOURCES ; + +return EFI_SUCCESS ; +} + +/* * Some firmware implementations refuse to boot if there's insufficient space * in the variable store. Ensure that we never use more than a safe limit. * * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable * store. */ -efi_status_t efi_query_variable_store (u32 attributes,unsigned long size) +efi_status_t efi_query_variable_store (u32 attributes,unsigned long size, +bool nonblocking) {efi_status_t status;u64 storage_size, remaining_size, max_size;
@@ -69,6 +99,9 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size)if (!(attributes &EFI_VARIABLE_NON_VOLATILE ))return 0 ; +if (nonblocking) +return query_variable_store_nonblocking (attributes, size); + status = efi.query_variable_info (attributes, &storage_size, &remaining_size, &max_size);if (status !=EFI_SUCCESS )
@@ -267,7 +300,7 @@ void __init efi_apply_memmap_quirks(void)* services. */ if (!efi_runtime_supported ()) { -pr_info ("efi: Setup done, disabling due to 32/64-bit mismatch\n" ); +pr_info ("Setup done, disabling due to 32/64-bit mismatch\n" );efi_unmap_memmap (); }
drivers/firmware/efi/arm-init.c +7 -7
@@ -61,8 +61,8 @@ static int __init uefi_init(void)char vendor[100 ] ="unknown" ;int i, retval; - efi.systab =early_memremap (efi_system_table, -sizeof (efi_system_table_t)); + efi.systab =early_memremap_ro (efi_system_table, +sizeof (efi_system_table_t));if (efi.systab ==NULL ) {pr_warn ("Unable to map EFI system table.\n" );return -ENOMEM ;
@@ -86,8 +86,8 @@ static int __init uefi_init(void) efi.systab->hdr.revision & 0xffff);/* Show what we know for posterity */ - c16 =early_memremap (efi_to_phys (efi.systab->fw_vendor), -sizeof (vendor) *sizeof (efi_char16_t)); + c16 =early_memremap_ro (efi_to_phys (efi.systab->fw_vendor), +sizeof (vendor) *sizeof (efi_char16_t));if (c16) {for (i =0 ; i < (int )sizeof (vendor) -1 && *c16; ++i) vendor[i] = c16[i];
@@ -100,8 +100,8 @@ static int __init uefi_init(void) efi.systab->hdr.revision & 0xffff, vendor); table_size =sizeof (efi_config_table_64_t) * efi.systab->nr_tables; - config_tables =early_memremap (efi_to_phys (efi.systab->tables), - table_size); + config_tables =early_memremap_ro (efi_to_phys (efi.systab->tables), + table_size);if (config_tables ==NULL ) {pr_warn ("Unable to map EFI config table array.\n" ); retval = -ENOMEM ;
@@ -185,7 +185,7 @@ void __init efi_init(void) efi_system_table = params.system_table; memmap.phys_map = params.mmap; - memmap.map =early_memremap (params.mmap, params.mmap_size); + memmap.map =early_memremap_ro (params.mmap, params.mmap_size);if (memmap.map ==NULL ) {/* * If we are booting via UEFI, the UEFI memory map is the only
drivers/firmware/efi/efi.c +7 -34
71 lines not on this page · raw message
drivers/firmware/efi/efivars.c +1 -1
@@ -386,7 +386,7 @@ static const struct sysfs_ops efivar_attr_ops = {static void efivar_release (struct kobject *kobj) { - struct efivar_entry *var = container_of(kobj, struct efivar_entry, kobj); +struct efivar_entry *var =to_efivar_entry (kobj);kfree (var); }
drivers/firmware/efi/esrt.c +1 -4
@@ -167,14 +167,11 @@ static struct kset *esrt_kset;static int esre_create_sysfs_entry (void *esre,int entry_num) {struct esre_entry *entry; -char name[20 ]; entry =kzalloc (sizeof (*entry),GFP_KERNEL );if (!entry)return -ENOMEM ; -sprintf (name,"entry%d" , entry_num); - entry->kobj.kset = esrt_kset;if (esrt->fw_resource_version ==1 ) {
@@ -182,7 +179,7 @@ static int esre_create_sysfs_entry(void *esre, int entry_num) entry->esre.esre1 = esre; rc =kobject_init_and_add (&entry->kobj, &esre1_ktype,NULL , -"%s" , name); +"entry%d" , entry_num);if (rc) {kfree (entry);return rc;
drivers/firmware/efi/libstub/arm-stub.c +4 -0
@@ -190,6 +190,10 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,pr_efi (sys_table,"Booting Linux Kernel...\n" ); + status =check_platform_features (sys_table); +if (status !=EFI_SUCCESS ) + goto fail; +/* * Get a handle to the loaded image protocol. This is used to get * information about the running image, such as size and the command
drivers/firmware/efi/libstub/arm32-stub.c +17 -0
@@ -9,6 +9,23 @@#include <linux/efi.h> #include <asm/efi.h> +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg) +{ +int block; + +/* non-LPAE kernels can run anywhere */ +if (!IS_ENABLED (CONFIG_ARM_LPAE )) +return EFI_SUCCESS ; + +/* LPAE kernels need compatible hardware */ + block =cpuid_feature_extract (CPUID_EXT_MMFR0 ,0 ); +if (block <5 ) { +pr_efi_err (sys_table_arg,"This LPAE kernel is not supported by your CPU\n" ); +return EFI_UNSUPPORTED ; + } +return EFI_SUCCESS ; +} + efi_status_t handle_kernel_image(efi_system_table_t *sys_table, unsigned long *image_addr, unsigned long *image_size,
drivers/firmware/efi/libstub/arm64-stub.c +27 -7
@@ -12,14 +12,34 @@#include <linux/efi.h> #include <asm/efi.h> #include <asm/sections.h> +#include <asm/sysreg.h> -efi_status_t __init handle_kernel_image (efi_system_table_t *sys_table_arg, -unsigned long *image_addr, -unsigned long *image_size, -unsigned long *reserve_addr, -unsigned long *reserve_size, -unsigned long dram_base, -efi_loaded_image_t *image) +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg) +{ +u64 tg; + +/* UEFI mandates support for 4 KB granularity, no need to check */ +if (IS_ENABLED (CONFIG_ARM64_4K_PAGES )) +return EFI_SUCCESS ; + + tg = (read_cpuid (ID_AA64MMFR0_EL1 ) >>ID_AA64MMFR0_TGRAN_SHIFT ) &0xf ; +if (tg !=ID_AA64MMFR0_TGRAN_SUPPORTED ) { +if (IS_ENABLED (CONFIG_ARM64_64K_PAGES )) +pr_efi_err (sys_table_arg,"This 64 KB granular kernel is not supported by your CPU\n" ); +else +pr_efi_err (sys_table_arg,"This 16 KB granular kernel is not supported by your CPU\n" ); +return EFI_UNSUPPORTED ; + } +return EFI_SUCCESS ; +} + +efi_status_t handle_kernel_image (efi_system_table_t *sys_table_arg, +unsigned long *image_addr, +unsigned long *image_size, +unsigned long *reserve_addr, +unsigned long *reserve_size, +unsigned long dram_base, +efi_loaded_image_t *image) {efi_status_t status;unsigned long kernel_size, kernel_memsize =0 ;
drivers/firmware/efi/libstub/efistub.h +12 -0
@@ -5,6 +5,16 @@/* error code which can't be mistaken for valid address */ #define EFI_ERROR (~0UL) +/* +* __init annotations should not be used in the EFI stub, since the code is +* either included in the decompressor (x86, ARM) where they have no effect, +* or the whole stub is __init annotated at the section level (arm64), by +* renaming the sections, in which case the __init annotation will be +* redundant, and will result in section names like .init.init.text, and our +* linker script does not expect that. +*/ +#undef __init +void efi_char16_printk (efi_system_table_t *,efi_char16_t *); efi_status_t efi_open_volume(efi_system_table_t *sys_table_arg, void *__image,
@@ -43,4 +53,6 @@ void efi_get_virtmap(efi_memory_desc_t *memory_map, unsigned long map_size, unsigned long desc_size, efi_memory_desc_t *runtime_map, int *count); +efi_status_t check_platform_features (efi_system_table_t *sys_table_arg); +#endif
drivers/firmware/efi/runtime-wrappers.c +39 -74
257 lines not on this page · raw message
drivers/firmware/efi/vars.c +14 -2
@@ -300,7 +300,18 @@ check_var_size(u32 attributes, unsigned long size)if (!fops->query_variable_store)return EFI_UNSUPPORTED ; -return fops->query_variable_store (attributes, size); +return fops->query_variable_store (attributes, size, false); +} + +static efi_status_t +check_var_size_nonblocking (u32 attributes,unsigned long size) +{ +const struct efivar_operations *fops = __efivars->ops; + +if (!fops->query_variable_store) +return EFI_UNSUPPORTED ; + +return fops->query_variable_store (attributes, size, true); }static int efi_status_to_err (efi_status_t status)
@@ -681,7 +692,8 @@ efivar_entry_set_nonblocking(efi_char16_t *name, efi_guid_t vendor,if (!spin_trylock_irqsave (&__efivars->lock, flags))return -EBUSY ; - status =check_var_size (attributes, size +ucs2_strsize (name,1024 )); + status =check_var_size_nonblocking (attributes, + size +ucs2_strsize (name,1024 ));if (status !=EFI_SUCCESS ) {spin_unlock_irqrestore (&__efivars->lock, flags);return -ENOSPC ;
include/linux/efi.h +55 -30
173 lines not on this page · raw message