Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'stable-shared-branch-for-driver-tree' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi into driver-core-next

Ard writes:

Stable shared branch between EFI and driver tree

Stable shared branch to ease the integration of Hans's series to support
device firmware loaded from EFI boot service memory regions.

[PATCH v12 00/10] efi/firmware/platform-x86: Add EFI embedded fw support
https://lore.kernel.org/linux-efi/20200115163554.101315-1-hdegoede@redhat.com/

* tag 'stable-shared-branch-for-driver-tree' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
efi: Add embedded peripheral firmware support
efi: Export boot-services code and data as debugfs-blobs

+264
+2
arch/x86/platform/efi/efi.c
··· 243 243 efi.memmap.desc_version); 244 244 245 245 memblock_reserve(pmap, efi.memmap.nr_map * efi.memmap.desc_size); 246 + set_bit(EFI_PRESERVE_BS_REGIONS, &efi.flags); 246 247 247 248 return 0; 248 249 } ··· 944 943 goto err; 945 944 } 946 945 946 + efi_check_for_embedded_firmwares(); 947 947 efi_free_boot_services(); 948 948 949 949 /*
+4
arch/x86/platform/efi/quirks.c
··· 410 410 int num_entries = 0; 411 411 void *new, *new_md; 412 412 413 + /* Keep all regions for /sys/kernel/debug/efi */ 414 + if (efi_enabled(EFI_DBG)) 415 + return; 416 + 413 417 for_each_efi_memory_desc(md) { 414 418 unsigned long long start = md->phys_addr; 415 419 unsigned long long size = md->num_pages << EFI_PAGE_SHIFT;
+5
drivers/firmware/efi/Kconfig
··· 239 239 240 240 endmenu 241 241 242 + config EFI_EMBEDDED_FIRMWARE 243 + bool 244 + depends on EFI 245 + select CRYPTO_LIB_SHA256 246 + 242 247 config UEFI_CPER 243 248 bool 244 249
+1
drivers/firmware/efi/Makefile
··· 26 26 obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o 27 27 obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o 28 28 obj-$(CONFIG_EFI_RCI2_TABLE) += rci2-table.o 29 + obj-$(CONFIG_EFI_EMBEDDED_FIRMWARE) += embedded-firmware.o 29 30 30 31 fake_map-y += fake_mem.o 31 32 fake_map-$(CONFIG_X86) += x86_fake_mem.o
+57
drivers/firmware/efi/efi.c
··· 17 17 #include <linux/kobject.h> 18 18 #include <linux/module.h> 19 19 #include <linux/init.h> 20 + #include <linux/debugfs.h> 20 21 #include <linux/device.h> 21 22 #include <linux/efi.h> 22 23 #include <linux/of.h> ··· 326 325 static inline int efivar_ssdt_load(void) { return 0; } 327 326 #endif 328 327 328 + #ifdef CONFIG_DEBUG_FS 329 + 330 + #define EFI_DEBUGFS_MAX_BLOBS 32 331 + 332 + static struct debugfs_blob_wrapper debugfs_blob[EFI_DEBUGFS_MAX_BLOBS]; 333 + 334 + static void __init efi_debugfs_init(void) 335 + { 336 + struct dentry *efi_debugfs; 337 + efi_memory_desc_t *md; 338 + char name[32]; 339 + int type_count[EFI_BOOT_SERVICES_DATA + 1] = {}; 340 + int i = 0; 341 + 342 + efi_debugfs = debugfs_create_dir("efi", NULL); 343 + if (IS_ERR_OR_NULL(efi_debugfs)) 344 + return; 345 + 346 + for_each_efi_memory_desc(md) { 347 + switch (md->type) { 348 + case EFI_BOOT_SERVICES_CODE: 349 + snprintf(name, sizeof(name), "boot_services_code%d", 350 + type_count[md->type]++); 351 + break; 352 + case EFI_BOOT_SERVICES_DATA: 353 + snprintf(name, sizeof(name), "boot_services_data%d", 354 + type_count[md->type]++); 355 + break; 356 + default: 357 + continue; 358 + } 359 + 360 + if (i >= EFI_DEBUGFS_MAX_BLOBS) { 361 + pr_warn("More then %d EFI boot service segments, only showing first %d in debugfs\n", 362 + EFI_DEBUGFS_MAX_BLOBS, EFI_DEBUGFS_MAX_BLOBS); 363 + break; 364 + } 365 + 366 + debugfs_blob[i].size = md->num_pages << EFI_PAGE_SHIFT; 367 + debugfs_blob[i].data = memremap(md->phys_addr, 368 + debugfs_blob[i].size, 369 + MEMREMAP_WB); 370 + if (!debugfs_blob[i].data) 371 + continue; 372 + 373 + debugfs_create_blob(name, 0400, efi_debugfs, &debugfs_blob[i]); 374 + i++; 375 + } 376 + } 377 + #else 378 + static inline void efi_debugfs_init(void) {} 379 + #endif 380 + 329 381 /* 330 382 * We register the efi subsystem with the firmware subsystem and the 331 383 * efivars subsystem with the efi subsystem, if the system was booted with ··· 434 380 pr_err("efivars: Subsystem registration failed.\n"); 435 381 goto err_remove_group; 436 382 } 383 + 384 + if (efi_enabled(EFI_DBG) && efi_enabled(EFI_PRESERVE_BS_REGIONS)) 385 + efi_debugfs_init(); 437 386 438 387 return 0; 439 388
+147
drivers/firmware/efi/embedded-firmware.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Support for extracting embedded firmware for peripherals from EFI code, 4 + * 5 + * Copyright (c) 2018 Hans de Goede <hdegoede@redhat.com> 6 + */ 7 + 8 + #include <linux/dmi.h> 9 + #include <linux/efi.h> 10 + #include <linux/efi_embedded_fw.h> 11 + #include <linux/io.h> 12 + #include <linux/slab.h> 13 + #include <linux/types.h> 14 + #include <linux/vmalloc.h> 15 + #include <crypto/sha.h> 16 + 17 + /* Exported for use by lib/test_firmware.c only */ 18 + LIST_HEAD(efi_embedded_fw_list); 19 + EXPORT_SYMBOL_GPL(efi_embedded_fw_list); 20 + 21 + static bool checked_for_fw; 22 + 23 + static const struct dmi_system_id * const embedded_fw_table[] = { 24 + NULL 25 + }; 26 + 27 + /* 28 + * Note the efi_check_for_embedded_firmwares() code currently makes the 29 + * following 2 assumptions. This may needs to be revisited if embedded firmware 30 + * is found where this is not true: 31 + * 1) The firmware is only found in EFI_BOOT_SERVICES_CODE memory segments 32 + * 2) The firmware always starts at an offset which is a multiple of 8 bytes 33 + */ 34 + static int __init efi_check_md_for_embedded_firmware( 35 + efi_memory_desc_t *md, const struct efi_embedded_fw_desc *desc) 36 + { 37 + struct sha256_state sctx; 38 + struct efi_embedded_fw *fw; 39 + u8 sha256[32]; 40 + u64 i, size; 41 + u8 *map; 42 + 43 + size = md->num_pages << EFI_PAGE_SHIFT; 44 + map = memremap(md->phys_addr, size, MEMREMAP_WB); 45 + if (!map) { 46 + pr_err("Error mapping EFI mem at %#llx\n", md->phys_addr); 47 + return -ENOMEM; 48 + } 49 + 50 + for (i = 0; (i + desc->length) <= size; i += 8) { 51 + if (memcmp(map + i, desc->prefix, EFI_EMBEDDED_FW_PREFIX_LEN)) 52 + continue; 53 + 54 + sha256_init(&sctx); 55 + sha256_update(&sctx, map + i, desc->length); 56 + sha256_final(&sctx, sha256); 57 + if (memcmp(sha256, desc->sha256, 32) == 0) 58 + break; 59 + } 60 + if ((i + desc->length) > size) { 61 + memunmap(map); 62 + return -ENOENT; 63 + } 64 + 65 + pr_info("Found EFI embedded fw '%s'\n", desc->name); 66 + 67 + fw = kmalloc(sizeof(*fw), GFP_KERNEL); 68 + if (!fw) { 69 + memunmap(map); 70 + return -ENOMEM; 71 + } 72 + 73 + fw->data = kmemdup(map + i, desc->length, GFP_KERNEL); 74 + memunmap(map); 75 + if (!fw->data) { 76 + kfree(fw); 77 + return -ENOMEM; 78 + } 79 + 80 + fw->name = desc->name; 81 + fw->length = desc->length; 82 + list_add(&fw->list, &efi_embedded_fw_list); 83 + 84 + return 0; 85 + } 86 + 87 + void __init efi_check_for_embedded_firmwares(void) 88 + { 89 + const struct efi_embedded_fw_desc *fw_desc; 90 + const struct dmi_system_id *dmi_id; 91 + efi_memory_desc_t *md; 92 + int i, r; 93 + 94 + for (i = 0; embedded_fw_table[i]; i++) { 95 + dmi_id = dmi_first_match(embedded_fw_table[i]); 96 + if (!dmi_id) 97 + continue; 98 + 99 + fw_desc = dmi_id->driver_data; 100 + 101 + /* 102 + * In some drivers the struct driver_data contains may contain 103 + * other driver specific data after the fw_desc struct; and 104 + * the fw_desc struct itself may be empty, skip these. 105 + */ 106 + if (!fw_desc->name) 107 + continue; 108 + 109 + for_each_efi_memory_desc(md) { 110 + if (md->type != EFI_BOOT_SERVICES_CODE) 111 + continue; 112 + 113 + r = efi_check_md_for_embedded_firmware(md, fw_desc); 114 + if (r == 0) 115 + break; 116 + } 117 + } 118 + 119 + checked_for_fw = true; 120 + } 121 + 122 + int efi_get_embedded_fw(const char *name, const u8 **data, size_t *size) 123 + { 124 + struct efi_embedded_fw *iter, *fw = NULL; 125 + 126 + if (!checked_for_fw) { 127 + pr_warn("Warning %s called while we did not check for embedded fw\n", 128 + __func__); 129 + return -ENOENT; 130 + } 131 + 132 + list_for_each_entry(iter, &efi_embedded_fw_list, list) { 133 + if (strcmp(name, iter->name) == 0) { 134 + fw = iter; 135 + break; 136 + } 137 + } 138 + 139 + if (!fw) 140 + return -ENOENT; 141 + 142 + *data = fw->data; 143 + *size = fw->length; 144 + 145 + return 0; 146 + } 147 + EXPORT_SYMBOL_GPL(efi_get_embedded_fw);
+7
include/linux/efi.h
··· 1124 1124 #define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */ 1125 1125 #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ 1126 1126 #define EFI_MEM_NO_SOFT_RESERVE 11 /* Is the kernel configured to ignore soft reservations? */ 1127 + #define EFI_PRESERVE_BS_REGIONS 12 /* Are EFI boot-services memory segments available? */ 1127 1128 1128 1129 #ifdef CONFIG_EFI 1129 1130 /* ··· 1552 1551 #else 1553 1552 static inline void 1554 1553 efi_enable_reset_attack_mitigation(void) { } 1554 + #endif 1555 + 1556 + #ifdef CONFIG_EFI_EMBEDDED_FIRMWARE 1557 + void efi_check_for_embedded_firmwares(void); 1558 + #else 1559 + static inline void efi_check_for_embedded_firmwares(void) { } 1555 1560 #endif 1556 1561 1557 1562 efi_status_t efi_random_get_seed(void);
+41
include/linux/efi_embedded_fw.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _LINUX_EFI_EMBEDDED_FW_H 3 + #define _LINUX_EFI_EMBEDDED_FW_H 4 + 5 + #include <linux/list.h> 6 + #include <linux/mod_devicetable.h> 7 + 8 + #define EFI_EMBEDDED_FW_PREFIX_LEN 8 9 + 10 + /* 11 + * This struct and efi_embedded_fw_list are private to the efi-embedded fw 12 + * implementation they are in this header for use by lib/test_firmware.c only! 13 + */ 14 + struct efi_embedded_fw { 15 + struct list_head list; 16 + const char *name; 17 + const u8 *data; 18 + size_t length; 19 + }; 20 + 21 + extern struct list_head efi_embedded_fw_list; 22 + 23 + /** 24 + * struct efi_embedded_fw_desc - This struct is used by the EFI embedded-fw 25 + * code to search for embedded firmwares. 26 + * 27 + * @name: Name to register the firmware with if found 28 + * @prefix: First 8 bytes of the firmware 29 + * @length: Length of the firmware in bytes including prefix 30 + * @sha256: SHA256 of the firmware 31 + */ 32 + struct efi_embedded_fw_desc { 33 + const char *name; 34 + u8 prefix[EFI_EMBEDDED_FW_PREFIX_LEN]; 35 + u32 length; 36 + u8 sha256[32]; 37 + }; 38 + 39 + int efi_get_embedded_fw(const char *name, const u8 **dat, size_t *sz); 40 + 41 + #endif