diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 12:42:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-09-07 12:42:35 -0400 |
commit | f92e3da18b7d5941468040af962c201235148301 (patch) | |
tree | 45b05ba50dfe4c5de9cf99b889297a6b51449a8b | |
parent | 57e88b43b81301d9b28f124a5576ac43a1cf9e8d (diff) | |
parent | 6de47a5e371f75f80544986e6c9636211a2ae8af (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.S | 160 | ||||
-rw-r--r-- | arch/arm/boot/compressed/vmlinux.lds.S | 30 | ||||
-rw-r--r-- | arch/arm64/include/asm/efi.h | 3 | ||||
-rw-r--r-- | arch/x86/boot/compressed/eboot.c | 3 | ||||
-rw-r--r-- | arch/x86/platform/efi/efi.c | 19 | ||||
-rw-r--r-- | drivers/firmware/dcdbas.c | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/Kconfig | 10 | ||||
-rw-r--r-- | drivers/firmware/efi/arm-init.c | 8 | ||||
-rw-r--r-- | drivers/firmware/efi/efi-bgrt.c | 22 | ||||
-rw-r--r-- | drivers/firmware/efi/efi.c | 42 | ||||
-rw-r--r-- | drivers/firmware/efi/esrt.c | 2 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/Makefile | 3 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/arm-stub.c | 3 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/arm64-stub.c | 10 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/random.c | 10 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/tpm.c | 58 | ||||
-rw-r--r-- | drivers/firmware/efi/reboot.c | 12 | ||||
-rw-r--r-- | drivers/video/fbdev/efifb.c | 31 | ||||
-rw-r--r-- | include/linux/efi.h | 9 |
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 | ||
39 | pe_header: | 42 | pe_header: |
40 | .ascii "PE\0\0" | 43 | .long PE_MAGIC |
41 | 44 | ||
42 | coff_header: | 45 | coff_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 | ||
56 | optional_header: | 59 | optional_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 | ||
67 | extra_header_fields: | 70 | extra_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 | ||
98 | section_table: | 101 | section_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 */ | ||
94 | extern struct screen_info screen_info __attribute__((__visibility__("hidden"))); | ||
95 | |||
93 | static inline void efifb_setup_from_dmi(struct screen_info *si, const char *opt) | 96 | static 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 | */ | ||
1038 | int 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 | |||
1054 | static int __init arch_parse_efi_cmdline(char *str) | 1035 | static 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 | ||
537 | static struct attribute_group dcdbas_attr_group = { | 537 | static 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 | ||
154 | config 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 | |||
154 | endmenu | 164 | endmenu |
155 | 165 | ||
156 | config UEFI_CPER | 166 | config 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); |
149 | out: | 152 | out: |
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 | ||
30 | static 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 | |||
50 | void __init efi_bgrt_init(struct acpi_table_header *table) | 30 | void __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 | ||
201 | static struct attribute_group efi_subsys_attr_group = { | 201 | static 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 | */ |
825 | u64 __weak efi_mem_attributes(unsigned long phys_addr) | 826 | u64 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 | */ | ||
850 | int 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 | |||
841 | int efi_status_to_err(efi_status_t status) | 867 | int 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 | ||
233 | static struct attribute_group esrt_attr_group = { | 233 | static 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 | ||
13 | cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) | 13 | cflags-$(CONFIG_ARM64) := $(subst -pg,,$(KBUILD_CFLAGS)) -fpie |
14 | cflags-$(CONFIG_ARM) := $(subst -pg,,$(KBUILD_CFLAGS)) \ | 14 | cflags-$(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 | |||
30 | KCOV_INSTRUMENT := n | 30 | KCOV_INSTRUMENT := n |
31 | 31 | ||
32 | lib-y := efi-stub-helper.o gop.o secureboot.o | 32 | lib-y := efi-stub-helper.o gop.o secureboot.o |
33 | lib-$(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 |
35 | arm-deps := fdt_rw.c fdt_ro.c fdt_wip.c fdt.c fdt_empty_tree.c fdt_sw.c sort.c | 36 | arm-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 | |||
150 | efi_status_t efi_random_get_seed(efi_system_table_t *sys_table_arg) | 148 | efi_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 | |||
16 | static 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 | */ | ||
41 | void 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 | ||
8 | static void (*orig_pm_power_off)(void); | ||
9 | |||
8 | int efi_reboot_quirk_mode = -1; | 10 | int efi_reboot_quirk_mode = -1; |
9 | 11 | ||
10 | void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) | 12 | void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) |
@@ -51,6 +53,12 @@ bool __weak efi_poweroff_required(void) | |||
51 | static void efi_power_off(void) | 53 | static 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 | ||
56 | static int __init efi_shutdown_init(void) | 64 | static 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 | ||
150 | static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ | 150 | static bool pci_dev_disabled; /* FB base matches BAR of a disabled device */ |
151 | 151 | ||
152 | static struct pci_dev *efifb_pci_dev; /* dev with BAR covering the efifb */ | ||
153 | static struct resource *bar_resource; | ||
154 | static u64 bar_offset; | ||
155 | |||
152 | static int efifb_probe(struct platform_device *dev) | 156 | static 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 | ||
371 | builtin_platform_driver(efifb_driver); | 382 | builtin_platform_driver(efifb_driver); |
372 | 383 | ||
373 | #if defined(CONFIG_PCI) && !defined(CONFIG_X86) | 384 | #if defined(CONFIG_PCI) |
374 | |||
375 | static bool pci_bar_found; /* did we find a BAR matching the efifb base? */ | ||
376 | 385 | ||
377 | static void claim_efifb_bar(struct pci_dev *dev, int idx) | 386 | static 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 | }; |
1527 | enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); | 1527 | enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); |
1528 | 1528 | ||
1529 | #ifdef CONFIG_RESET_ATTACK_MITIGATION | ||
1530 | void efi_enable_reset_attack_mitigation(efi_system_table_t *sys_table_arg); | ||
1531 | #else | ||
1532 | static inline void | ||
1533 | efi_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 | |||
1589 | struct linux_efi_random_seed { | 1598 | struct linux_efi_random_seed { |
1590 | u32 size; | 1599 | u32 size; |
1591 | u8 bits[]; | 1600 | u8 bits[]; |