aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-09-07 12:42:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2017-09-07 12:42:35 -0400
commitf92e3da18b7d5941468040af962c201235148301 (patch)
tree45b05ba50dfe4c5de9cf99b889297a6b51449a8b
parent57e88b43b81301d9b28f124a5576ac43a1cf9e8d (diff)
parent6de47a5e371f75f80544986e6c9636211a2ae8af (diff)
Merge branch 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull EFI updates from Ingo Molnar: "The main changes in this cycle were: - Transparently fall back to other poweroff method(s) if EFI poweroff fails (and returns) - Use separate PE/COFF section headers for the RX and RW parts of the ARM stub loader so that the firmware can use strict mapping permissions - Add support for requesting the firmware to wipe RAM at warm reboot - Increase the size of the random seed obtained from UEFI so CRNG fast init can complete earlier - Update the EFI framebuffer address if it points to a BAR that gets moved by the PCI resource allocation code - Enable "reset attack mitigation" of TPM environments: this is enabled if the kernel is configured with CONFIG_RESET_ATTACK_MITIGATION=y. - Clang related fixes - Misc cleanups, constification, refactoring, etc" * 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: efi/bgrt: Use efi_mem_type() efi: Move efi_mem_type() to common code efi/reboot: Make function pointer orig_pm_power_off static efi/random: Increase size of firmware supplied randomness efi/libstub: Enable reset attack mitigation firmware/efi/esrt: Constify attribute_group structures firmware/efi: Constify attribute_group structures firmware/dcdbas: Constify attribute_group structures arm/efi: Split zImage code and data into separate PE/COFF sections arm/efi: Replace open coded constants with symbolic ones arm/efi: Remove pointless dummy .reloc section arm/efi: Remove forbidden values from the PE/COFF header drivers/fbdev/efifb: Allow BAR to be moved instead of claiming it efi/reboot: Fall back to original power-off method if EFI_RESET_SHUTDOWN returns efi/arm/arm64: Add missing assignment of efi.config_table efi/libstub/arm64: Set -fpie when building the EFI stub efi/libstub/arm64: Force 'hidden' visibility for section markers efi/libstub/arm64: Use hidden attribute for struct screen_info reference efi/arm: Don't mark ACPI reclaim memory as MEMBLOCK_NOMAP
-rw-r--r--arch/arm/boot/compressed/efi-header.S160
-rw-r--r--arch/arm/boot/compressed/vmlinux.lds.S30
-rw-r--r--arch/arm64/include/asm/efi.h3
-rw-r--r--arch/x86/boot/compressed/eboot.c3
-rw-r--r--arch/x86/platform/efi/efi.c19
-rw-r--r--drivers/firmware/dcdbas.c2
-rw-r--r--drivers/firmware/efi/Kconfig10
-rw-r--r--drivers/firmware/efi/arm-init.c8
-rw-r--r--drivers/firmware/efi/efi-bgrt.c22
-rw-r--r--drivers/firmware/efi/efi.c42
-rw-r--r--drivers/firmware/efi/esrt.c2
-rw-r--r--drivers/firmware/efi/libstub/Makefile3
-rw-r--r--drivers/firmware/efi/libstub/arm-stub.c3
-rw-r--r--drivers/firmware/efi/libstub/arm64-stub.c10
-rw-r--r--drivers/firmware/efi/libstub/random.c10
-rw-r--r--drivers/firmware/efi/libstub/tpm.c58
-rw-r--r--drivers/firmware/efi/reboot.c12
-rw-r--r--drivers/video/fbdev/efifb.c31
-rw-r--r--include/linux/efi.h9
19 files changed, 280 insertions, 157 deletions
diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S
index a17ca8d78656..c94a88ae834d 100644
--- a/arch/arm/boot/compressed/efi-header.S
+++ b/arch/arm/boot/compressed/efi-header.S
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2013-2015 Linaro Ltd 2 * Copyright (C) 2013-2017 Linaro Ltd
3 * Authors: Roy Franz <roy.franz@linaro.org> 3 * Authors: Roy Franz <roy.franz@linaro.org>
4 * Ard Biesheuvel <ard.biesheuvel@linaro.org> 4 * Ard Biesheuvel <ard.biesheuvel@linaro.org>
5 * 5 *
@@ -8,6 +8,9 @@
8 * published by the Free Software Foundation. 8 * published by the Free Software Foundation.
9 */ 9 */
10 10
11#include <linux/pe.h>
12#include <linux/sizes.h>
13
11 .macro __nop 14 .macro __nop
12#ifdef CONFIG_EFI_STUB 15#ifdef CONFIG_EFI_STUB
13 @ This is almost but not quite a NOP, since it does clobber the 16 @ This is almost but not quite a NOP, since it does clobber the
@@ -15,7 +18,7 @@
15 @ PE/COFF expects the magic string "MZ" at offset 0, while the 18 @ PE/COFF expects the magic string "MZ" at offset 0, while the
16 @ ARM/Linux boot protocol expects an executable instruction 19 @ ARM/Linux boot protocol expects an executable instruction
17 @ there. 20 @ there.
18 .inst 'M' | ('Z' << 8) | (0x1310 << 16) @ tstne r0, #0x4d000 21 .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000
19#else 22#else
20 AR_CLASS( mov r0, r0 ) 23 AR_CLASS( mov r0, r0 )
21 M_CLASS( nop.w ) 24 M_CLASS( nop.w )
@@ -34,96 +37,97 @@
34 @ The only 2 fields of the MSDOS header that are used are this 37 @ The only 2 fields of the MSDOS header that are used are this
35 @ PE/COFF offset, and the "MZ" bytes at offset 0x0. 38 @ PE/COFF offset, and the "MZ" bytes at offset 0x0.
36 @ 39 @
37 .long pe_header - start @ Offset to the PE header. 40 .long pe_header - start @ Offset to the PE header.
38 41
39pe_header: 42pe_header:
40 .ascii "PE\0\0" 43 .long PE_MAGIC
41 44
42coff_header: 45coff_header:
43 .short 0x01c2 @ ARM or Thumb 46 .short IMAGE_FILE_MACHINE_THUMB @ Machine
44 .short 2 @ nr_sections 47 .short section_count @ NumberOfSections
45 .long 0 @ TimeDateStamp 48 .long 0 @ TimeDateStamp
46 .long 0 @ PointerToSymbolTable 49 .long 0 @ PointerToSymbolTable
47 .long 1 @ NumberOfSymbols 50 .long 0 @ NumberOfSymbols
48 .short section_table - optional_header 51 .short section_table - optional_header @ SizeOfOptionalHeader
49 @ SizeOfOptionalHeader 52 .short IMAGE_FILE_32BIT_MACHINE | \
50 .short 0x306 @ Characteristics. 53 IMAGE_FILE_DEBUG_STRIPPED | \
51 @ IMAGE_FILE_32BIT_MACHINE | 54 IMAGE_FILE_EXECUTABLE_IMAGE | \
52 @ IMAGE_FILE_DEBUG_STRIPPED | 55 IMAGE_FILE_LINE_NUMS_STRIPPED @ Characteristics
53 @ IMAGE_FILE_EXECUTABLE_IMAGE | 56
54 @ IMAGE_FILE_LINE_NUMS_STRIPPED 57#define __pecoff_code_size (__pecoff_data_start - __efi_start)
55 58
56optional_header: 59optional_header:
57 .short 0x10b @ PE32 format 60 .short PE_OPT_MAGIC_PE32 @ PE32 format
58 .byte 0x02 @ MajorLinkerVersion 61 .byte 0x02 @ MajorLinkerVersion
59 .byte 0x14 @ MinorLinkerVersion 62 .byte 0x14 @ MinorLinkerVersion
60 .long _end - __efi_start @ SizeOfCode 63 .long __pecoff_code_size @ SizeOfCode
61 .long 0 @ SizeOfInitializedData 64 .long __pecoff_data_size @ SizeOfInitializedData
62 .long 0 @ SizeOfUninitializedData 65 .long 0 @ SizeOfUninitializedData
63 .long efi_stub_entry - start @ AddressOfEntryPoint 66 .long efi_stub_entry - start @ AddressOfEntryPoint
64 .long start_offset @ BaseOfCode 67 .long start_offset @ BaseOfCode
65 .long 0 @ data 68 .long __pecoff_data_start - start @ BaseOfData
66 69
67extra_header_fields: 70extra_header_fields:
68 .long 0 @ ImageBase 71 .long 0 @ ImageBase
69 .long 0x200 @ SectionAlignment 72 .long SZ_4K @ SectionAlignment
70 .long 0x200 @ FileAlignment 73 .long SZ_512 @ FileAlignment
71 .short 0 @ MajorOperatingSystemVersion 74 .short 0 @ MajorOsVersion
72 .short 0 @ MinorOperatingSystemVersion 75 .short 0 @ MinorOsVersion
73 .short 0 @ MajorImageVersion 76 .short 0 @ MajorImageVersion
74 .short 0 @ MinorImageVersion 77 .short 0 @ MinorImageVersion
75 .short 0 @ MajorSubsystemVersion 78 .short 0 @ MajorSubsystemVersion
76 .short 0 @ MinorSubsystemVersion 79 .short 0 @ MinorSubsystemVersion
77 .long 0 @ Win32VersionValue 80 .long 0 @ Win32VersionValue
78 81
79 .long _end - start @ SizeOfImage 82 .long __pecoff_end - start @ SizeOfImage
80 .long start_offset @ SizeOfHeaders 83 .long start_offset @ SizeOfHeaders
81 .long 0 @ CheckSum 84 .long 0 @ CheckSum
82 .short 0xa @ Subsystem (EFI application) 85 .short IMAGE_SUBSYSTEM_EFI_APPLICATION @ Subsystem
83 .short 0 @ DllCharacteristics 86 .short 0 @ DllCharacteristics
84 .long 0 @ SizeOfStackReserve 87 .long 0 @ SizeOfStackReserve
85 .long 0 @ SizeOfStackCommit 88 .long 0 @ SizeOfStackCommit
86 .long 0 @ SizeOfHeapReserve 89 .long 0 @ SizeOfHeapReserve
87 .long 0 @ SizeOfHeapCommit 90 .long 0 @ SizeOfHeapCommit
88 .long 0 @ LoaderFlags 91 .long 0 @ LoaderFlags
89 .long 0x6 @ NumberOfRvaAndSizes 92 .long (section_table - .) / 8 @ NumberOfRvaAndSizes
90 93
91 .quad 0 @ ExportTable 94 .quad 0 @ ExportTable
92 .quad 0 @ ImportTable 95 .quad 0 @ ImportTable
93 .quad 0 @ ResourceTable 96 .quad 0 @ ResourceTable
94 .quad 0 @ ExceptionTable 97 .quad 0 @ ExceptionTable
95 .quad 0 @ CertificationTable 98 .quad 0 @ CertificationTable
96 .quad 0 @ BaseRelocationTable 99 .quad 0 @ BaseRelocationTable
97 100
98section_table: 101section_table:
99 @
100 @ The EFI application loader requires a relocation section
101 @ because EFI applications must be relocatable. This is a
102 @ dummy section as far as we are concerned.
103 @
104 .ascii ".reloc\0\0"
105 .long 0 @ VirtualSize
106 .long 0 @ VirtualAddress
107 .long 0 @ SizeOfRawData
108 .long 0 @ PointerToRawData
109 .long 0 @ PointerToRelocations
110 .long 0 @ PointerToLineNumbers
111 .short 0 @ NumberOfRelocations
112 .short 0 @ NumberOfLineNumbers
113 .long 0x42100040 @ Characteristics
114
115 .ascii ".text\0\0\0" 102 .ascii ".text\0\0\0"
116 .long _end - __efi_start @ VirtualSize 103 .long __pecoff_code_size @ VirtualSize
117 .long __efi_start @ VirtualAddress 104 .long __efi_start @ VirtualAddress
118 .long _edata - __efi_start @ SizeOfRawData 105 .long __pecoff_code_size @ SizeOfRawData
119 .long __efi_start @ PointerToRawData 106 .long __efi_start @ PointerToRawData
120 .long 0 @ PointerToRelocations 107 .long 0 @ PointerToRelocations
121 .long 0 @ PointerToLineNumbers 108 .long 0 @ PointerToLineNumbers
122 .short 0 @ NumberOfRelocations 109 .short 0 @ NumberOfRelocations
123 .short 0 @ NumberOfLineNumbers 110 .short 0 @ NumberOfLineNumbers
124 .long 0xe0500020 @ Characteristics 111 .long IMAGE_SCN_CNT_CODE | \
112 IMAGE_SCN_MEM_READ | \
113 IMAGE_SCN_MEM_EXECUTE @ Characteristics
114
115 .ascii ".data\0\0\0"
116 .long __pecoff_data_size @ VirtualSize
117 .long __pecoff_data_start - start @ VirtualAddress
118 .long __pecoff_data_rawsize @ SizeOfRawData
119 .long __pecoff_data_start - start @ PointerToRawData
120 .long 0 @ PointerToRelocations
121 .long 0 @ PointerToLineNumbers
122 .short 0 @ NumberOfRelocations
123 .short 0 @ NumberOfLineNumbers
124 .long IMAGE_SCN_CNT_INITIALIZED_DATA | \
125 IMAGE_SCN_MEM_READ | \
126 IMAGE_SCN_MEM_WRITE @ Characteristics
127
128 .set section_count, (. - section_table) / 40
125 129
126 .align 9 130 .align 12
127__efi_start: 131__efi_start:
128#endif 132#endif
129 .endm 133 .endm
diff --git a/arch/arm/boot/compressed/vmlinux.lds.S b/arch/arm/boot/compressed/vmlinux.lds.S
index 81c493156ce8..7a4c59154361 100644
--- a/arch/arm/boot/compressed/vmlinux.lds.S
+++ b/arch/arm/boot/compressed/vmlinux.lds.S
@@ -48,13 +48,6 @@ SECTIONS
48 *(.rodata) 48 *(.rodata)
49 *(.rodata.*) 49 *(.rodata.*)
50 } 50 }
51 .data : {
52 /*
53 * The EFI stub always executes from RAM, and runs strictly before the
54 * decompressor, so we can make an exception for its r/w data, and keep it
55 */
56 *(.data.efistub)
57 }
58 .piggydata : { 51 .piggydata : {
59 *(.piggydata) 52 *(.piggydata)
60 } 53 }
@@ -70,6 +63,26 @@ SECTIONS
70 /* ensure the zImage file size is always a multiple of 64 bits */ 63 /* ensure the zImage file size is always a multiple of 64 bits */
71 /* (without a dummy byte, ld just ignores the empty section) */ 64 /* (without a dummy byte, ld just ignores the empty section) */
72 .pad : { BYTE(0); . = ALIGN(8); } 65 .pad : { BYTE(0); . = ALIGN(8); }
66
67#ifdef CONFIG_EFI_STUB
68 .data : ALIGN(4096) {
69 __pecoff_data_start = .;
70 /*
71 * The EFI stub always executes from RAM, and runs strictly before the
72 * decompressor, so we can make an exception for its r/w data, and keep it
73 */
74 *(.data.efistub)
75 __pecoff_data_end = .;
76
77 /*
78 * PE/COFF mandates a file size which is a multiple of 512 bytes if the
79 * section size equals or exceeds 4 KB
80 */
81 . = ALIGN(512);
82 }
83 __pecoff_data_rawsize = . - ADDR(.data);
84#endif
85
73 _edata = .; 86 _edata = .;
74 87
75 _magic_sig = ZIMAGE_MAGIC(0x016f2818); 88 _magic_sig = ZIMAGE_MAGIC(0x016f2818);
@@ -84,6 +97,9 @@ SECTIONS
84 . = ALIGN(8); /* the stack must be 64-bit aligned */ 97 . = ALIGN(8); /* the stack must be 64-bit aligned */
85 .stack : { *(.stack) } 98 .stack : { *(.stack) }
86 99
100 PROVIDE(__pecoff_data_size = ALIGN(512) - ADDR(.data));
101 PROVIDE(__pecoff_end = ALIGN(512));
102
87 .stab 0 : { *(.stab) } 103 .stab 0 : { *(.stab) }
88 .stabstr 0 : { *(.stabstr) } 104 .stabstr 0 : { *(.stabstr) }
89 .stab.excl 0 : { *(.stab.excl) } 105 .stab.excl 0 : { *(.stab.excl) }
diff --git a/arch/arm64/include/asm/efi.h b/arch/arm64/include/asm/efi.h
index 0cad5a5894b9..b93904b16fc2 100644
--- a/arch/arm64/include/asm/efi.h
+++ b/arch/arm64/include/asm/efi.h
@@ -90,6 +90,9 @@ static inline unsigned long efi_get_max_initrd_addr(unsigned long dram_base,
90#define alloc_screen_info(x...) &screen_info 90#define alloc_screen_info(x...) &screen_info
91#define free_screen_info(x...) 91#define free_screen_info(x...)
92 92
93/* redeclare as 'hidden' so the compiler will generate relative references */
94extern struct screen_info screen_info __attribute__((__visibility__("hidden")));
95
93static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) 96static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt)
94{ 97{
95} 98}
diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c
index 926c2cc4facc..e56dbc67e837 100644
--- a/arch/x86/boot/compressed/eboot.c
+++ b/arch/x86/boot/compressed/eboot.c
@@ -997,6 +997,9 @@ struct boot_params *efi_main(struct efi_config *c,
997 if (boot_params->secure_boot == efi_secureboot_mode_unset) 997 if (boot_params->secure_boot == efi_secureboot_mode_unset)
998 boot_params->secure_boot = efi_get_secureboot(sys_table); 998 boot_params->secure_boot = efi_get_secureboot(sys_table);
999 999
1000 /* Ask the firmware to clear memory on unclean shutdown */
1001 efi_enable_reset_attack_mitigation(sys_table);
1002
1000 setup_graphics(boot_params); 1003 setup_graphics(boot_params);
1001 1004
1002 setup_efi_pci(boot_params); 1005 setup_efi_pci(boot_params);
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c
index 6217b23e85f6..928b6dceeca0 100644
--- a/arch/x86/platform/efi/efi.c
+++ b/arch/x86/platform/efi/efi.c
@@ -1032,25 +1032,6 @@ void __init efi_enter_virtual_mode(void)
1032 efi_dump_pagetable(); 1032 efi_dump_pagetable();
1033} 1033}
1034 1034
1035/*
1036 * Convenience functions to obtain memory types and attributes
1037 */
1038int efi_mem_type(unsigned long phys_addr)
1039{
1040 efi_memory_desc_t *md;
1041
1042 if (!efi_enabled(EFI_MEMMAP))
1043 return -ENOTSUPP;
1044
1045 for_each_efi_memory_desc(md) {
1046 if ((md->phys_addr <= phys_addr) &&
1047 (phys_addr < (md->phys_addr +
1048 (md->num_pages << EFI_PAGE_SHIFT))))
1049 return md->type;
1050 }
1051 return -EINVAL;
1052}
1053
1054static int __init arch_parse_efi_cmdline(char *str) 1035static int __init arch_parse_efi_cmdline(char *str)
1055{ 1036{
1056 if (!str) { 1037 if (!str) {
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 2fe1a130189f..c16600f30611 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -534,7 +534,7 @@ static struct attribute *dcdbas_dev_attrs[] = {
534 NULL 534 NULL
535}; 535};
536 536
537static struct attribute_group dcdbas_attr_group = { 537static const struct attribute_group dcdbas_attr_group = {
538 .attrs = dcdbas_dev_attrs, 538 .attrs = dcdbas_dev_attrs,
539 .bin_attrs = dcdbas_bin_attrs, 539 .bin_attrs = dcdbas_bin_attrs,
540}; 540};
diff --git a/drivers/firmware/efi/Kconfig b/drivers/firmware/efi/Kconfig
index 394db40ed374..2b4c39fdfa91 100644
--- a/drivers/firmware/efi/Kconfig
+++ b/drivers/firmware/efi/Kconfig
@@ -151,6 +151,16 @@ config APPLE_PROPERTIES
151 151
152 If unsure, say Y if you have a Mac. Otherwise N. 152 If unsure, say Y if you have a Mac. Otherwise N.
153 153
154config RESET_ATTACK_MITIGATION
155 bool "Reset memory attack mitigation"
156 depends on EFI_STUB
157 help
158 Request that the firmware clear the contents of RAM after a reboot
159 using the TCG Platform Reset Attack Mitigation specification. This
160 protects against an attacker forcibly rebooting the system while it
161 still contains secrets in RAM, booting another OS and extracting the
162 secrets.
163
154endmenu 164endmenu
155 165
156config UEFI_CPER 166config UEFI_CPER
diff --git a/drivers/firmware/efi/arm-init.c b/drivers/firmware/efi/arm-init.c
index 1027d7b44358..80d1a885def5 100644
--- a/drivers/firmware/efi/arm-init.c
+++ b/drivers/firmware/efi/arm-init.c
@@ -145,6 +145,9 @@ static int __init uefi_init(void)
145 sizeof(efi_config_table_t), 145 sizeof(efi_config_table_t),
146 arch_tables); 146 arch_tables);
147 147
148 if (!retval)
149 efi.config_table = (unsigned long)efi.systab->tables;
150
148 early_memunmap(config_tables, table_size); 151 early_memunmap(config_tables, table_size);
149out: 152out:
150 early_memunmap(efi.systab, sizeof(efi_system_table_t)); 153 early_memunmap(efi.systab, sizeof(efi_system_table_t));
@@ -159,6 +162,7 @@ static __init int is_usable_memory(efi_memory_desc_t *md)
159 switch (md->type) { 162 switch (md->type) {
160 case EFI_LOADER_CODE: 163 case EFI_LOADER_CODE:
161 case EFI_LOADER_DATA: 164 case EFI_LOADER_DATA:
165 case EFI_ACPI_RECLAIM_MEMORY:
162 case EFI_BOOT_SERVICES_CODE: 166 case EFI_BOOT_SERVICES_CODE:
163 case EFI_BOOT_SERVICES_DATA: 167 case EFI_BOOT_SERVICES_DATA:
164 case EFI_CONVENTIONAL_MEMORY: 168 case EFI_CONVENTIONAL_MEMORY:
@@ -211,6 +215,10 @@ static __init void reserve_regions(void)
211 215
212 if (!is_usable_memory(md)) 216 if (!is_usable_memory(md))
213 memblock_mark_nomap(paddr, size); 217 memblock_mark_nomap(paddr, size);
218
219 /* keep ACPI reclaim memory intact for kexec etc. */
220 if (md->type == EFI_ACPI_RECLAIM_MEMORY)
221 memblock_reserve(paddr, size);
214 } 222 }
215 } 223 }
216} 224}
diff --git a/drivers/firmware/efi/efi-bgrt.c b/drivers/firmware/efi/efi-bgrt.c
index b58233e4ed71..50793fda7819 100644
--- a/drivers/firmware/efi/efi-bgrt.c
+++ b/drivers/firmware/efi/efi-bgrt.c
@@ -27,26 +27,6 @@ struct bmp_header {
27 u32 size; 27 u32 size;
28} __packed; 28} __packed;
29 29
30static bool efi_bgrt_addr_valid(u64 addr)
31{
32 efi_memory_desc_t *md;
33
34 for_each_efi_memory_desc(md) {
35 u64 size;
36 u64 end;
37
38 if (md->type != EFI_BOOT_SERVICES_DATA)
39 continue;
40
41 size = md->num_pages << EFI_PAGE_SHIFT;
42 end = md->phys_addr + size;
43 if (addr >= md->phys_addr && addr < end)
44 return true;
45 }
46
47 return false;
48}
49
50void __init efi_bgrt_init(struct acpi_table_header *table) 30void __init efi_bgrt_init(struct acpi_table_header *table)
51{ 31{
52 void *image; 32 void *image;
@@ -85,7 +65,7 @@ void __init efi_bgrt_init(struct acpi_table_header *table)
85 goto out; 65 goto out;
86 } 66 }
87 67
88 if (!efi_bgrt_addr_valid(bgrt->image_address)) { 68 if (efi_mem_type(bgrt->image_address) != EFI_BOOT_SERVICES_DATA) {
89 pr_notice("Ignoring BGRT: invalid image address\n"); 69 pr_notice("Ignoring BGRT: invalid image address\n");
90 goto out; 70 goto out;
91 } 71 }
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 69d4d130e055..f70febf680c3 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -198,7 +198,7 @@ static umode_t efi_attr_is_visible(struct kobject *kobj,
198 return attr->mode; 198 return attr->mode;
199} 199}
200 200
201static struct attribute_group efi_subsys_attr_group = { 201static const struct attribute_group efi_subsys_attr_group = {
202 .attrs = efi_subsys_attrs, 202 .attrs = efi_subsys_attrs,
203 .is_visible = efi_attr_is_visible, 203 .is_visible = efi_attr_is_visible,
204}; 204};
@@ -541,6 +541,7 @@ int __init efi_config_parse_tables(void *config_tables, int count, int sz,
541 if (seed != NULL) { 541 if (seed != NULL) {
542 add_device_randomness(seed->bits, seed->size); 542 add_device_randomness(seed->bits, seed->size);
543 early_memunmap(seed, sizeof(*seed) + size); 543 early_memunmap(seed, sizeof(*seed) + size);
544 pr_notice("seeding entropy pool\n");
544 } else { 545 } else {
545 pr_err("Could not map UEFI random seed!\n"); 546 pr_err("Could not map UEFI random seed!\n");
546 } 547 }
@@ -810,19 +811,19 @@ char * __init efi_md_typeattr_format(char *buf, size_t size,
810} 811}
811 812
812/* 813/*
814 * IA64 has a funky EFI memory map that doesn't work the same way as
815 * other architectures.
816 */
817#ifndef CONFIG_IA64
818/*
813 * efi_mem_attributes - lookup memmap attributes for physical address 819 * efi_mem_attributes - lookup memmap attributes for physical address
814 * @phys_addr: the physical address to lookup 820 * @phys_addr: the physical address to lookup
815 * 821 *
816 * Search in the EFI memory map for the region covering 822 * Search in the EFI memory map for the region covering
817 * @phys_addr. Returns the EFI memory attributes if the region 823 * @phys_addr. Returns the EFI memory attributes if the region
818 * was found in the memory map, 0 otherwise. 824 * was found in the memory map, 0 otherwise.
819 *
820 * Despite being marked __weak, most architectures should *not*
821 * override this function. It is __weak solely for the benefit
822 * of ia64 which has a funky EFI memory map that doesn't work
823 * the same way as other architectures.
824 */ 825 */
825u64 __weak efi_mem_attributes(unsigned long phys_addr) 826u64 efi_mem_attributes(unsigned long phys_addr)
826{ 827{
827 efi_memory_desc_t *md; 828 efi_memory_desc_t *md;
828 829
@@ -838,6 +839,31 @@ u64 __weak efi_mem_attributes(unsigned long phys_addr)
838 return 0; 839 return 0;
839} 840}
840 841
842/*
843 * efi_mem_type - lookup memmap type for physical address
844 * @phys_addr: the physical address to lookup
845 *
846 * Search in the EFI memory map for the region covering @phys_addr.
847 * Returns the EFI memory type if the region was found in the memory
848 * map, EFI_RESERVED_TYPE (zero) otherwise.
849 */
850int efi_mem_type(unsigned long phys_addr)
851{
852 const efi_memory_desc_t *md;
853
854 if (!efi_enabled(EFI_MEMMAP))
855 return -ENOTSUPP;
856
857 for_each_efi_memory_desc(md) {
858 if ((md->phys_addr <= phys_addr) &&
859 (phys_addr < (md->phys_addr +
860 (md->num_pages << EFI_PAGE_SHIFT))))
861 return md->type;
862 }
863 return -EINVAL;
864}
865#endif
866
841int efi_status_to_err(efi_status_t status) 867int efi_status_to_err(efi_status_t status)
842{ 868{
843 int err; 869 int err;
@@ -900,7 +926,7 @@ static int update_efi_random_seed(struct notifier_block *nb,
900 926
901 seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB); 927 seed = memremap(efi.rng_seed, sizeof(*seed), MEMREMAP_WB);
902 if (seed != NULL) { 928 if (seed != NULL) {
903 size = min(seed->size, 32U); 929 size = min(seed->size, EFI_RANDOM_SEED_SIZE);
904 memunmap(seed); 930 memunmap(seed);
905 } else { 931 } else {
906 pr_err("Could not map UEFI random seed!\n"); 932 pr_err("Could not map UEFI random seed!\n");
diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c
index 8554d7aec31c..bd7ed3c1148a 100644
--- a/drivers/firmware/efi/esrt.c
+++ b/drivers/firmware/efi/esrt.c
@@ -230,7 +230,7 @@ static umode_t esrt_attr_is_visible(struct kobject *kobj,
230 return attr->mode; 230 return attr->mode;
231} 231}
232 232
233static struct attribute_group esrt_attr_group = { 233static const struct attribute_group esrt_attr_group = {
234 .attrs = esrt_attrs, 234 .attrs = esrt_attrs,
235 .is_visible = esrt_attr_is_visible, 235 .is_visible = esrt_attr_is_visible,
236}; 236};
diff --git a/drivers/firmware/efi/libstub/Makefile b/drivers/firmware/efi/libstub/Makefile
index 37e24f525162..dedf9bde44db 100644
--- a/drivers/firmware/efi/libstub/Makefile
+++ b/drivers/firmware/efi/libstub/Makefile
@@ -10,7 +10,7 @@ cflags-$(CONFIG_X86) += -m$(BITS) -D__KERNEL__ -O2 \
10 -fPIC -fno-strict-aliasing -mno-red-zone \ 10 -fPIC -fno-strict-aliasing -mno-red-zone \
11 -mno-mmx -mno-sse 11 -mno-mmx -mno-sse
12 12
13cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) 13cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie
14cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \ 14cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \
15 -fno-builtin -fpic -mno-single-pic-base 15 -fno-builtin -fpic -mno-single-pic-base
16 16
@@ -30,6 +30,7 @@ OBJECT_FILES_NON_STANDARD := y
30KCOV_INSTRUMENT := n 30KCOV_INSTRUMENT := n
31 31
32lib-y := efi-stub-helper.o gop.o secureboot.o 32lib-y := efi-stub-helper.o gop.o secureboot.o
33lib-$(CONFIG_RESET_ATTACK_MITIGATION) += tpm.o
33 34
34# include the stub's generic dependencies from lib/ when building for ARM/arm64 35# include the stub's generic dependencies from lib/ when building for ARM/arm64
35arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c 36arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c
index 8181ac179d14..1cb2d1c070c3 100644
--- a/drivers/firmware/efi/libstub/arm-stub.c
+++ b/drivers/firmware/efi/libstub/arm-stub.c
@@ -192,6 +192,9 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table,
192 goto fail_free_cmdline; 192 goto fail_free_cmdline;
193 } 193 }
194 194
195 /* Ask the firmware to clear memory on unclean shutdown */
196 efi_enable_reset_attack_mitigation(sys_table);
197
195 secure_boot = efi_get_secureboot(sys_table); 198 secure_boot = efi_get_secureboot(sys_table);
196 199
197 /* 200 /*
diff --git a/drivers/firmware/efi/libstub/arm64-stub.c b/drivers/firmware/efi/libstub/arm64-stub.c
index af6ae95a5e34..b9bd827caa22 100644
--- a/drivers/firmware/efi/libstub/arm64-stub.c
+++ b/drivers/firmware/efi/libstub/arm64-stub.c
@@ -9,10 +9,18 @@
9 * published by the Free Software Foundation. 9 * published by the Free Software Foundation.
10 * 10 *
11 */ 11 */
12
13/*
14 * To prevent the compiler from emitting GOT-indirected (and thus absolute)
15 * references to the section markers, override their visibility as 'hidden'
16 */
17#pragma GCC visibility push(hidden)
18#include <asm/sections.h>
19#pragma GCC visibility pop
20
12#include <linux/efi.h> 21#include <linux/efi.h>
13#include <asm/efi.h> 22#include <asm/efi.h>
14#include <asm/memory.h> 23#include <asm/memory.h>
15#include <asm/sections.h>
16#include <asm/sysreg.h> 24#include <asm/sysreg.h>
17 25
18#include "efistub.h" 26#include "efistub.h"
diff --git a/drivers/firmware/efi/libstub/random.c b/drivers/firmware/efi/libstub/random.c
index 7e72954d5860..e0e603a89aa9 100644
--- a/drivers/firmware/efi/libstub/random.c
+++ b/drivers/firmware/efi/libstub/random.c
@@ -145,8 +145,6 @@ efi_status_t efi_random_alloc(efi_system_table_t *sys_table_arg,
145 return status; 145 return status;
146} 146}
147 147
148#define RANDOM_SEED_SIZE 32
149
150efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg) 148efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
151{ 149{
152 efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID; 150 efi_guid_t rng_proto = EFI_RNG_PROTOCOL_GUID;
@@ -162,25 +160,25 @@ efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg)
162 return status; 160 return status;
163 161
164 status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA, 162 status = efi_call_early(allocate_pool, EFI_RUNTIME_SERVICES_DATA,
165 sizeof(*seed) + RANDOM_SEED_SIZE, 163 sizeof(*seed) + EFI_RANDOM_SEED_SIZE,
166 (void **)&seed); 164 (void **)&seed);
167 if (status != EFI_SUCCESS) 165 if (status != EFI_SUCCESS)
168 return status; 166 return status;
169 167
170 status = rng->get_rng(rng, &rng_algo_raw, RANDOM_SEED_SIZE, 168 status = rng->get_rng(rng, &rng_algo_raw, EFI_RANDOM_SEED_SIZE,
171 seed->bits); 169 seed->bits);
172 if (status == EFI_UNSUPPORTED) 170 if (status == EFI_UNSUPPORTED)
173 /* 171 /*
174 * Use whatever algorithm we have available if the raw algorithm 172 * Use whatever algorithm we have available if the raw algorithm
175 * is not implemented. 173 * is not implemented.
176 */ 174 */
177 status = rng->get_rng(rng, NULL, RANDOM_SEED_SIZE, 175 status = rng->get_rng(rng, NULL, EFI_RANDOM_SEED_SIZE,
178 seed->bits); 176 seed->bits);
179 177
180 if (status != EFI_SUCCESS) 178 if (status != EFI_SUCCESS)
181 goto err_freepool; 179 goto err_freepool;
182 180
183 seed->size = RANDOM_SEED_SIZE; 181 seed->size = EFI_RANDOM_SEED_SIZE;
184 status = efi_call_early(install_configuration_table, &rng_table_guid, 182 status = efi_call_early(install_configuration_table, &rng_table_guid,
185 seed); 183 seed);
186 if (status != EFI_SUCCESS) 184 if (status != EFI_SUCCESS)
diff --git a/drivers/firmware/efi/libstub/tpm.c b/drivers/firmware/efi/libstub/tpm.c
new file mode 100644
index 000000000000..6224cdbc9669
--- /dev/null
+++ b/drivers/firmware/efi/libstub/tpm.c
@@ -0,0 +1,58 @@
1/*
2 * TPM handling.
3 *
4 * Copyright (C) 2016 CoreOS, Inc
5 * Copyright (C) 2017 Google, Inc.
6 * Matthew Garrett <mjg59@google.com>
7 *
8 * This file is part of the Linux kernel, and is made available under the
9 * terms of the GNU General Public License version 2.
10 */
11#include <linux/efi.h>
12#include <asm/efi.h>
13
14#include "efistub.h"
15
16static const efi_char16_t efi_MemoryOverWriteRequest_name[] = {
17 'M', 'e', 'm', 'o', 'r', 'y', 'O', 'v', 'e', 'r', 'w', 'r', 'i', 't',
18 'e', 'R', 'e', 'q', 'u', 'e', 's', 't', 'C', 'o', 'n', 't', 'r', 'o',
19 'l', 0
20};
21
22#define MEMORY_ONLY_RESET_CONTROL_GUID \
23 EFI_GUID(0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29)
24
25#define get_efi_var(name, vendor, ...) \
26 efi_call_runtime(get_variable, \
27 (efi_char16_t *)(name), (efi_guid_t *)(vendor), \
28 __VA_ARGS__)
29
30#define set_efi_var(name, vendor, ...) \
31 efi_call_runtime(set_variable, \
32 (efi_char16_t *)(name), (efi_guid_t *)(vendor), \
33 __VA_ARGS__)
34
35/*
36 * Enable reboot attack mitigation. This requests that the firmware clear the
37 * RAM on next reboot before proceeding with boot, ensuring that any secrets
38 * are cleared. If userland has ensured that all secrets have been removed
39 * from RAM before reboot it can simply reset this variable.
40 */
41void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg)
42{
43 u8 val = 1;
44 efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID;
45 efi_status_t status;
46 unsigned long datasize = 0;
47
48 status = get_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
49 NULL, &datasize, NULL);
50
51 if (status == EFI_NOT_FOUND)
52 return;
53
54 set_efi_var(efi_MemoryOverWriteRequest_name, &var_guid,
55 EFI_VARIABLE_NON_VOLATILE |
56 EFI_VARIABLE_BOOTSERVICE_ACCESS |
57 EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), &val);
58}
diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c
index 62ead9b9d871..22874544d301 100644
--- a/drivers/firmware/efi/reboot.c
+++ b/drivers/firmware/efi/reboot.c
@@ -5,6 +5,8 @@
5#include <linux/efi.h> 5#include <linux/efi.h>
6#include <linux/reboot.h> 6#include <linux/reboot.h>
7 7
8static void (*orig_pm_power_off)(void);
9
8int efi_reboot_quirk_mode = -1; 10int efi_reboot_quirk_mode = -1;
9 11
10void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) 12void efi_reboot(enum reboot_mode reboot_mode, const char *__unused)
@@ -51,6 +53,12 @@ bool __weak efi_poweroff_required(void)
51static void efi_power_off(void) 53static void efi_power_off(void)
52{ 54{
53 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); 55 efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL);
56 /*
57 * The above call should not return, if it does fall back to
58 * the original power off method (typically ACPI poweroff).
59 */
60 if (orig_pm_power_off)
61 orig_pm_power_off();
54} 62}
55 63
56static int __init efi_shutdown_init(void) 64static int __init efi_shutdown_init(void)
@@ -58,8 +66,10 @@ static int __init efi_shutdown_init(void)
58 if (!efi_enabled(EFI_RUNTIME_SERVICES)) 66 if (!efi_enabled(EFI_RUNTIME_SERVICES))
59 return -ENODEV; 67 return -ENODEV;
60 68
61 if (efi_poweroff_required()) 69 if (efi_poweroff_required()) {
70 orig_pm_power_off = pm_power_off;
62 pm_power_off = efi_power_off; 71 pm_power_off = efi_power_off;
72 }
63 73
64 return 0; 74 return 0;
65} 75}
diff --git a/drivers/video/fbdev/efifb.c b/drivers/video/fbdev/efifb.c
index 1e784adb89b1..3a010641f630 100644
--- a/drivers/video/fbdev/efifb.c
+++ b/drivers/video/fbdev/efifb.c
@@ -149,6 +149,10 @@ ATTRIBUTE_GROUPS(efifb);
149 149
150static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ 150static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */
151 151
152static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */
153static struct resource *bar_resource;
154static u64 bar_offset;
155
152static int efifb_probe(struct platform_device *dev) 156static int efifb_probe(struct platform_device *dev)
153{ 157{
154 struct fb_info *info; 158 struct fb_info *info;
@@ -203,6 +207,13 @@ static int efifb_probe(struct platform_device *dev)
203 efifb_fix.smem_start |= ext_lfb_base; 207 efifb_fix.smem_start |= ext_lfb_base;
204 } 208 }
205 209
210 if (bar_resource &&
211 bar_resource->start + bar_offset != efifb_fix.smem_start) {
212 dev_info(&efifb_pci_dev->dev,
213 "BAR has moved, updating efifb address\n");
214 efifb_fix.smem_start = bar_resource->start + bar_offset;
215 }
216
206 efifb_defined.bits_per_pixel = screen_info.lfb_depth; 217 efifb_defined.bits_per_pixel = screen_info.lfb_depth;
207 efifb_defined.xres = screen_info.lfb_width; 218 efifb_defined.xres = screen_info.lfb_width;
208 efifb_defined.yres = screen_info.lfb_height; 219 efifb_defined.yres = screen_info.lfb_height;
@@ -370,15 +381,13 @@ static struct platform_driver efifb_driver = {
370 381
371builtin_platform_driver(efifb_driver); 382builtin_platform_driver(efifb_driver);
372 383
373#if defined(CONFIG_PCI) && !defined(CONFIG_X86) 384#if defined(CONFIG_PCI)
374
375static bool pci_bar_found; /* did we find a BAR matching the efifb base? */
376 385
377static void claim_efifb_bar(struct pci_dev *dev, int idx) 386static void record_efifb_bar_resource(struct pci_dev *dev, int idx, u64 offset)
378{ 387{
379 u16 word; 388 u16 word;
380 389
381 pci_bar_found = true; 390 efifb_pci_dev = dev;
382 391
383 pci_read_config_word(dev, PCI_COMMAND, &word); 392 pci_read_config_word(dev, PCI_COMMAND, &word);
384 if (!(word & PCI_COMMAND_MEMORY)) { 393 if (!(word & PCI_COMMAND_MEMORY)) {
@@ -389,12 +398,8 @@ static void claim_efifb_bar(struct pci_dev *dev, int idx)
389 return; 398 return;
390 } 399 }
391 400
392 if (pci_claim_resource(dev, idx)) { 401 bar_resource = &dev->resource[idx];
393 pci_dev_disabled = true; 402 bar_offset = offset;
394 dev_err(&dev->dev,
395 "BAR %d: failed to claim resource for efifb!\n", idx);
396 return;
397 }
398 403
399 dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx); 404 dev_info(&dev->dev, "BAR %d: assigned to efifb\n", idx);
400} 405}
@@ -405,7 +410,7 @@ static void efifb_fixup_resources(struct pci_dev *dev)
405 u64 size = screen_info.lfb_size; 410 u64 size = screen_info.lfb_size;
406 int i; 411 int i;
407 412
408 if (pci_bar_found || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI) 413 if (efifb_pci_dev || screen_info.orig_video_isVGA != VIDEO_TYPE_EFI)
409 return; 414 return;
410 415
411 if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE) 416 if (screen_info.capabilities & VIDEO_CAPABILITY_64BIT_BASE)
@@ -421,7 +426,7 @@ static void efifb_fixup_resources(struct pci_dev *dev)
421 continue; 426 continue;
422 427
423 if (res->start <= base && res->end >= base + size - 1) { 428 if (res->start <= base && res->end >= base + size - 1) {
424 claim_efifb_bar(dev, i); 429 record_efifb_bar_resource(dev, i, base - res->start);
425 break; 430 break;
426 } 431 }
427 } 432 }
diff --git a/include/linux/efi.h b/include/linux/efi.h
index 4102b85217d5..65905c3cb655 100644
--- a/include/linux/efi.h
+++ b/include/linux/efi.h
@@ -1526,6 +1526,13 @@ enum efi_secureboot_mode {
1526}; 1526};
1527enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); 1527enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table);
1528 1528
1529#ifdef CONFIG_RESET_ATTACK_MITIGATION
1530void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg);
1531#else
1532static inline void
1533efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg) { }
1534#endif
1535
1529/* 1536/*
1530 * Arch code can implement the following three template macros, avoiding 1537 * Arch code can implement the following three template macros, avoiding
1531 * reptition for the void/non-void return cases of {__,}efi_call_virt(): 1538 * reptition for the void/non-void return cases of {__,}efi_call_virt():
@@ -1586,6 +1593,8 @@ efi_status_t efi_exit_boot_services(efi_system_table_t *sys_table,
1586 void *priv, 1593 void *priv,
1587 efi_exit_boot_map_processing priv_func); 1594 efi_exit_boot_map_processing priv_func);
1588 1595
1596#define EFI_RANDOM_SEED_SIZE 64U
1597
1589struct linux_efi_random_seed { 1598struct linux_efi_random_seed {
1590 u32 size; 1599 u32 size;
1591 u8 bits[]; 1600 u8 bits[];