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

Merge branch 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull x86 EFI update from Peter Anvin:
"EFI tree, from Matt Fleming. Most of the patches are the new efivarfs
filesystem by Matt Garrett & co. The balance are support for EFI
wallclock in the absence of a hardware-specific driver, and various
fixes and cleanups."

* 'core-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (24 commits)
efivarfs: Make efivarfs_fill_super() static
x86, efi: Check table header length in efi_bgrt_init()
efivarfs: Use query_variable_info() to limit kmalloc()
efivarfs: Fix return value of efivarfs_file_write()
efivarfs: Return a consistent error when efivarfs_get_inode() fails
efivarfs: Make 'datasize' unsigned long
efivarfs: Add unique magic number
efivarfs: Replace magic number with sizeof(attributes)
efivarfs: Return an error if we fail to read a variable
efi: Clarify GUID length calculations
efivarfs: Implement exclusive access for {get,set}_variable
efivarfs: efivarfs_fill_super() ensure we clean up correctly on error
efivarfs: efivarfs_fill_super() ensure we free our temporary name
efivarfs: efivarfs_fill_super() fix inode reference counts
efivarfs: efivarfs_create() ensure we drop our reference on inode on error
efivarfs: efivarfs_file_read ensure we free data in error paths
x86-64/efi: Use EFI to deal with platform wall clock (again)
x86/kernel: remove tboot 1:1 page table creation code
x86, efi: 1:1 pagetable mapping for virtual EFI calls
x86, mm: Include the entire kernel memory map in trampoline_pgd
...

