aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/firmware/efi/libstub/arm-stub.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 16:06:27 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 16:06:27 -0400
commit49817c33433a3cd6f320b13699e6746cc39b453b (patch)
tree1eb8c4a4d585e648b0783741c02ab611149971d9 /drivers/firmware/efi/libstub/arm-stub.c
parent230e51f21101e49c8d73018d414adbd0d57459a1 (diff)
parent6c5450ef66816216e574885cf8d3ddb31ef77428 (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.c77
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
21bool __nokaslr; 21bool __nokaslr;
22 22
23static int efi_secureboot_enabled(efi_system_table_t *sys_table_arg) 23static 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
56out_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
172static 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);
311fail_free_cmdline: 365fail_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);
313fail: 368fail:
314 return EFI_ERROR; 369 return EFI_ERROR;