diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-16 16:06:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-16 16:06:27 -0400 |
commit | 49817c33433a3cd6f320b13699e6746cc39b453b (patch) | |
tree | 1eb8c4a4d585e648b0783741c02ab611149971d9 /drivers/firmware/efi/libstub/arm-stub.c | |
parent | 230e51f21101e49c8d73018d414adbd0d57459a1 (diff) | |
parent | 6c5450ef66816216e574885cf8d3ddb31ef77428 (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:
- Drop the unused EFI_SYSTEM_TABLES efi.flags bit and ensure the
ARM/arm64 EFI System Table mapping is read-only (Ard Biesheuvel)
- Add a comment to explain that one of the code paths in the x86/pat
code is only executed for EFI boot (Matt Fleming)
- Improve Secure Boot status checks on arm64 and handle unexpected
errors (Linn Crosetto)
- Remove the global EFI memory map variable 'memmap' as the same
information is already available in efi::memmap (Matt Fleming)
- Add EFI Memory Attribute table support for ARM/arm64 (Ard
Biesheuvel)
- Add EFI GOP framebuffer support for ARM/arm64 (Ard Biesheuvel)
- Add EFI Bootloader Control driver for storing reboot(2) data in EFI
variables for consumption by bootloaders (Jeremy Compostella)
- Add Core EFI capsule support (Matt Fleming)
- Add EFI capsule char driver (Kweh, Hock Leong)
- Unify EFI memory map code for ARM and arm64 (Ard Biesheuvel)
- Add generic EFI support for detecting when firmware corrupts CPU
status register bits (like IRQ flags) when performing EFI runtime
service calls (Mark Rutland)
... and other misc cleanups"
* 'efi-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (46 commits)
efivarfs: Make efivarfs_file_ioctl() static
efi: Merge boolean flag arguments
efi/capsule: Move 'capsule' to the stack in efi_capsule_supported()
efibc: Fix excessive stack footprint warning
efi/capsule: Make efi_capsule_pending() lockless
efi: Remove unnecessary (and buggy) .memmap initialization from the Xen EFI driver
efi/runtime-wrappers: Remove ARCH_EFI_IRQ_FLAGS_MASK #ifdef
x86/efi: Enable runtime call flag checking
arm/efi: Enable runtime call flag checking
arm64/efi: Enable runtime call flag checking
efi/runtime-wrappers: Detect firmware IRQ flag corruption
efi/runtime-wrappers: Remove redundant #ifdefs
x86/efi: Move to generic {__,}efi_call_virt()
arm/efi: Move to generic {__,}efi_call_virt()
arm64/efi: Move to generic {__,}efi_call_virt()
efi/runtime-wrappers: Add {__,}efi_call_virt() templates
efi/arm-init: Reserve rather than unmap the memory map for ARM as well
efi: Add misc char driver interface to update EFI firmware
x86/efi: Force EFI reboot to process pending capsules
efi: Add 'capsule' update support
...
Diffstat (limited to 'drivers/firmware/efi/libstub/arm-stub.c')
-rw-r--r-- | drivers/firmware/efi/libstub/arm-stub.c | 77 |
1 files changed, 66 insertions, 11 deletions
diff --git a/drivers/firmware/efi/libstub/arm-stub.c b/drivers/firmware/efi/libstub/arm-stub.c index 414deb85c2e5..993aa56755f6 100644 --- a/drivers/firmware/efi/libstub/arm-stub.c +++ b/drivers/firmware/efi/libstub/arm-stub.c | |||
@@ -20,27 +20,49 @@ | |||
20 | 20 | ||
21 | bool __nokaslr; | 21 | bool __nokaslr; |
22 | 22 | ||
23 | static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg) | 23 | static int efi_get_secureboot(efi_system_table_t *sys_table_arg) |
24 | { | 24 | { |
25 | static efi_guid_t const var_guid = EFI_GLOBAL_VARIABLE_GUID; | 25 | static efi_char16_t const sb_var_name[] = { |
26 | static efi_char16_t const var_name[] = { | ||
27 | 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 }; | 26 | 'S', 'e', 'c', 'u', 'r', 'e', 'B', 'o', 'o', 't', 0 }; |
27 | static efi_char16_t const sm_var_name[] = { | ||
28 | 'S', 'e', 't', 'u', 'p', 'M', 'o', 'd', 'e', 0 }; | ||
28 | 29 | ||
30 | efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; | ||
29 | efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable; | 31 | efi_get_variable_t *f_getvar = sys_table_arg->runtime->get_variable; |
30 | unsigned long size = sizeof(u8); | ||
31 | efi_status_t status; | ||
32 | u8 val; | 32 | u8 val; |
33 | unsigned long size = sizeof(val); | ||
34 | efi_status_t status; | ||
33 | 35 | ||
34 | status = f_getvar((efi_char16_t *)var_name, (efi_guid_t *)&var_guid, | 36 | status = f_getvar((efi_char16_t *)sb_var_name, (efi_guid_t *)&var_guid, |
35 | NULL, &size, &val); | 37 | NULL, &size, &val); |
36 | 38 | ||
39 | if (status != EFI_SUCCESS) | ||
40 | goto out_efi_err; | ||
41 | |||
42 | if (val == 0) | ||
43 | return 0; | ||
44 | |||
45 | status = f_getvar((efi_char16_t *)sm_var_name, (efi_guid_t *)&var_guid, | ||
46 | NULL, &size, &val); | ||
47 | |||
48 | if (status != EFI_SUCCESS) | ||
49 | goto out_efi_err; | ||
50 | |||
51 | if (val == 1) | ||
52 | return 0; | ||
53 | |||
54 | return 1; | ||
55 | |||
56 | out_efi_err: | ||
37 | switch (status) { | 57 | switch (status) { |
38 | case EFI_SUCCESS: | ||
39 | return val; | ||
40 | case EFI_NOT_FOUND: | 58 | case EFI_NOT_FOUND: |
41 | return 0; | 59 | return 0; |
60 | case EFI_DEVICE_ERROR: | ||
61 | return -EIO; | ||
62 | case EFI_SECURITY_VIOLATION: | ||
63 | return -EACCES; | ||
42 | default: | 64 | default: |
43 | return 1; | 65 | return -EINVAL; |
44 | } | 66 | } |
45 | } | 67 | } |
46 | 68 | ||
@@ -147,6 +169,25 @@ void efi_char16_printk(efi_system_table_t *sys_table_arg, | |||
147 | out->output_string(out, str); | 169 | out->output_string(out, str); |
148 | } | 170 | } |
149 | 171 | ||
172 | static struct screen_info *setup_graphics(efi_system_table_t *sys_table_arg) | ||
173 | { | ||
174 | efi_guid_t gop_proto = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; | ||
175 | efi_status_t status; | ||
176 | unsigned long size; | ||
177 | void **gop_handle = NULL; | ||
178 | struct screen_info *si = NULL; | ||
179 | |||
180 | size = 0; | ||
181 | status = efi_call_early(locate_handle, EFI_LOCATE_BY_PROTOCOL, | ||
182 | &gop_proto, NULL, &size, gop_handle); | ||
183 | if (status == EFI_BUFFER_TOO_SMALL) { | ||
184 | si = alloc_screen_info(sys_table_arg); | ||
185 | if (!si) | ||
186 | return NULL; | ||
187 | efi_setup_gop(sys_table_arg, si, &gop_proto, size); | ||
188 | } | ||
189 | return si; | ||
190 | } | ||
150 | 191 | ||
151 | /* | 192 | /* |
152 | * This function handles the architcture specific differences between arm and | 193 | * This function handles the architcture specific differences between arm and |
@@ -185,6 +226,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, | |||
185 | efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; | 226 | efi_guid_t loaded_image_proto = LOADED_IMAGE_PROTOCOL_GUID; |
186 | unsigned long reserve_addr = 0; | 227 | unsigned long reserve_addr = 0; |
187 | unsigned long reserve_size = 0; | 228 | unsigned long reserve_size = 0; |
229 | int secure_boot = 0; | ||
230 | struct screen_info *si; | ||
188 | 231 | ||
189 | /* Check if we were booted by the EFI firmware */ | 232 | /* Check if we were booted by the EFI firmware */ |
190 | if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) | 233 | if (sys_table->hdr.signature != EFI_SYSTEM_TABLE_SIGNATURE) |
@@ -237,6 +280,8 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, | |||
237 | __nokaslr = true; | 280 | __nokaslr = true; |
238 | } | 281 | } |
239 | 282 | ||
283 | si = setup_graphics(sys_table); | ||
284 | |||
240 | status = handle_kernel_image(sys_table, image_addr, &image_size, | 285 | status = handle_kernel_image(sys_table, image_addr, &image_size, |
241 | &reserve_addr, | 286 | &reserve_addr, |
242 | &reserve_size, | 287 | &reserve_size, |
@@ -250,12 +295,21 @@ unsigned long efi_entry(void *handle, efi_system_table_t *sys_table, | |||
250 | if (status != EFI_SUCCESS) | 295 | if (status != EFI_SUCCESS) |
251 | pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n"); | 296 | pr_efi_err(sys_table, "Failed to parse EFI cmdline options\n"); |
252 | 297 | ||
298 | secure_boot = efi_get_secureboot(sys_table); | ||
299 | if (secure_boot > 0) | ||
300 | pr_efi(sys_table, "UEFI Secure Boot is enabled.\n"); | ||
301 | |||
302 | if (secure_boot < 0) { | ||
303 | pr_efi_err(sys_table, | ||
304 | "could not determine UEFI Secure Boot status.\n"); | ||
305 | } | ||
306 | |||
253 | /* | 307 | /* |
254 | * Unauthenticated device tree data is a security hazard, so | 308 | * Unauthenticated device tree data is a security hazard, so |
255 | * ignore 'dtb=' unless UEFI Secure Boot is disabled. | 309 | * ignore 'dtb=' unless UEFI Secure Boot is disabled. |
256 | */ | 310 | */ |
257 | if (efi_secureboot_enabled(sys_table)) { | 311 | if (secure_boot != 0 && strstr(cmdline_ptr, "dtb=")) { |
258 | pr_efi(sys_table, "UEFI Secure Boot is enabled.\n"); | 312 | pr_efi(sys_table, "Ignoring DTB from command line.\n"); |
259 | } else { | 313 | } else { |
260 | status = handle_cmdline_files(sys_table, image, cmdline_ptr, | 314 | status = handle_cmdline_files(sys_table, image, cmdline_ptr, |
261 | "dtb=", | 315 | "dtb=", |
@@ -309,6 +363,7 @@ fail_free_image: | |||
309 | efi_free(sys_table, image_size, *image_addr); | 363 | efi_free(sys_table, image_size, *image_addr); |
310 | efi_free(sys_table, reserve_size, reserve_addr); | 364 | efi_free(sys_table, reserve_size, reserve_addr); |
311 | fail_free_cmdline: | 365 | fail_free_cmdline: |
366 | free_screen_info(sys_table, si); | ||
312 | efi_free(sys_table, cmdline_size, (unsigned long)cmdline_ptr); | 367 | efi_free(sys_table, cmdline_size, (unsigned long)cmdline_ptr); |
313 | fail: | 368 | fail: |
314 | return EFI_ERROR; | 369 | return EFI_ERROR; |