+714 -127
+2
Documentation/filesystems/00-INDEX
··· 38 38 - example program for dnotify 39 39 ecryptfs.txt 40 40 - docs on eCryptfs: stacked cryptographic filesystem for Linux. 41 + efivarfs.txt 42 + - info for the efivarfs filesystem. 41 43 exofs.txt 42 44 - info, usage, mount options, design about EXOFS. 43 45 ext2.txt
+16
Documentation/filesystems/efivarfs.txt
··· 1 + 2 + efivarfs - a (U)EFI variable filesystem 3 + 4 + The efivarfs filesystem was created to address the shortcomings of 5 + using entries in sysfs to maintain EFI variables. The old sysfs EFI 6 + variables code only supported variables of up to 1024 bytes. This 7 + limitation existed in version 0.99 of the EFI specification, but was 8 + removed before any full releases. Since variables can now be larger 9 + than a single page, sysfs isn't the best interface for this. 10 + 11 + Variables can be created, deleted and modified with the efivarfs 12 + filesystem. 13 + 14 + efivarfs is typically mounted like this, 15 + 16 + mount -t efivarfs none /sys/firmware/efi/efivars
+21 -7
arch/x86/include/asm/efi.h
··· 69 69 efi_call6((void *)(f), (u64)(a1), (u64)(a2), (u64)(a3), \ 70 70 (u64)(a4), (u64)(a5), (u64)(a6)) 71 71 72 + extern unsigned long efi_call_virt_prelog(void); 73 + extern void efi_call_virt_epilog(unsigned long); 74 + 75 + #define efi_callx(x, func, ...) \ 76 + ({ \ 77 + efi_status_t __status; \ 78 + unsigned long __pgd; \ 79 + \ 80 + __pgd = efi_call_virt_prelog(); \ 81 + __status = efi_call##x(func, __VA_ARGS__); \ 82 + efi_call_virt_epilog(__pgd); \ 83 + __status; \ 84 + }) 85 + 72 86 #define efi_call_virt0(f) \ 73 - efi_call0((void *)(efi.systab->runtime->f)) 87 + efi_callx(0, (void *)(efi.systab->runtime->f)) 74 88 #define efi_call_virt1(f, a1) \ 75 - efi_call1((void *)(efi.systab->runtime->f), (u64)(a1)) 89 + efi_callx(1, (void *)(efi.systab->runtime->f), (u64)(a1)) 76 90 #define efi_call_virt2(f, a1, a2) \ 77 - efi_call2((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2)) 91 + efi_callx(2, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2)) 78 92 #define efi_call_virt3(f, a1, a2, a3) \ 79 - efi_call3((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 93 + efi_callx(3, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 80 94 (u64)(a3)) 81 95 #define efi_call_virt4(f, a1, a2, a3, a4) \ 82 - efi_call4((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 96 + efi_callx(4, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 83 97 (u64)(a3), (u64)(a4)) 84 98 #define efi_call_virt5(f, a1, a2, a3, a4, a5) \ 85 - efi_call5((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 99 + efi_callx(5, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 86 100 (u64)(a3), (u64)(a4), (u64)(a5)) 87 101 #define efi_call_virt6(f, a1, a2, a3, a4, a5, a6) \ 88 - efi_call6((void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 102 + efi_callx(6, (void *)(efi.systab->runtime->f), (u64)(a1), (u64)(a2), \ 89 103 (u64)(a3), (u64)(a4), (u64)(a5), (u64)(a6)) 90 104 91 105 extern void __iomem *efi_ioremap(unsigned long addr, unsigned long size,
+5 -73
arch/x86/kernel/tboot.c
··· 103 103 pr_debug("tboot_size: 0x%x\n", tboot->tboot_size); 104 104 } 105 105 106 - static pgd_t *tboot_pg_dir; 107 - static struct mm_struct tboot_mm = { 108 - .mm_rb = RB_ROOT, 109 - .pgd = swapper_pg_dir, 110 - .mm_users = ATOMIC_INIT(2), 111 - .mm_count = ATOMIC_INIT(1), 112 - .mmap_sem = __RWSEM_INITIALIZER(init_mm.mmap_sem), 113 - .page_table_lock = __SPIN_LOCK_UNLOCKED(init_mm.page_table_lock), 114 - .mmlist = LIST_HEAD_INIT(init_mm.mmlist), 115 - }; 116 - 117 106 static inline void switch_to_tboot_pt(void) 118 107 { 119 - write_cr3(virt_to_phys(tboot_pg_dir)); 120 - } 121 - 122 - static int map_tboot_page(unsigned long vaddr, unsigned long pfn, 123 - pgprot_t prot) 124 - { 125 - pgd_t *pgd; 126 - pud_t *pud; 127 - pmd_t *pmd; 128 - pte_t *pte; 129 - 130 - pgd = pgd_offset(&tboot_mm, vaddr); 131 - pud = pud_alloc(&tboot_mm, pgd, vaddr); 132 - if (!pud) 133 - return -1; 134 - pmd = pmd_alloc(&tboot_mm, pud, vaddr); 135 - if (!pmd) 136 - return -1; 137 - pte = pte_alloc_map(&tboot_mm, NULL, pmd, vaddr); 138 - if (!pte) 139 - return -1; 140 - set_pte_at(&tboot_mm, vaddr, pte, pfn_pte(pfn, prot)); 141 - pte_unmap(pte); 142 - return 0; 143 - } 144 - 145 - static int map_tboot_pages(unsigned long vaddr, unsigned long start_pfn, 146 - unsigned long nr) 147 - { 148 - /* Reuse the original kernel mapping */ 149 - tboot_pg_dir = pgd_alloc(&tboot_mm); 150 - if (!tboot_pg_dir) 151 - return -1; 152 - 153 - for (; nr > 0; nr--, vaddr += PAGE_SIZE, start_pfn++) { 154 - if (map_tboot_page(vaddr, start_pfn, PAGE_KERNEL_EXEC)) 155 - return -1; 156 - } 157 - 158 - return 0; 159 - } 160 - 161 - static void tboot_create_trampoline(void) 162 - { 163 - u32 map_base, map_size; 164 - 165 - /* Create identity map for tboot shutdown code. */ 166 - map_base = PFN_DOWN(tboot->tboot_base); 167 - map_size = PFN_UP(tboot->tboot_size); 168 - if (map_tboot_pages(map_base << PAGE_SHIFT, map_base, map_size)) 169 - panic("tboot: Error mapping tboot pages (mfns) @ 0x%x, 0x%x\n", 170 - map_base, map_size); 108 + #ifdef CONFIG_X86_32 109 + load_cr3(initial_page_table); 110 + #else 111 + write_cr3(real_mode_header->trampoline_pgd); 112 + #endif 171 113 } 172 114 173 115 #ifdef CONFIG_ACPI_SLEEP ··· 165 223 void (*shutdown)(void); 166 224 167 225 if (!tboot_enabled()) 168 - return; 169 - 170 - /* 171 - * if we're being called before the 1:1 mapping is set up then just 172 - * return and let the normal shutdown happen; this should only be 173 - * due to very early panic() 174 - */ 175 - if (!tboot_pg_dir) 176 226 return; 177 227 178 228 /* if this is S3 then set regions to MAC */ ··· 276 342 { 277 343 if (!tboot_enabled()) 278 344 return 0; 279 - 280 - tboot_create_trampoline(); 281 345 282 346 atomic_set(&ap_wfs_count, 0); 283 347 register_hotcpu_notifier(&tboot_cpu_notifier);
+8 -1
arch/x86/mm/init_64.c
··· 108 108 for (address = start; address <= end; address += PGDIR_SIZE) { 109 109 const pgd_t *pgd_ref = pgd_offset_k(address); 110 110 struct page *page; 111 + pgd_t *pgd; 111 112 112 113 if (pgd_none(*pgd_ref)) 113 114 continue; 114 115 115 116 spin_lock(&pgd_lock); 116 117 list_for_each_entry(page, &pgd_list, lru) { 117 - pgd_t *pgd; 118 118 spinlock_t *pgt_lock; 119 119 120 120 pgd = (pgd_t *)page_address(page) + pgd_index(address); ··· 130 130 131 131 spin_unlock(pgt_lock); 132 132 } 133 + 134 + pgd = __va(real_mode_header->trampoline_pgd); 135 + pgd += pgd_index(address); 136 + 137 + if (pgd_none(*pgd)) 138 + set_pgd(pgd, *pgd_ref); 139 + 133 140 spin_unlock(&pgd_lock); 134 141 } 135 142 }
+105
arch/x86/mm/ioremap.c
··· 50 50 return err; 51 51 } 52 52 53 + #ifdef CONFIG_X86_64 54 + static void ident_pte_range(unsigned long paddr, unsigned long vaddr, 55 + pmd_t *ppmd, pmd_t *vpmd, unsigned long end) 56 + { 57 + pte_t *ppte = pte_offset_kernel(ppmd, paddr); 58 + pte_t *vpte = pte_offset_kernel(vpmd, vaddr); 59 + 60 + do { 61 + set_pte(ppte, *vpte); 62 + } while (ppte++, vpte++, vaddr += PAGE_SIZE, vaddr != end); 63 + } 64 + 65 + static int ident_pmd_range(unsigned long paddr, unsigned long vaddr, 66 + pud_t *ppud, pud_t *vpud, unsigned long end) 67 + { 68 + pmd_t *ppmd = pmd_offset(ppud, paddr); 69 + pmd_t *vpmd = pmd_offset(vpud, vaddr); 70 + unsigned long next; 71 + 72 + do { 73 + next = pmd_addr_end(vaddr, end); 74 + 75 + if (!pmd_present(*ppmd)) { 76 + pte_t *ppte = (pte_t *)get_zeroed_page(GFP_KERNEL); 77 + if (!ppte) 78 + return 1; 79 + 80 + set_pmd(ppmd, __pmd(_KERNPG_TABLE | __pa(ppte))); 81 + } 82 + 83 + ident_pte_range(paddr, vaddr, ppmd, vpmd, next); 84 + } while (ppmd++, vpmd++, vaddr = next, vaddr != end); 85 + 86 + return 0; 87 + } 88 + 89 + static int ident_pud_range(unsigned long paddr, unsigned long vaddr, 90 + pgd_t *ppgd, pgd_t *vpgd, unsigned long end) 91 + { 92 + pud_t *ppud = pud_offset(ppgd, paddr); 93 + pud_t *vpud = pud_offset(vpgd, vaddr); 94 + unsigned long next; 95 + 96 + do { 97 + next = pud_addr_end(vaddr, end); 98 + 99 + if (!pud_present(*ppud)) { 100 + pmd_t *ppmd = (pmd_t *)get_zeroed_page(GFP_KERNEL); 101 + if (!ppmd) 102 + return 1; 103 + 104 + set_pud(ppud, __pud(_KERNPG_TABLE | __pa(ppmd))); 105 + } 106 + 107 + if (ident_pmd_range(paddr, vaddr, ppud, vpud, next)) 108 + return 1; 109 + } while (ppud++, vpud++, vaddr = next, vaddr != end); 110 + 111 + return 0; 112 + } 113 + 114 + static int insert_identity_mapping(resource_size_t paddr, unsigned long vaddr, 115 + unsigned long size) 116 + { 117 + unsigned long end = vaddr + size; 118 + unsigned long next; 119 + pgd_t *vpgd, *ppgd; 120 + 121 + /* Don't map over the guard hole. */ 122 + if (paddr >= 0x800000000000 || paddr + size > 0x800000000000) 123 + return 1; 124 + 125 + ppgd = __va(real_mode_header->trampoline_pgd) + pgd_index(paddr); 126 + 127 + vpgd = pgd_offset_k(vaddr); 128 + do { 129 + next = pgd_addr_end(vaddr, end); 130 + 131 + if (!pgd_present(*ppgd)) { 132 + pud_t *ppud = (pud_t *)get_zeroed_page(GFP_KERNEL); 133 + if (!ppud) 134 + return 1; 135 + 136 + set_pgd(ppgd, __pgd(_KERNPG_TABLE | __pa(ppud))); 137 + } 138 + 139 + if (ident_pud_range(paddr, vaddr, ppgd, vpgd, next)) 140 + return 1; 141 + } while (ppgd++, vpgd++, vaddr = next, vaddr != end); 142 + 143 + return 0; 144 + } 145 + #else 146 + static inline int insert_identity_mapping(resource_size_t paddr, 147 + unsigned long vaddr, 148 + unsigned long size) 149 + { 150 + return 0; 151 + } 152 + #endif /* CONFIG_X86_64 */ 153 + 53 154 /* 54 155 * Remap an arbitrary physical address space into the kernel virtual 55 156 * address space. Needed when the kernel wants to access high addresses ··· 263 162 264 163 ret_addr = (void __iomem *) (vaddr + offset); 265 164 mmiotrace_ioremap(unaligned_phys_addr, unaligned_size, ret_addr); 165 + 166 + if (insert_identity_mapping(phys_addr, vaddr, size)) 167 + printk(KERN_WARNING "ioremap: unable to map 0x%llx in identity pagetable\n", 168 + (unsigned long long)phys_addr); 266 169 267 170 /* 268 171 * Check if the request spans more than any BAR in the iomem resource
+6 -4
arch/x86/mm/pageattr.c
··· 919 919 920 920 /* 921 921 * On success we use clflush, when the CPU supports it to 922 - * avoid the wbindv. If the CPU does not support it and in the 923 - * error case we fall back to cpa_flush_all (which uses 924 - * wbindv): 922 + * avoid the wbindv. If the CPU does not support it, in the 923 + * error case, and during early boot (for EFI) we fall back 924 + * to cpa_flush_all (which uses wbinvd): 925 925 */ 926 - if (!ret && cpu_has_clflush) { 926 + if (early_boot_irqs_disabled) 927 + __cpa_flush_all((void *)(long)cache); 928 + else if (!ret && cpu_has_clflush) { 927 929 if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { 928 930 cpa_flush_array(addr, numpages, cache, 929 931 cpa.flags, pages);
+2
arch/x86/platform/efi/efi-bgrt.c
··· 39 39 if (ACPI_FAILURE(status)) 40 40 return; 41 41 42 + if (bgrt_tab->header.length < sizeof(*bgrt_tab)) 43 + return; 42 44 if (bgrt_tab->version != 1) 43 45 return; 44 46 if (bgrt_tab->image_type != 0 || !bgrt_tab->image_address)
+4 -26
arch/x86/platform/efi/efi.c
··· 239 239 return status; 240 240 } 241 241 242 - static efi_status_t __init phys_efi_get_time(efi_time_t *tm, 243 - efi_time_cap_t *tc) 244 - { 245 - unsigned long flags; 246 - efi_status_t status; 247 - 248 - spin_lock_irqsave(&rtc_lock, flags); 249 - efi_call_phys_prelog(); 250 - status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), 251 - virt_to_phys(tc)); 252 - efi_call_phys_epilog(); 253 - spin_unlock_irqrestore(&rtc_lock, flags); 254 - return status; 255 - } 256 - 257 - int efi_set_rtc_mmss(unsigned long nowtime) 242 + static int efi_set_rtc_mmss(unsigned long nowtime) 258 243 { 259 244 int real_seconds, real_minutes; 260 245 efi_status_t status; ··· 268 283 return 0; 269 284 } 270 285 271 - unsigned long efi_get_time(void) 286 + static unsigned long efi_get_time(void) 272 287 { 273 288 efi_status_t status; 274 289 efi_time_t eft; ··· 624 639 } 625 640 /* 626 641 * We will only need *early* access to the following 627 - * two EFI runtime services before set_virtual_address_map 642 + * EFI runtime service before set_virtual_address_map 628 643 * is invoked. 629 644 */ 630 - efi_phys.get_time = (efi_get_time_t *)runtime->get_time; 631 645 efi_phys.set_virtual_address_map = 632 646 (efi_set_virtual_address_map_t *) 633 647 runtime->set_virtual_address_map; 634 - /* 635 - * Make efi_get_time can be called before entering 636 - * virtual mode. 637 - */ 638 - efi.get_time = phys_efi_get_time; 648 + 639 649 early_iounmap(runtime, sizeof(efi_runtime_services_t)); 640 650 641 651 return 0; ··· 716 736 efi_enabled = 0; 717 737 return; 718 738 } 719 - #ifdef CONFIG_X86_32 720 739 if (efi_is_native()) { 721 740 x86_platform.get_wallclock = efi_get_time; 722 741 x86_platform.set_wallclock = efi_set_rtc_mmss; 723 742 } 724 - #endif 725 743 726 744 #if EFI_DEBUG 727 745 print_efi_memmap();
+15
arch/x86/platform/efi/efi_64.c
··· 58 58 } 59 59 } 60 60 61 + unsigned long efi_call_virt_prelog(void) 62 + { 63 + unsigned long saved; 64 + 65 + saved = read_cr3(); 66 + write_cr3(real_mode_header->trampoline_pgd); 67 + 68 + return saved; 69 + } 70 + 71 + void efi_call_virt_epilog(unsigned long saved) 72 + { 73 + write_cr3(saved); 74 + } 75 + 61 76 void __init efi_call_phys_prelog(void) 62 77 { 63 78 unsigned long vaddress;
+15 -2
arch/x86/realmode/init.c
··· 78 78 *trampoline_cr4_features = read_cr4(); 79 79 80 80 trampoline_pgd = (u64 *) __va(real_mode_header->trampoline_pgd); 81 - trampoline_pgd[0] = __pa(level3_ident_pgt) + _KERNPG_TABLE; 82 - trampoline_pgd[511] = __pa(level3_kernel_pgt) + _KERNPG_TABLE; 81 + 82 + /* 83 + * Create an identity mapping for all of physical memory. 84 + */ 85 + for (i = 0; i <= pgd_index(max_pfn << PAGE_SHIFT); i++) { 86 + int index = pgd_index(PAGE_OFFSET) + i; 87 + 88 + trampoline_pgd[i] = (u64)pgd_val(swapper_pg_dir[index]); 89 + } 90 + 91 + /* 92 + * Copy the upper-half of the kernel pages tables. 93 + */ 94 + for (i = pgd_index(PAGE_OFFSET); i < PTRS_PER_PGD; i++) 95 + trampoline_pgd[i] = (u64)pgd_val(swapper_pg_dir[i]); 83 96 #endif 84 97 } 85 98
+504 -8
drivers/firmware/efivars.c
··· 80 80 #include <linux/slab.h> 81 81 #include <linux/pstore.h> 82 82 83 + #include <linux/fs.h> 84 + #include <linux/ramfs.h> 85 + #include <linux/pagemap.h> 86 + 83 87 #include <asm/uaccess.h> 84 88 85 89 #define EFIVARS_VERSION "0.08" ··· 95 91 MODULE_VERSION(EFIVARS_VERSION); 96 92 97 93 #define DUMP_NAME_LEN 52 94 + 95 + /* 96 + * Length of a GUID string (strlen("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee")) 97 + * not including trailing NUL 98 + */ 99 + #define GUID_LEN 36 98 100 99 101 /* 100 102 * The maximum size of VariableName + Data = 1024 ··· 118 108 __u32 Attributes; 119 109 } __attribute__((packed)); 120 110 121 - 122 111 struct efivar_entry { 123 112 struct efivars *efivars; 124 113 struct efi_variable var; ··· 130 121 ssize_t (*show) (struct efivar_entry *entry, char *buf); 131 122 ssize_t (*store)(struct efivar_entry *entry, const char *buf, size_t count); 132 123 }; 124 + 125 + static struct efivars __efivars; 126 + static struct efivar_operations ops; 133 127 134 128 #define PSTORE_EFI_ATTRIBUTES \ 135 129 (EFI_VARIABLE_NON_VOLATILE | \ ··· 641 629 .default_attrs = def_attrs, 642 630 }; 643 631 644 - static struct pstore_info efi_pstore_info; 645 - 646 632 static inline void 647 633 efivar_unregister(struct efivar_entry *var) 648 634 { 649 635 kobject_put(&var->kobj); 650 636 } 637 + 638 + static int efivarfs_file_open(struct inode *inode, struct file *file) 639 + { 640 + file->private_data = inode->i_private; 641 + return 0; 642 + } 643 + 644 + static int efi_status_to_err(efi_status_t status) 645 + { 646 + int err; 647 + 648 + switch (status) { 649 + case EFI_INVALID_PARAMETER: 650 + err = -EINVAL; 651 + break; 652 + case EFI_OUT_OF_RESOURCES: 653 + err = -ENOSPC; 654 + break; 655 + case EFI_DEVICE_ERROR: 656 + err = -EIO; 657 + break; 658 + case EFI_WRITE_PROTECTED: 659 + err = -EROFS; 660 + break; 661 + case EFI_SECURITY_VIOLATION: 662 + err = -EACCES; 663 + break; 664 + case EFI_NOT_FOUND: 665 + err = -ENOENT; 666 + break; 667 + default: 668 + err = -EINVAL; 669 + } 670 + 671 + return err; 672 + } 673 + 674 + static ssize_t efivarfs_file_write(struct file *file, 675 + const char __user *userbuf, size_t count, loff_t *ppos) 676 + { 677 + struct efivar_entry *var = file->private_data; 678 + struct efivars *efivars; 679 + efi_status_t status; 680 + void *data; 681 + u32 attributes; 682 + struct inode *inode = file->f_mapping->host; 683 + unsigned long datasize = count - sizeof(attributes); 684 + unsigned long newdatasize; 685 + u64 storage_size, remaining_size, max_size; 686 + ssize_t bytes = 0; 687 + 688 + if (count < sizeof(attributes)) 689 + return -EINVAL; 690 + 691 + if (copy_from_user(&attributes, userbuf, sizeof(attributes))) 692 + return -EFAULT; 693 + 694 + if (attributes & ~(EFI_VARIABLE_MASK)) 695 + return -EINVAL; 696 + 697 + efivars = var->efivars; 698 + 699 + /* 700 + * Ensure that the user can't allocate arbitrarily large 701 + * amounts of memory. Pick a default size of 64K if 702 + * QueryVariableInfo() isn't supported by the firmware. 703 + */ 704 + spin_lock(&efivars->lock); 705 + 706 + if (!efivars->ops->query_variable_info) 707 + status = EFI_UNSUPPORTED; 708 + else { 709 + const struct efivar_operations *fops = efivars->ops; 710 + status = fops->query_variable_info(attributes, &storage_size, 711 + &remaining_size, &max_size); 712 + } 713 + 714 + spin_unlock(&efivars->lock); 715 + 716 + if (status != EFI_SUCCESS) { 717 + if (status != EFI_UNSUPPORTED) 718 + return efi_status_to_err(status); 719 + 720 + remaining_size = 65536; 721 + } 722 + 723 + if (datasize > remaining_size) 724 + return -ENOSPC; 725 + 726 + data = kmalloc(datasize, GFP_KERNEL); 727 + if (!data) 728 + return -ENOMEM; 729 + 730 + if (copy_from_user(data, userbuf + sizeof(attributes), datasize)) { 731 + bytes = -EFAULT; 732 + goto out; 733 + } 734 + 735 + if (validate_var(&var->var, data, datasize) == false) { 736 + bytes = -EINVAL; 737 + goto out; 738 + } 739 + 740 + /* 741 + * The lock here protects the get_variable call, the conditional 742 + * set_variable call, and removal of the variable from the efivars 743 + * list (in the case of an authenticated delete). 744 + */ 745 + spin_lock(&efivars->lock); 746 + 747 + status = efivars->ops->set_variable(var->var.VariableName, 748 + &var->var.VendorGuid, 749 + attributes, datasize, 750 + data); 751 + 752 + if (status != EFI_SUCCESS) { 753 + spin_unlock(&efivars->lock); 754 + kfree(data); 755 + 756 + return efi_status_to_err(status); 757 + } 758 + 759 + bytes = count; 760 + 761 + /* 762 + * Writing to the variable may have caused a change in size (which 763 + * could either be an append or an overwrite), or the variable to be 764 + * deleted. Perform a GetVariable() so we can tell what actually 765 + * happened. 766 + */ 767 + newdatasize = 0; 768 + status = efivars->ops->get_variable(var->var.VariableName, 769 + &var->var.VendorGuid, 770 + NULL, &newdatasize, 771 + NULL); 772 + 773 + if (status == EFI_BUFFER_TOO_SMALL) { 774 + spin_unlock(&efivars->lock); 775 + mutex_lock(&inode->i_mutex); 776 + i_size_write(inode, newdatasize + sizeof(attributes)); 777 + mutex_unlock(&inode->i_mutex); 778 + 779 + } else if (status == EFI_NOT_FOUND) { 780 + list_del(&var->list); 781 + spin_unlock(&efivars->lock); 782 + efivar_unregister(var); 783 + drop_nlink(inode); 784 + dput(file->f_dentry); 785 + 786 + } else { 787 + spin_unlock(&efivars->lock); 788 + pr_warn("efivarfs: inconsistent EFI variable implementation? " 789 + "status = %lx\n", status); 790 + } 791 + 792 + out: 793 + kfree(data); 794 + 795 + return bytes; 796 + } 797 + 798 + static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, 799 + size_t count, loff_t *ppos) 800 + { 801 + struct efivar_entry *var = file->private_data; 802 + struct efivars *efivars = var->efivars; 803 + efi_status_t status; 804 + unsigned long datasize = 0; 805 + u32 attributes; 806 + void *data; 807 + ssize_t size = 0; 808 + 809 + spin_lock(&efivars->lock); 810 + status = efivars->ops->get_variable(var->var.VariableName, 811 + &var->var.VendorGuid, 812 + &attributes, &datasize, NULL); 813 + spin_unlock(&efivars->lock); 814 + 815 + if (status != EFI_BUFFER_TOO_SMALL) 816 + return efi_status_to_err(status); 817 + 818 + data = kmalloc(datasize + sizeof(attributes), GFP_KERNEL); 819 + 820 + if (!data) 821 + return -ENOMEM; 822 + 823 + spin_lock(&efivars->lock); 824 + status = efivars->ops->get_variable(var->var.VariableName, 825 + &var->var.VendorGuid, 826 + &attributes, &datasize, 827 + (data + sizeof(attributes))); 828 + spin_unlock(&efivars->lock); 829 + 830 + if (status != EFI_SUCCESS) { 831 + size = efi_status_to_err(status); 832 + goto out_free; 833 + } 834 + 835 + memcpy(data, &attributes, sizeof(attributes)); 836 + size = simple_read_from_buffer(userbuf, count, ppos, 837 + data, datasize + sizeof(attributes)); 838 + out_free: 839 + kfree(data); 840 + 841 + return size; 842 + } 843 + 844 + static void efivarfs_evict_inode(struct inode *inode) 845 + { 846 + clear_inode(inode); 847 + } 848 + 849 + static const struct super_operations efivarfs_ops = { 850 + .statfs = simple_statfs, 851 + .drop_inode = generic_delete_inode, 852 + .evict_inode = efivarfs_evict_inode, 853 + .show_options = generic_show_options, 854 + }; 855 + 856 + static struct super_block *efivarfs_sb; 857 + 858 + static const struct inode_operations efivarfs_dir_inode_operations; 859 + 860 + static const struct file_operations efivarfs_file_operations = { 861 + .open = efivarfs_file_open, 862 + .read = efivarfs_file_read, 863 + .write = efivarfs_file_write, 864 + .llseek = no_llseek, 865 + }; 866 + 867 + static struct inode *efivarfs_get_inode(struct super_block *sb, 868 + const struct inode *dir, int mode, dev_t dev) 869 + { 870 + struct inode *inode = new_inode(sb); 871 + 872 + if (inode) { 873 + inode->i_ino = get_next_ino(); 874 + inode->i_uid = inode->i_gid = 0; 875 + inode->i_mode = mode; 876 + inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; 877 + switch (mode & S_IFMT) { 878 + case S_IFREG: 879 + inode->i_fop = &efivarfs_file_operations; 880 + break; 881 + case S_IFDIR: 882 + inode->i_op = &efivarfs_dir_inode_operations; 883 + inode->i_fop = &simple_dir_operations; 884 + inc_nlink(inode); 885 + break; 886 + } 887 + } 888 + return inode; 889 + } 890 + 891 + static void efivarfs_hex_to_guid(const char *str, efi_guid_t *guid) 892 + { 893 + guid->b[0] = hex_to_bin(str[6]) << 4 | hex_to_bin(str[7]); 894 + guid->b[1] = hex_to_bin(str[4]) << 4 | hex_to_bin(str[5]); 895 + guid->b[2] = hex_to_bin(str[2]) << 4 | hex_to_bin(str[3]); 896 + guid->b[3] = hex_to_bin(str[0]) << 4 | hex_to_bin(str[1]); 897 + guid->b[4] = hex_to_bin(str[11]) << 4 | hex_to_bin(str[12]); 898 + guid->b[5] = hex_to_bin(str[9]) << 4 | hex_to_bin(str[10]); 899 + guid->b[6] = hex_to_bin(str[16]) << 4 | hex_to_bin(str[17]); 900 + guid->b[7] = hex_to_bin(str[14]) << 4 | hex_to_bin(str[15]); 901 + guid->b[8] = hex_to_bin(str[19]) << 4 | hex_to_bin(str[20]); 902 + guid->b[9] = hex_to_bin(str[21]) << 4 | hex_to_bin(str[22]); 903 + guid->b[10] = hex_to_bin(str[24]) << 4 | hex_to_bin(str[25]); 904 + guid->b[11] = hex_to_bin(str[26]) << 4 | hex_to_bin(str[27]); 905 + guid->b[12] = hex_to_bin(str[28]) << 4 | hex_to_bin(str[29]); 906 + guid->b[13] = hex_to_bin(str[30]) << 4 | hex_to_bin(str[31]); 907 + guid->b[14] = hex_to_bin(str[32]) << 4 | hex_to_bin(str[33]); 908 + guid->b[15] = hex_to_bin(str[34]) << 4 | hex_to_bin(str[35]); 909 + } 910 + 911 + static int efivarfs_create(struct inode *dir, struct dentry *dentry, 912 + umode_t mode, bool excl) 913 + { 914 + struct inode *inode; 915 + struct efivars *efivars = &__efivars; 916 + struct efivar_entry *var; 917 + int namelen, i = 0, err = 0; 918 + 919 + /* 920 + * We need a GUID, plus at least one letter for the variable name, 921 + * plus the '-' separator 922 + */ 923 + if (dentry->d_name.len < GUID_LEN + 2) 924 + return -EINVAL; 925 + 926 + inode = efivarfs_get_inode(dir->i_sb, dir, mode, 0); 927 + if (!inode) 928 + return -ENOMEM; 929 + 930 + var = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); 931 + if (!var) { 932 + err = -ENOMEM; 933 + goto out; 934 + } 935 + 936 + /* length of the variable name itself: remove GUID and separator */ 937 + namelen = dentry->d_name.len - GUID_LEN - 1; 938 + 939 + efivarfs_hex_to_guid(dentry->d_name.name + namelen + 1, 940 + &var->var.VendorGuid); 941 + 942 + for (i = 0; i < namelen; i++) 943 + var->var.VariableName[i] = dentry->d_name.name[i]; 944 + 945 + var->var.VariableName[i] = '\0'; 946 + 947 + inode->i_private = var; 948 + var->efivars = efivars; 949 + var->kobj.kset = efivars->kset; 950 + 951 + err = kobject_init_and_add(&var->kobj, &efivar_ktype, NULL, "%s", 952 + dentry->d_name.name); 953 + if (err) 954 + goto out; 955 + 956 + kobject_uevent(&var->kobj, KOBJ_ADD); 957 + spin_lock(&efivars->lock); 958 + list_add(&var->list, &efivars->list); 959 + spin_unlock(&efivars->lock); 960 + d_instantiate(dentry, inode); 961 + dget(dentry); 962 + out: 963 + if (err) { 964 + kfree(var); 965 + iput(inode); 966 + } 967 + return err; 968 + } 969 + 970 + static int efivarfs_unlink(struct inode *dir, struct dentry *dentry) 971 + { 972 + struct efivar_entry *var = dentry->d_inode->i_private; 973 + struct efivars *efivars = var->efivars; 974 + efi_status_t status; 975 + 976 + spin_lock(&efivars->lock); 977 + 978 + status = efivars->ops->set_variable(var->var.VariableName, 979 + &var->var.VendorGuid, 980 + 0, 0, NULL); 981 + 982 + if (status == EFI_SUCCESS || status == EFI_NOT_FOUND) { 983 + list_del(&var->list); 984 + spin_unlock(&efivars->lock); 985 + efivar_unregister(var); 986 + drop_nlink(dir); 987 + dput(dentry); 988 + return 0; 989 + } 990 + 991 + spin_unlock(&efivars->lock); 992 + return -EINVAL; 993 + }; 994 + 995 + static int efivarfs_fill_super(struct super_block *sb, void *data, int silent) 996 + { 997 + struct inode *inode = NULL; 998 + struct dentry *root; 999 + struct efivar_entry *entry, *n; 1000 + struct efivars *efivars = &__efivars; 1001 + char *name; 1002 + 1003 + efivarfs_sb = sb; 1004 + 1005 + sb->s_maxbytes = MAX_LFS_FILESIZE; 1006 + sb->s_blocksize = PAGE_CACHE_SIZE; 1007 + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; 1008 + sb->s_magic = EFIVARFS_MAGIC; 1009 + sb->s_op = &efivarfs_ops; 1010 + sb->s_time_gran = 1; 1011 + 1012 + inode = efivarfs_get_inode(sb, NULL, S_IFDIR | 0755, 0); 1013 + if (!inode) 1014 + return -ENOMEM; 1015 + inode->i_op = &efivarfs_dir_inode_operations; 1016 + 1017 + root = d_make_root(inode); 1018 + sb->s_root = root; 1019 + if (!root) 1020 + return -ENOMEM; 1021 + 1022 + list_for_each_entry_safe(entry, n, &efivars->list, list) { 1023 + struct dentry *dentry, *root = efivarfs_sb->s_root; 1024 + unsigned long size = 0; 1025 + int len, i; 1026 + 1027 + inode = NULL; 1028 + 1029 + len = utf16_strlen(entry->var.VariableName); 1030 + 1031 + /* name, plus '-', plus GUID, plus NUL*/ 1032 + name = kmalloc(len + 1 + GUID_LEN + 1, GFP_ATOMIC); 1033 + if (!name) 1034 + goto fail; 1035 + 1036 + for (i = 0; i < len; i++) 1037 + name[i] = entry->var.VariableName[i] & 0xFF; 1038 + 1039 + name[len] = '-'; 1040 + 1041 + efi_guid_unparse(&entry->var.VendorGuid, name + len + 1); 1042 + 1043 + name[len+GUID_LEN+1] = '\0'; 1044 + 1045 + inode = efivarfs_get_inode(efivarfs_sb, root->d_inode, 1046 + S_IFREG | 0644, 0); 1047 + if (!inode) 1048 + goto fail_name; 1049 + 1050 + dentry = d_alloc_name(root, name); 1051 + if (!dentry) 1052 + goto fail_inode; 1053 + 1054 + /* copied by the above to local storage in the dentry. */ 1055 + kfree(name); 1056 + 1057 + spin_lock(&efivars->lock); 1058 + efivars->ops->get_variable(entry->var.VariableName, 1059 + &entry->var.VendorGuid, 1060 + &entry->var.Attributes, 1061 + &size, 1062 + NULL); 1063 + spin_unlock(&efivars->lock); 1064 + 1065 + mutex_lock(&inode->i_mutex); 1066 + inode->i_private = entry; 1067 + i_size_write(inode, size+4); 1068 + mutex_unlock(&inode->i_mutex); 1069 + d_add(dentry, inode); 1070 + } 1071 + 1072 + return 0; 1073 + 1074 + fail_inode: 1075 + iput(inode); 1076 + fail_name: 1077 + kfree(name); 1078 + fail: 1079 + return -ENOMEM; 1080 + } 1081 + 1082 + static struct dentry *efivarfs_mount(struct file_system_type *fs_type, 1083 + int flags, const char *dev_name, void *data) 1084 + { 1085 + return mount_single(fs_type, flags, data, efivarfs_fill_super); 1086 + } 1087 + 1088 + static void efivarfs_kill_sb(struct super_block *sb) 1089 + { 1090 + kill_litter_super(sb); 1091 + efivarfs_sb = NULL; 1092 + } 1093 + 1094 + static struct file_system_type efivarfs_type = { 1095 + .name = "efivarfs", 1096 + .mount = efivarfs_mount, 1097 + .kill_sb = efivarfs_kill_sb, 1098 + }; 1099 + 1100 + static const struct inode_operations efivarfs_dir_inode_operations = { 1101 + .lookup = simple_lookup, 1102 + .unlink = efivarfs_unlink, 1103 + .create = efivarfs_create, 1104 + }; 1105 + 1106 + static struct pstore_info efi_pstore_info; 651 1107 652 1108 #ifdef CONFIG_PSTORE 653 1109 ··· 1545 1065 efi_char16_t *variable_name, 1546 1066 efi_guid_t *vendor_guid) 1547 1067 { 1548 - int i, short_name_size = variable_name_size / sizeof(efi_char16_t) + 38; 1068 + int i, short_name_size; 1549 1069 char *short_name; 1550 1070 struct efivar_entry *new_efivar; 1551 1071 1552 - short_name = kzalloc(short_name_size + 1, GFP_KERNEL); 1072 + /* 1073 + * Length of the variable bytes in ASCII, plus the '-' separator, 1074 + * plus the GUID, plus trailing NUL 1075 + */ 1076 + short_name_size = variable_name_size / sizeof(efi_char16_t) 1077 + + 1 + GUID_LEN + 1; 1078 + 1079 + short_name = kzalloc(short_name_size, GFP_KERNEL); 1553 1080 new_efivar = kzalloc(sizeof(struct efivar_entry), GFP_KERNEL); 1554 1081 1555 1082 if (!short_name || !new_efivar) { ··· 1676 1189 sysfs_remove_bin_file(&efivars->kset->kobj, efivars->del_var); 1677 1190 kfree(efivars->new_var); 1678 1191 kfree(efivars->del_var); 1192 + kobject_put(efivars->kobject); 1679 1193 kset_unregister(efivars->kset); 1680 1194 } 1681 1195 EXPORT_SYMBOL_GPL(unregister_efivars); ··· 1705 1217 if (!efivars->kset) { 1706 1218 printk(KERN_ERR "efivars: Subsystem registration failed.\n"); 1707 1219 error = -ENOMEM; 1220 + goto out; 1221 + } 1222 + 1223 + efivars->kobject = kobject_create_and_add("efivars", parent_kobj); 1224 + if (!efivars->kobject) { 1225 + pr_err("efivars: Subsystem registration failed.\n"); 1226 + error = -ENOMEM; 1227 + kset_unregister(efivars->kset); 1708 1228 goto out; 1709 1229 } 1710 1230 ··· 1758 1262 pstore_register(&efivars->efi_pstore_info); 1759 1263 } 1760 1264 1265 + register_filesystem(&efivarfs_type); 1266 + 1761 1267 out: 1762 1268 kfree(variable_name); 1763 1269 1764 1270 return error; 1765 1271 } 1766 1272 EXPORT_SYMBOL_GPL(register_efivars); 1767 - 1768 - static struct efivars __efivars; 1769 - static struct efivar_operations ops; 1770 1273 1771 1274 /* 1772 1275 * For now we register the efi subsystem with the firmware subsystem ··· 1797 1302 ops.set_variable = efi.set_variable; 1798 1303 ops.get_next_variable = efi.get_next_variable; 1799 1304 ops.query_variable_info = efi.query_variable_info; 1305 + 1800 1306 error = register_efivars(&__efivars, &ops, efi_kobj); 1801 1307 if (error) 1802 1308 goto err_put;
+6 -2
include/linux/efi.h
··· 29 29 #define EFI_UNSUPPORTED ( 3 | (1UL << (BITS_PER_LONG-1))) 30 30 #define EFI_BAD_BUFFER_SIZE ( 4 | (1UL << (BITS_PER_LONG-1))) 31 31 #define EFI_BUFFER_TOO_SMALL ( 5 | (1UL << (BITS_PER_LONG-1))) 32 + #define EFI_NOT_READY ( 6 | (1UL << (BITS_PER_LONG-1))) 33 + #define EFI_DEVICE_ERROR ( 7 | (1UL << (BITS_PER_LONG-1))) 34 + #define EFI_WRITE_PROTECTED ( 8 | (1UL << (BITS_PER_LONG-1))) 35 + #define EFI_OUT_OF_RESOURCES ( 9 | (1UL << (BITS_PER_LONG-1))) 32 36 #define EFI_NOT_FOUND (14 | (1UL << (BITS_PER_LONG-1))) 37 + #define EFI_SECURITY_VIOLATION (26 | (1UL << (BITS_PER_LONG-1))) 33 38 34 39 typedef unsigned long efi_status_t; 35 40 typedef u8 efi_bool_t; ··· 587 582 extern int __init efi_uart_console_only (void); 588 583 extern void efi_initialize_iomem_resources(struct resource *code_resource, 589 584 struct resource *data_resource, struct resource *bss_resource); 590 - extern unsigned long efi_get_time(void); 591 - extern int efi_set_rtc_mmss(unsigned long nowtime); 592 585 extern void efi_reserve_boot_services(void); 593 586 extern struct efi_memory_map memmap; 594 587 ··· 732 729 spinlock_t lock; 733 730 struct list_head list; 734 731 struct kset *kset; 732 + struct kobject *kobject; 735 733 struct bin_attribute *new_var, *del_var; 736 734 const struct efivar_operations *ops; 737 735 struct efivar_entry *walk_entry;
+1
include/uapi/linux/magic.h
··· 27 27 #define ISOFS_SUPER_MAGIC 0x9660 28 28 #define JFFS2_SUPER_MAGIC 0x72b6 29 29 #define PSTOREFS_MAGIC 0x6165676C 30 + #define EFIVARFS_MAGIC 0xde5e81e4 30 31 31 32 #define MINIX_SUPER_MAGIC 0x137F /* minix v1 fs, 14 char names */ 32 33 #define MINIX_SUPER_MAGIC2 0x138F /* minix v1 fs, 30 char names */
+4 -4
init/main.c
··· 463 463 percpu_init_late(); 464 464 pgtable_cache_init(); 465 465 vmalloc_init(); 466 + #ifdef CONFIG_X86 467 + if (efi_enabled) 468 + efi_enter_virtual_mode(); 469 + #endif 466 470 } 467 471 468 472 asmlinkage void __init start_kernel(void) ··· 607 603 calibrate_delay(); 608 604 pidmap_init(); 609 605 anon_vma_init(); 610 - #ifdef CONFIG_X86 611 - if (efi_enabled) 612 - efi_enter_virtual_mode(); 613 - #endif 614 606 thread_info_cache_init(); 615 607 cred_init(); 616 608 fork_init(totalram_pages);