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