aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/arm64/include/asm/efi.h4
-rw-r--r--arch/arm64/kernel/Makefile3
-rw-r--r--arch/arm64/kernel/efi-rt-wrapper.S41
-rw-r--r--arch/arm64/kernel/efi.c6
-rw-r--r--arch/x86/boot/compressed/eboot.c3
-rw-r--r--arch/x86/include/asm/efi.h26
-rw-r--r--arch/x86/mm/debug_pagetables.c6
-rw-r--r--arch/x86/platform/efi/efi_64.c60
-rw-r--r--arch/x86/platform/efi/efi_thunk_64.S2
-rw-r--r--arch/x86/platform/efi/quirks.c10
-rw-r--r--drivers/firmware/efi/apple-properties.c20
-rw-r--r--drivers/firmware/efi/arm-runtime.c17
-rw-r--r--drivers/firmware/efi/efi.c11
-rw-r--r--drivers/firmware/efi/esrt.c17
-rw-r--r--drivers/firmware/efi/libstub/Makefile2
-rw-r--r--drivers/firmware/efi/libstub/secureboot.c12
-rw-r--r--drivers/firmware/efi/libstub/tpm.c7
-rw-r--r--include/linux/efi.h2
18 files changed, 141 insertions, 108 deletions
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 8389050328bb..192d791f1103 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -31,7 +31,7 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
31({ \ 31({ \
32 efi_##f##_t *__f; \ 32 efi_##f##_t *__f; \
33 __f = p->f; \ 33 __f = p->f; \
34 __f(args); \ 34 __efi_rt_asm_wrapper(__f, #f, args); \
35}) 35})
36 36
37#define arch_efi_call_virt_teardown() \ 37#define arch_efi_call_virt_teardown() \
@@ -40,6 +40,8 @@ int efi_set_mapping_permissions(struct mm_struct *mm, efi_memory_desc_t *md);
40 efi_virtmap_unload(); \ 40 efi_virtmap_unload(); \
41}) 41})
42 42
43efi_status_t __efi_rt_asm_wrapper(void *, const char *, ...);
44
43#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT) 45#define ARCH_EFI_IRQ_FLAGS_MASK (PSR_D_BIT | PSR_A_BIT | PSR_I_BIT | PSR_F_BIT)
44 46
45/* arch specific definitions used by the stub code */ 47/* arch specific definitions used by the stub code */
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index b87541360f43..6a4bd80c75bd 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -38,7 +38,8 @@ arm64-obj-$(CONFIG_CPU_PM) += sleep.o suspend.o
38arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o 38arm64-obj-$(CONFIG_CPU_IDLE) += cpuidle.o
39arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o 39arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o
40arm64-obj-$(CONFIG_KGDB) += kgdb.o 40arm64-obj-$(CONFIG_KGDB) += kgdb.o
41arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o 41arm64-obj-$(CONFIG_EFI) += efi.o efi-entry.stub.o \
42 efi-rt-wrapper.o
42arm64-obj-$(CONFIG_PCI) += pci.o 43arm64-obj-$(CONFIG_PCI) += pci.o
43arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o 44arm64-obj-$(CONFIG_ARMV8_DEPRECATED) += armv8_deprecated.o
44arm64-obj-$(CONFIG_ACPI) += acpi.o 45arm64-obj-$(CONFIG_ACPI) += acpi.o
diff --git a/arch/arm64/kernel/efi-rt-wrapper.S b/arch/arm64/kernel/efi-rt-wrapper.S
new file mode 100644
index 000000000000..05235ebb336d
--- /dev/null
+++ b/arch/arm64/kernel/efi-rt-wrapper.S
@@ -0,0 +1,41 @@
1/*
2 * Copyright (C) 2018 Linaro Ltd <ard.biesheuvel@linaro.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include <linux/linkage.h>
10
11ENTRY(__efi_rt_asm_wrapper)
12 stp x29, x30, [sp, #-32]!
13 mov x29, sp
14
15 /*
16 * Register x18 is designated as the 'platform' register by the AAPCS,
17 * which means firmware running at the same exception level as the OS
18 * (such as UEFI) should never touch it.
19 */
20 stp x1, x18, [sp, #16]
21
22 /*
23 * We are lucky enough that no EFI runtime services take more than
24 * 5 arguments, so all are passed in registers rather than via the
25 * stack.
26 */
27 mov x8, x0
28 mov x0, x2
29 mov x1, x3
30 mov x2, x4
31 mov x3, x5
32 mov x4, x6
33 blr x8
34
35 ldp x1, x2, [sp, #16]
36 cmp x2, x18
37 ldp x29, x30, [sp], #32
38 b.ne 0f
39 ret
400: b efi_handle_corrupted_x18 // tail call
41ENDPROC(__efi_rt_asm_wrapper)
diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c
index a8bf1c892b90..4f9acb5fbe97 100644
--- a/arch/arm64/kernel/efi.c
+++ b/arch/arm64/kernel/efi.c
@@ -126,3 +126,9 @@ bool efi_poweroff_required(void)
126{ 126{
127 return efi_enabled(EFI_RUNTIME_SERVICES); 127 return efi_enabled(EFI_RUNTIME_SERVICES);
128} 128}
129
130asmlinkage efi_status_t efi_handle_corrupted_x18(efi_status_t s, const char *f)
131{
132 pr_err_ratelimited(FW_BUG "register x18 corrupted by EFI %s\n", f);
133 return s;
134}
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 886a9115af62..47d3efff6805 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -421,9 +421,10 @@ static void retrieve_apple_device_properties(struct boot_params *boot_params)
421 } 421 }
422} 422}
423 423
424static const efi_char16_t apple[] = L"Apple";
425
424static void setup_quirks(struct boot_params *boot_params) 426static void setup_quirks(struct boot_params *boot_params)
425{ 427{
426 efi_char16_t const apple[] = { 'A', 'p', 'p', 'l', 'e', 0 };
427 efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long) 428 efi_char16_t *fw_vendor = (efi_char16_t *)(unsigned long)
428 efi_table_attr(efi_system_table, fw_vendor, sys_table); 429 efi_table_attr(efi_system_table, fw_vendor, sys_table);
429 430
diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h
index a399c1ebf6f0..cec5fae23eb3 100644
--- a/arch/x86/include/asm/efi.h
+++ b/arch/x86/include/asm/efi.h
@@ -7,6 +7,7 @@
7#include <asm/processor-flags.h> 7#include <asm/processor-flags.h>
8#include <asm/tlb.h> 8#include <asm/tlb.h>
9#include <asm/nospec-branch.h> 9#include <asm/nospec-branch.h>
10#include <asm/mmu_context.h>
10 11
11/* 12/*
12 * We map the EFI regions needed for runtime services non-contiguously, 13 * We map the EFI regions needed for runtime services non-contiguously,
@@ -69,14 +70,13 @@ extern asmlinkage u64 efi_call(void *fp, ...);
69#define efi_call_phys(f, args...) efi_call((f), args) 70#define efi_call_phys(f, args...) efi_call((f), args)
70 71
71/* 72/*
72 * Scratch space used for switching the pagetable in the EFI stub 73 * struct efi_scratch - Scratch space used while switching to/from efi_mm
74 * @phys_stack: stack used during EFI Mixed Mode
75 * @prev_mm: store/restore stolen mm_struct while switching to/from efi_mm
73 */ 76 */
74struct efi_scratch { 77struct efi_scratch {
75 u64 r15; 78 u64 phys_stack;
76 u64 prev_cr3; 79 struct mm_struct *prev_mm;
77 pgd_t *efi_pgt;
78 bool use_pgd;
79 u64 phys_stack;
80} __packed; 80} __packed;
81 81
82#define arch_efi_call_virt_setup() \ 82#define arch_efi_call_virt_setup() \
@@ -86,11 +86,8 @@ struct efi_scratch {
86 __kernel_fpu_begin(); \ 86 __kernel_fpu_begin(); \
87 firmware_restrict_branch_speculation_start(); \ 87 firmware_restrict_branch_speculation_start(); \
88 \ 88 \
89 if (efi_scratch.use_pgd) { \ 89 if (!efi_enabled(EFI_OLD_MEMMAP)) \
90 efi_scratch.prev_cr3 = __read_cr3(); \ 90 efi_switch_mm(&efi_mm); \
91 write_cr3((unsigned long)efi_scratch.efi_pgt); \
92 __flush_tlb_all(); \
93 } \
94}) 91})
95 92
96#define arch_efi_call_virt(p, f, args...) \ 93#define arch_efi_call_virt(p, f, args...) \
@@ -98,10 +95,8 @@ struct efi_scratch {
98 95
99#define arch_efi_call_virt_teardown() \ 96#define arch_efi_call_virt_teardown() \
100({ \ 97({ \
101 if (efi_scratch.use_pgd) { \ 98 if (!efi_enabled(EFI_OLD_MEMMAP)) \
102 write_cr3(efi_scratch.prev_cr3); \ 99 efi_switch_mm(efi_scratch.prev_mm); \
103 __flush_tlb_all(); \
104 } \
105 \ 100 \
106 firmware_restrict_branch_speculation_end(); \ 101 firmware_restrict_branch_speculation_end(); \
107 __kernel_fpu_end(); \ 102 __kernel_fpu_end(); \
@@ -144,6 +139,7 @@ extern void __init efi_dump_pagetable(void);
144extern void __init efi_apply_memmap_quirks(void); 139extern void __init efi_apply_memmap_quirks(void);
145extern int __init efi_reuse_config(u64 tables, int nr_tables); 140extern int __init efi_reuse_config(u64 tables, int nr_tables);
146extern void efi_delete_dummy_variable(void); 141extern void efi_delete_dummy_variable(void);
142extern void efi_switch_mm(struct mm_struct *mm);
147 143
148struct efi_setup_data { 144struct efi_setup_data {
149 u64 fw_vendor; 145 u64 fw_vendor;
diff --git a/arch/x86/mm/debug_pagetables.c b/arch/x86/mm/debug_pagetables.c
index 51a6f92da2bf..225fe2f0bfec 100644
--- a/arch/x86/mm/debug_pagetables.c
+++ b/arch/x86/mm/debug_pagetables.c
@@ -1,4 +1,5 @@
1#include <linux/debugfs.h> 1#include <linux/debugfs.h>
2#include <linux/efi.h>
2#include <linux/module.h> 3#include <linux/module.h>
3#include <linux/seq_file.h> 4#include <linux/seq_file.h>
4#include <asm/pgtable.h> 5#include <asm/pgtable.h>
@@ -73,13 +74,12 @@ static const struct file_operations ptdump_curusr_fops = {
73#endif 74#endif
74 75
75#if defined(CONFIG_EFI) && defined(CONFIG_X86_64) 76#if defined(CONFIG_EFI) && defined(CONFIG_X86_64)
76extern pgd_t *efi_pgd;
77static struct dentry *pe_efi; 77static struct dentry *pe_efi;
78 78
79static int ptdump_show_efi(struct seq_file *m, void *v) 79static int ptdump_show_efi(struct seq_file *m, void *v)
80{ 80{
81 if (efi_pgd) 81 if (efi_mm.pgd)
82 ptdump_walk_pgd_level_debugfs(m, efi_pgd, false); 82 ptdump_walk_pgd_level_debugfs(m, efi_mm.pgd, false);
83 return 0; 83 return 0;
84} 84}
85 85
diff --git a/arch/x86/platform/efi/efi_64.c b/arch/x86/platform/efi/efi_64.c
index 7f443bd1411d..bed7e7f4e44c 100644
--- a/arch/x86/platform/efi/efi_64.c
+++ b/arch/x86/platform/efi/efi_64.c
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/ucs2_string.h> 35#include <linux/ucs2_string.h>
36#include <linux/mem_encrypt.h> 36#include <linux/mem_encrypt.h>
37#include <linux/sched/task.h>
37 38
38#include <asm/setup.h> 39#include <asm/setup.h>
39#include <asm/page.h> 40#include <asm/page.h>
@@ -82,9 +83,8 @@ pgd_t * __init efi_call_phys_prolog(void)
82 int n_pgds, i, j; 83 int n_pgds, i, j;
83 84
84 if (!efi_enabled(EFI_OLD_MEMMAP)) { 85 if (!efi_enabled(EFI_OLD_MEMMAP)) {
85 save_pgd = (pgd_t *)__read_cr3(); 86 efi_switch_mm(&efi_mm);
86 write_cr3((unsigned long)efi_scratch.efi_pgt); 87 return NULL;
87 goto out;
88 } 88 }
89 89
90 early_code_mapping_set_exec(1); 90 early_code_mapping_set_exec(1);
@@ -156,8 +156,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
156 pud_t *pud; 156 pud_t *pud;
157 157
158 if (!efi_enabled(EFI_OLD_MEMMAP)) { 158 if (!efi_enabled(EFI_OLD_MEMMAP)) {
159 write_cr3((unsigned long)save_pgd); 159 efi_switch_mm(efi_scratch.prev_mm);
160 __flush_tlb_all();
161 return; 160 return;
162 } 161 }
163 162
@@ -191,8 +190,7 @@ void __init efi_call_phys_epilog(pgd_t *save_pgd)
191 early_code_mapping_set_exec(0); 190 early_code_mapping_set_exec(0);
192} 191}
193 192
194pgd_t *efi_pgd; 193EXPORT_SYMBOL_GPL(efi_mm);
195EXPORT_SYMBOL_GPL(efi_pgd);
196 194
197/* 195/*
198 * We need our own copy of the higher levels of the page tables 196 * We need our own copy of the higher levels of the page tables
@@ -205,7 +203,7 @@ EXPORT_SYMBOL_GPL(efi_pgd);
205 */ 203 */
206int __init efi_alloc_page_tables(void) 204int __init efi_alloc_page_tables(void)
207{ 205{
208 pgd_t *pgd; 206 pgd_t *pgd, *efi_pgd;
209 p4d_t *p4d; 207 p4d_t *p4d;
210 pud_t *pud; 208 pud_t *pud;
211 gfp_t gfp_mask; 209 gfp_t gfp_mask;
@@ -233,6 +231,10 @@ int __init efi_alloc_page_tables(void)
233 return -ENOMEM; 231 return -ENOMEM;
234 } 232 }
235 233
234 efi_mm.pgd = efi_pgd;
235 mm_init_cpumask(&efi_mm);
236 init_new_context(NULL, &efi_mm);
237
236 return 0; 238 return 0;
237} 239}
238 240
@@ -245,6 +247,7 @@ void efi_sync_low_kernel_mappings(void)
245 pgd_t *pgd_k, *pgd_efi; 247 pgd_t *pgd_k, *pgd_efi;
246 p4d_t *p4d_k, *p4d_efi; 248 p4d_t *p4d_k, *p4d_efi;
247 pud_t *pud_k, *pud_efi; 249 pud_t *pud_k, *pud_efi;
250 pgd_t *efi_pgd = efi_mm.pgd;
248 251
249 if (efi_enabled(EFI_OLD_MEMMAP)) 252 if (efi_enabled(EFI_OLD_MEMMAP))
250 return; 253 return;
@@ -338,20 +341,12 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
338 unsigned long pfn, text, pf; 341 unsigned long pfn, text, pf;
339 struct page *page; 342 struct page *page;
340 unsigned npages; 343 unsigned npages;
341 pgd_t *pgd; 344 pgd_t *pgd = efi_mm.pgd;
342 345
343 if (efi_enabled(EFI_OLD_MEMMAP)) 346 if (efi_enabled(EFI_OLD_MEMMAP))
344 return 0; 347 return 0;
345 348
346 /* 349 /*
347 * Since the PGD is encrypted, set the encryption mask so that when
348 * this value is loaded into cr3 the PGD will be decrypted during
349 * the pagetable walk.
350 */
351 efi_scratch.efi_pgt = (pgd_t *)__sme_pa(efi_pgd);
352 pgd = efi_pgd;
353
354 /*
355 * It can happen that the physical address of new_memmap lands in memory 350 * It can happen that the physical address of new_memmap lands in memory
356 * which is not mapped in the EFI page table. Therefore we need to go 351 * which is not mapped in the EFI page table. Therefore we need to go
357 * and ident-map those pages containing the map before calling 352 * and ident-map those pages containing the map before calling
@@ -364,8 +359,6 @@ int __init efi_setup_page_tables(unsigned long pa_memmap, unsigned num_pages)
364 return 1; 359 return 1;
365 } 360 }
366 361
367 efi_scratch.use_pgd = true;
368
369 /* 362 /*
370 * Certain firmware versions are way too sentimential and still believe 363 * Certain firmware versions are way too sentimential and still believe
371 * they are exclusive and unquestionable owners of the first physical page, 364 * they are exclusive and unquestionable owners of the first physical page,
@@ -419,7 +412,7 @@ static void __init __map_region(efi_memory_desc_t *md, u64 va)
419{ 412{
420 unsigned long flags = _PAGE_RW; 413 unsigned long flags = _PAGE_RW;
421 unsigned long pfn; 414 unsigned long pfn;
422 pgd_t *pgd = efi_pgd; 415 pgd_t *pgd = efi_mm.pgd;
423 416
424 if (!(md->attribute & EFI_MEMORY_WB)) 417 if (!(md->attribute & EFI_MEMORY_WB))
425 flags |= _PAGE_PCD; 418 flags |= _PAGE_PCD;
@@ -523,7 +516,7 @@ void __init parse_efi_setup(u64 phys_addr, u32 data_len)
523static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf) 516static int __init efi_update_mappings(efi_memory_desc_t *md, unsigned long pf)
524{ 517{
525 unsigned long pfn; 518 unsigned long pfn;
526 pgd_t *pgd = efi_pgd; 519 pgd_t *pgd = efi_mm.pgd;
527 int err1, err2; 520 int err1, err2;
528 521
529 /* Update the 1:1 mapping */ 522 /* Update the 1:1 mapping */
@@ -620,10 +613,26 @@ void __init efi_dump_pagetable(void)
620 if (efi_enabled(EFI_OLD_MEMMAP)) 613 if (efi_enabled(EFI_OLD_MEMMAP))
621 ptdump_walk_pgd_level(NULL, swapper_pg_dir); 614 ptdump_walk_pgd_level(NULL, swapper_pg_dir);
622 else 615 else
623 ptdump_walk_pgd_level(NULL, efi_pgd); 616 ptdump_walk_pgd_level(NULL, efi_mm.pgd);
624#endif 617#endif
625} 618}
626 619
620/*
621 * Makes the calling thread switch to/from efi_mm context. Can be used
622 * for SetVirtualAddressMap() i.e. current->active_mm == init_mm as well
623 * as during efi runtime calls i.e current->active_mm == current_mm.
624 * We are not mm_dropping()/mm_grabbing() any mm, because we are not
625 * losing/creating any references.
626 */
627void efi_switch_mm(struct mm_struct *mm)
628{
629 task_lock(current);
630 efi_scratch.prev_mm = current->active_mm;
631 current->active_mm = mm;
632 switch_mm(efi_scratch.prev_mm, mm, NULL);
633 task_unlock(current);
634}
635
627#ifdef CONFIG_EFI_MIXED 636#ifdef CONFIG_EFI_MIXED
628extern efi_status_t efi64_thunk(u32, ...); 637extern efi_status_t efi64_thunk(u32, ...);
629 638
@@ -677,16 +686,13 @@ efi_status_t efi_thunk_set_virtual_address_map(
677 efi_sync_low_kernel_mappings(); 686 efi_sync_low_kernel_mappings();
678 local_irq_save(flags); 687 local_irq_save(flags);
679 688
680 efi_scratch.prev_cr3 = __read_cr3(); 689 efi_switch_mm(&efi_mm);
681 write_cr3((unsigned long)efi_scratch.efi_pgt);
682 __flush_tlb_all();
683 690
684 func = (u32)(unsigned long)phys_set_virtual_address_map; 691 func = (u32)(unsigned long)phys_set_virtual_address_map;
685 status = efi64_thunk(func, memory_map_size, descriptor_size, 692 status = efi64_thunk(func, memory_map_size, descriptor_size,
686 descriptor_version, virtual_map); 693 descriptor_version, virtual_map);
687 694
688 write_cr3(efi_scratch.prev_cr3); 695 efi_switch_mm(efi_scratch.prev_mm);
689 __flush_tlb_all();
690 local_irq_restore(flags); 696 local_irq_restore(flags);
691 697
692 return status; 698 return status;
diff --git a/arch/x86/platform/efi/efi_thunk_64.S b/arch/x86/platform/efi/efi_thunk_64.S
index 189b218da87c..46c58b08739c 100644
--- a/arch/x86/platform/efi/efi_thunk_64.S
+++ b/arch/x86/platform/efi/efi_thunk_64.S
@@ -33,7 +33,7 @@ ENTRY(efi64_thunk)
33 * Switch to 1:1 mapped 32-bit stack pointer. 33 * Switch to 1:1 mapped 32-bit stack pointer.
34 */ 34 */
35 movq %rsp, efi_saved_sp(%rip) 35 movq %rsp, efi_saved_sp(%rip)
36 movq efi_scratch+25(%rip), %rsp 36 movq efi_scratch(%rip), %rsp
37 37
38 /* 38 /*
39 * Calculate the physical address of the kernel text. 39 * Calculate the physical address of the kernel text.
diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c
index 5b513ccffde4..36c1f8b9f7e0 100644
--- a/arch/x86/platform/efi/quirks.c
+++ b/arch/x86/platform/efi/quirks.c
@@ -75,7 +75,7 @@ struct quark_security_header {
75 u32 rsvd[2]; 75 u32 rsvd[2];
76}; 76};
77 77
78static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; 78static const efi_char16_t efi_dummy_name[] = L"DUMMY";
79 79
80static bool efi_no_storage_paranoia; 80static bool efi_no_storage_paranoia;
81 81
@@ -105,7 +105,8 @@ early_param("efi_no_storage_paranoia", setup_storage_paranoia);
105*/ 105*/
106void efi_delete_dummy_variable(void) 106void efi_delete_dummy_variable(void)
107{ 107{
108 efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, 108 efi.set_variable((efi_char16_t *)efi_dummy_name,
109 &EFI_DUMMY_GUID,
109 EFI_VARIABLE_NON_VOLATILE | 110 EFI_VARIABLE_NON_VOLATILE |
110 EFI_VARIABLE_BOOTSERVICE_ACCESS | 111 EFI_VARIABLE_BOOTSERVICE_ACCESS |
111 EFI_VARIABLE_RUNTIME_ACCESS, 112 EFI_VARIABLE_RUNTIME_ACCESS,
@@ -177,12 +178,13 @@ efi_status_t efi_query_variable_store(u32 attributes, unsigned long size,
177 * that by attempting to use more space than is available. 178 * that by attempting to use more space than is available.
178 */ 179 */
179 unsigned long dummy_size = remaining_size + 1024; 180 unsigned long dummy_size = remaining_size + 1024;
180 void *dummy = kzalloc(dummy_size, GFP_ATOMIC); 181 void *dummy = kzalloc(dummy_size, GFP_KERNEL);
181 182
182 if (!dummy) 183 if (!dummy)
183 return EFI_OUT_OF_RESOURCES; 184 return EFI_OUT_OF_RESOURCES;
184 185
185 status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, 186 status = efi.set_variable((efi_char16_t *)efi_dummy_name,
187 &EFI_DUMMY_GUID,
186 EFI_VARIABLE_NON_VOLATILE | 188 EFI_VARIABLE_NON_VOLATILE |
187 EFI_VARIABLE_BOOTSERVICE_ACCESS | 189 EFI_VARIABLE_BOOTSERVICE_ACCESS |
188 EFI_VARIABLE_RUNTIME_ACCESS, 190 EFI_VARIABLE_RUNTIME_ACCESS,
diff --git a/drivers/firmware/efi/apple-properties.c b/drivers/firmware/efi/apple-properties.c
index 9f6bcf173b0e..adaa9a3714b9 100644
--- a/drivers/firmware/efi/apple-properties.c
+++ b/drivers/firmware/efi/apple-properties.c
@@ -19,6 +19,7 @@
19 19
20#include <linux/bootmem.h> 20#include <linux/bootmem.h>
21#include <linux/efi.h> 21#include <linux/efi.h>
22#include <linux/io.h>
22#include <linux/platform_data/x86/apple.h> 23#include <linux/platform_data/x86/apple.h>
23#include <linux/property.h> 24#include <linux/property.h>
24#include <linux/slab.h> 25#include <linux/slab.h>
@@ -52,8 +53,6 @@ struct properties_header {
52 struct dev_header dev_header[0]; 53 struct dev_header dev_header[0];
53}; 54};
54 55
55static u8 one __initdata = 1;
56
57static void __init unmarshal_key_value_pairs(struct dev_header *dev_header, 56static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
58 struct device *dev, void *ptr, 57 struct device *dev, void *ptr,
59 struct property_entry entry[]) 58 struct property_entry entry[])
@@ -95,14 +94,9 @@ static void __init unmarshal_key_value_pairs(struct dev_header *dev_header,
95 key_len - sizeof(key_len)); 94 key_len - sizeof(key_len));
96 95
97 entry[i].name = key; 96 entry[i].name = key;
98 entry[i].is_array = true;
99 entry[i].length = val_len - sizeof(val_len); 97 entry[i].length = val_len - sizeof(val_len);
98 entry[i].is_array = !!entry[i].length;
100 entry[i].pointer.raw_data = ptr + key_len + sizeof(val_len); 99 entry[i].pointer.raw_data = ptr + key_len + sizeof(val_len);
101 if (!entry[i].length) {
102 /* driver core doesn't accept empty properties */
103 entry[i].length = 1;
104 entry[i].pointer.raw_data = &one;
105 }
106 100
107 if (dump_properties) { 101 if (dump_properties) {
108 dev_info(dev, "property: %s\n", entry[i].name); 102 dev_info(dev, "property: %s\n", entry[i].name);
@@ -196,7 +190,7 @@ static int __init map_properties(void)
196 190
197 pa_data = boot_params.hdr.setup_data; 191 pa_data = boot_params.hdr.setup_data;
198 while (pa_data) { 192 while (pa_data) {
199 data = ioremap(pa_data, sizeof(*data)); 193 data = memremap(pa_data, sizeof(*data), MEMREMAP_WB);
200 if (!data) { 194 if (!data) {
201 pr_err("cannot map setup_data header\n"); 195 pr_err("cannot map setup_data header\n");
202 return -ENOMEM; 196 return -ENOMEM;
@@ -204,14 +198,14 @@ static int __init map_properties(void)
204 198
205 if (data->type != SETUP_APPLE_PROPERTIES) { 199 if (data->type != SETUP_APPLE_PROPERTIES) {
206 pa_data = data->next; 200 pa_data = data->next;
207 iounmap(data); 201 memunmap(data);
208 continue; 202 continue;
209 } 203 }
210 204
211 data_len = data->len; 205 data_len = data->len;
212 iounmap(data); 206 memunmap(data);
213 207
214 data = ioremap(pa_data, sizeof(*data) + data_len); 208 data = memremap(pa_data, sizeof(*data) + data_len, MEMREMAP_WB);
215 if (!data) { 209 if (!data) {
216 pr_err("cannot map setup_data payload\n"); 210 pr_err("cannot map setup_data payload\n");
217 return -ENOMEM; 211 return -ENOMEM;
@@ -236,7 +230,7 @@ static int __init map_properties(void)
236 * to avoid breaking the chain of ->next pointers. 230 * to avoid breaking the chain of ->next pointers.
237 */ 231 */
238 data->len = 0; 232 data->len = 0;
239 iounmap(data); 233 memunmap(data);
240 free_bootmem_late(pa_data + sizeof(*data), data_len); 234 free_bootmem_late(pa_data + sizeof(*data), data_len);
241 235
242 return ret; 236 return ret;
diff --git a/drivers/firmware/efi/arm-runtime.c b/drivers/firmware/efi/arm-runtime.c
index 1cc41c3d6315..5889cbea60b8 100644
--- a/drivers/firmware/efi/arm-runtime.c
+++ b/drivers/firmware/efi/arm-runtime.c
@@ -31,15 +31,6 @@
31 31
32extern u64 efi_system_table; 32extern u64 efi_system_table;
33 33
34static struct mm_struct efi_mm = {
35 .mm_rb = RB_ROOT,
36 .mm_users = ATOMIC_INIT(2),
37 .mm_count = ATOMIC_INIT(1),
38 .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
39 .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
40 .mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
41};
42
43#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS 34#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS
44#include <asm/ptdump.h> 35#include <asm/ptdump.h>
45 36
@@ -54,6 +45,9 @@ static struct ptdump_info efi_ptdump_info = {
54 45
55static int __init ptdump_init(void) 46static int __init ptdump_init(void)
56{ 47{
48 if (!efi_enabled(EFI_RUNTIME_SERVICES))
49 return 0;
50
57 return ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables"); 51 return ptdump_debugfs_register(&efi_ptdump_info, "efi_page_tables");
58} 52}
59device_initcall(ptdump_init); 53device_initcall(ptdump_init);
@@ -80,10 +74,7 @@ static bool __init efi_virtmap_init(void)
80 return false; 74 return false;
81 75
82 ret = efi_create_mapping(&efi_mm, md); 76 ret = efi_create_mapping(&efi_mm, md);
83 if (!ret) { 77 if (ret) {
84 pr_info(" EFI remap %pa => %p\n",
85 &phys, (void *)(unsigned long)md->virt_addr);
86 } else {
87 pr_warn(" EFI remap %pa: failed to create mapping (%d)\n", 78 pr_warn(" EFI remap %pa: failed to create mapping (%d)\n",
88 &phys, ret); 79 &phys, ret);
89 return false; 80 return false;
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index cd42f66a7c85..232f4915223b 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -75,6 +75,15 @@ static unsigned long *efi_tables[] = {
75 &efi.mem_attr_table, 75 &efi.mem_attr_table,
76}; 76};
77 77
78struct mm_struct efi_mm = {
79 .mm_rb = RB_ROOT,
80 .mm_users = ATOMIC_INIT(2),
81 .mm_count = ATOMIC_INIT(1),
82 .mmap_sem = __RWSEM_INITIALIZER(efi_mm.mmap_sem),
83 .page_table_lock = __SPIN_LOCK_UNLOCKED(efi_mm.page_table_lock),
84 .mmlist = LIST_HEAD_INIT(efi_mm.mmlist),
85};
86
78static bool disable_runtime; 87static bool disable_runtime;
79static int __init setup_noefi(char *arg) 88static int __init setup_noefi(char *arg)
80{ 89{
@@ -542,9 +551,9 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
542 seed = early_memremap(efi.rng_seed, 551 seed = early_memremap(efi.rng_seed,
543 sizeof(*seed) + size); 552 sizeof(*seed) + size);
544 if (seed != NULL) { 553 if (seed != NULL) {
554 pr_notice("seeding entropy pool\n");
545 add_device_randomness(seed->bits, seed->size); 555 add_device_randomness(seed->bits, seed->size);
546 early_memunmap(seed, sizeof(*seed) + size); 556 early_memunmap(seed, sizeof(*seed) + size);
547 pr_notice("seeding entropy pool\n");
548 } else { 557 } else {
549 pr_err("Could not map UEFI random seed!\n"); 558 pr_err("Could not map UEFI random seed!\n");
550 } 559 }
diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c
index c47e0c6ec00f..1ab80e06e7c5 100644
--- a/drivers/firmware/efi/esrt.c
+++ b/drivers/firmware/efi/esrt.c
@@ -279,6 +279,7 @@ void __init efi_esrt_init(void)
279 } 279 }
280 280
281 memcpy(&tmpesrt, va, sizeof(tmpesrt)); 281 memcpy(&tmpesrt, va, sizeof(tmpesrt));
282 early_memunmap(va, size);
282 283
283 if (tmpesrt.fw_resource_version == 1) { 284 if (tmpesrt.fw_resource_version == 1) {
284 entry_size = sizeof (*v1_entries); 285 entry_size = sizeof (*v1_entries);
@@ -291,7 +292,7 @@ void __init efi_esrt_init(void)
291 if (tmpesrt.fw_resource_count > 0 && max - size < entry_size) { 292 if (tmpesrt.fw_resource_count > 0 && max - size < entry_size) {
292 pr_err("ESRT memory map entry can only hold the header. (max: %zu size: %zu)\n", 293 pr_err("ESRT memory map entry can only hold the header. (max: %zu size: %zu)\n",
293 max - size, entry_size); 294 max - size, entry_size);
294 goto err_memunmap; 295 return;
295 } 296 }
296 297
297 /* 298 /*
@@ -304,7 +305,7 @@ void __init efi_esrt_init(void)
304 if (tmpesrt.fw_resource_count > 128) { 305 if (tmpesrt.fw_resource_count > 128) {
305 pr_err("ESRT says fw_resource_count has very large value %d.\n", 306 pr_err("ESRT says fw_resource_count has very large value %d.\n",
306 tmpesrt.fw_resource_count); 307 tmpesrt.fw_resource_count);
307 goto err_memunmap; 308 return;
308 } 309 }
309 310
310 /* 311 /*
@@ -315,18 +316,10 @@ void __init efi_esrt_init(void)
315 if (max < size + entries_size) { 316 if (max < size + entries_size) {
316 pr_err("ESRT does not fit on single memory map entry (size: %zu max: %zu)\n", 317 pr_err("ESRT does not fit on single memory map entry (size: %zu max: %zu)\n",
317 size, max); 318 size, max);
318 goto err_memunmap; 319 return;
319 } 320 }
320 321
321 /* remap it with our (plausible) new pages */
322 early_memunmap(va, size);
323 size += entries_size; 322 size += entries_size;
324 va = early_memremap(efi.esrt, size);
325 if (!va) {
326 pr_err("early_memremap(%p, %zu) failed.\n", (void *)efi.esrt,
327 size);
328 return;
329 }
330 323
331 esrt_data = (phys_addr_t)efi.esrt; 324 esrt_data = (phys_addr_t)efi.esrt;
332 esrt_data_size = size; 325 esrt_data_size = size;
@@ -336,8 +329,6 @@ void __init efi_esrt_init(void)
336 efi_mem_reserve(esrt_data, esrt_data_size); 329 efi_mem_reserve(esrt_data, esrt_data_size);
337 330
338 pr_debug("esrt-init: loaded.\n"); 331 pr_debug("esrt-init: loaded.\n");
339err_memunmap:
340 early_memunmap(va, size);
341} 332}
342 333
343static int __init register_entries(void) 334static int __init register_entries(void)
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 7b3ba40f0745..a34e9290a699 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -9,7 +9,7 @@ cflags-$(CONFIG_X86_32) := -march=i386
9cflags-$(CONFIG_X86_64) := -mcmodel=small 9cflags-$(CONFIG_X86_64) := -mcmodel=small
10cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \ 10cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \
11 -fPIC -fno-strict-aliasing -mno-red-zone \ 11 -fPIC -fno-strict-aliasing -mno-red-zone \
12 -mno-mmx -mno-sse 12 -mno-mmx -mno-sse -fshort-wchar
13 13
14cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie 14cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie
15cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \ 15cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \
diff --git a/drivers/firmware/efi/libstub/secureboot.c b/drivers/firmware/efi/libstub/secureboot.c
index 959777ec8a77..8f07eb414c00 100644
--- a/drivers/firmware/efi/libstub/secureboot.c
+++ b/drivers/firmware/efi/libstub/secureboot.c
@@ -16,18 +16,12 @@
16 16
17/* BIOS variables */ 17/* BIOS variables */
18static const efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID; 18static const efi_guid_t efi_variable_guid = EFI_GLOBAL_VARIABLE_GUID;
19static const efi_char16_t efi_SecureBoot_name[] = { 19static const efi_char16_t efi_SecureBoot_name[] = L"SecureBoot";
20 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 20static const efi_char16_t efi_SetupMode_name[] = L"SetupMode";
21};
22static const efi_char16_t efi_SetupMode_name[] = {
23 'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0
24};
25 21
26/* SHIM variables */ 22/* SHIM variables */
27static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID; 23static const efi_guid_t shim_guid = EFI_SHIM_LOCK_GUID;
28static efi_char16_t const shim_MokSBState_name[] = { 24static const efi_char16_t shim_MokSBState_name[] = L"MokSBState";
29 'M', 'o', 'k', 'S', 'B', 'S', 't', 'a', 't', 'e', 0
30};
31 25
32#define get_efi_var(name, vendor, ...) \ 26#define get_efi_var(name, vendor, ...) \
33 efi_call_runtime(get_variable, \ 27 efi_call_runtime(get_variable, \
diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c
index 13c1edd37e96..9d08cea3f1b0 100644
--- a/drivers/firmware/efi/libstub/tpm.c
+++ b/drivers/firmware/efi/libstub/tpm.c
@@ -16,11 +16,8 @@
16#include "efistub.h" 16#include "efistub.h"
17 17
18#ifdef CONFIG_RESET_ATTACK_MITIGATION 18#ifdef CONFIG_RESET_ATTACK_MITIGATION
19static const efi_char16_t efi_MemoryOverWriteRequest_name[] = { 19static const efi_char16_t efi_MemoryOverWriteRequest_name[] =
20 'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't', 20 L"MemoryOverwriteRequestControl";
21 'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o',
22 'l', 0
23};
24 21
25#define MEMORY_ONLY_RESET_CONTROL_GUID \ 22#define MEMORY_ONLY_RESET_CONTROL_GUID \
26 EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29) 23 EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
diff --git a/include/linux/efi.h b/include/linux/efi.h
index f5083aa72eae..f1b7d68ac460 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -966,6 +966,8 @@ extern struct efi {
966 unsigned long flags; 966 unsigned long flags;
967} efi; 967} efi;
968 968
969extern struct mm_struct efi_mm;
970
969static inline int 971static inline int
970efi_guidcmp (efi_guid_t left, efi_guid_t right) 972efi_guidcmp (efi_guid_t left, efi_guid_t right)
971{ 973{