diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 15:36:30 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2022-01-11 15:36:30 -0800 |
commit | f12fc75ef7db44d71d5a509e2f1bec6966b73776 (patch) | |
tree | 5afdcbdeacae408fb546a60253510d3ea25a0b6c /drivers/firmware | |
parent | f69212114220edf8372867088b97b47760b6839d (diff) | |
parent | 42f4046bc4ba56c6e4d2af7a9d7f70eaa563daec (diff) |
Merge tag 'efi-next-for-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi
Pull EFI updates from Ard Biesheuvel:
- support taking the measurement of the initrd when loaded via the
LoadFile2 protocol
- kobject API cleanup from Greg
- some header file whitespace fixes
* tag 'efi-next-for-v5.17' of git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi:
efi: use default_groups in kobj_type
efi/libstub: measure loaded initrd info into the TPM
efi/libstub: consolidate initrd handling across architectures
efi/libstub: x86/mixed: increase supported argument count
efi/libstub: add prototype of efi_tcg2_protocol::hash_log_extend_event()
include/linux/efi.h: Remove unneeded whitespaces before tabs
Diffstat (limited to 'drivers/firmware')
-rw-r--r-- | drivers/firmware/efi/efivars.c | 3 | ||||
-rw-r--r-- | drivers/firmware/efi/esrt.c | 4 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efi-stub-helper.c | 73 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efi-stub.c | 10 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/efistub.h | 30 | ||||
-rw-r--r-- | drivers/firmware/efi/libstub/x86-stub.c | 26 | ||||
-rw-r--r-- | drivers/firmware/efi/runtime-map.c | 3 |
7 files changed, 108 insertions, 41 deletions
diff --git a/drivers/firmware/efi/efivars.c b/drivers/firmware/efi/efivars.c index e6b16b3a17a8..ea0bc39dc965 100644 --- a/drivers/firmware/efi/efivars.c +++ b/drivers/firmware/efi/efivars.c @@ -352,11 +352,12 @@ static struct attribute *def_attrs[] = { &efivar_attr_raw_var.attr, NULL, }; +ATTRIBUTE_GROUPS(def); static struct kobj_type efivar_ktype = { .release = efivar_release, .sysfs_ops = &efivar_attr_ops, - .default_attrs = def_attrs, + .default_groups = def_groups, }; static ssize_t efivar_create(struct file *filp, struct kobject *kobj, diff --git a/drivers/firmware/efi/esrt.c b/drivers/firmware/efi/esrt.c index d5915272141f..2a2f52b017e7 100644 --- a/drivers/firmware/efi/esrt.c +++ b/drivers/firmware/efi/esrt.c @@ -146,6 +146,8 @@ static struct attribute *esre1_attrs[] = { &esre_last_attempt_status.attr, NULL }; +ATTRIBUTE_GROUPS(esre1); + static void esre_release(struct kobject *kobj) { struct esre_entry *entry = to_entry(kobj); @@ -157,7 +159,7 @@ static void esre_release(struct kobject *kobj) static struct kobj_type esre1_ktype = { .release = esre_release, .sysfs_ops = &esre_attr_ops, - .default_attrs = esre1_attrs, + .default_groups = esre1_groups, }; diff --git a/drivers/firmware/efi/libstub/efi-stub-helper.c b/drivers/firmware/efi/libstub/efi-stub-helper.c index d489bdc645fe..3d972061c1b0 100644 --- a/drivers/firmware/efi/libstub/efi-stub-helper.c +++ b/drivers/firmware/efi/libstub/efi-stub-helper.c @@ -20,10 +20,10 @@ bool efi_nochunk; bool efi_nokaslr = !IS_ENABLED(CONFIG_RANDOMIZE_BASE); -bool efi_noinitrd; int efi_loglevel = CONSOLE_LOGLEVEL_DEFAULT; bool efi_novamap; +static bool efi_noinitrd; static bool efi_nosoftreserve; static bool efi_disable_pci_dma = IS_ENABLED(CONFIG_EFI_DISABLE_PCI_DMA); @@ -625,6 +625,47 @@ efi_status_t efi_load_initrd_cmdline(efi_loaded_image_t *image, load_addr, load_size); } +static const struct { + efi_tcg2_event_t event_data; + efi_tcg2_tagged_event_t tagged_event; + u8 tagged_event_data[]; +} initrd_tcg2_event = { + { + sizeof(initrd_tcg2_event) + sizeof("Linux initrd"), + { + sizeof(initrd_tcg2_event.event_data.event_header), + EFI_TCG2_EVENT_HEADER_VERSION, + 9, + EV_EVENT_TAG, + }, + }, + { + INITRD_EVENT_TAG_ID, + sizeof("Linux initrd"), + }, + { "Linux initrd" }, +}; + +static void efi_measure_initrd(unsigned long load_addr, unsigned long load_size) +{ + efi_guid_t tcg2_guid = EFI_TCG2_PROTOCOL_GUID; + efi_tcg2_protocol_t *tcg2 = NULL; + efi_status_t status; + + efi_bs_call(locate_protocol, &tcg2_guid, NULL, (void **)&tcg2); + if (tcg2) { + status = efi_call_proto(tcg2, hash_log_extend_event, + 0, load_addr, load_size, + &initrd_tcg2_event.event_data); + if (status != EFI_SUCCESS) + efi_warn("Failed to measure initrd data: 0x%lx\n", + status); + else + efi_info("Measured initrd data into PCR %d\n", + initrd_tcg2_event.event_data.event_header.pcr_index); + } +} + /** * efi_load_initrd() - Load initial RAM disk * @image: EFI loaded image protocol @@ -643,17 +684,25 @@ efi_status_t efi_load_initrd(efi_loaded_image_t *image, { efi_status_t status; - if (!load_addr || !load_size) - return EFI_INVALID_PARAMETER; - - status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); - if (status == EFI_SUCCESS) { - efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); - } else if (status == EFI_NOT_FOUND) { - status = efi_load_initrd_cmdline(image, load_addr, load_size, - soft_limit, hard_limit); - if (status == EFI_SUCCESS && *load_size > 0) - efi_info("Loaded initrd from command line option\n"); + if (efi_noinitrd) { + *load_addr = *load_size = 0; + status = EFI_SUCCESS; + } else { + status = efi_load_initrd_dev_path(load_addr, load_size, hard_limit); + if (status == EFI_SUCCESS) { + efi_info("Loaded initrd from LINUX_EFI_INITRD_MEDIA_GUID device path\n"); + if (*load_size > 0) + efi_measure_initrd(*load_addr, *load_size); + } else if (status == EFI_NOT_FOUND) { + status = efi_load_initrd_cmdline(image, load_addr, load_size, + soft_limit, hard_limit); + if (status == EFI_SUCCESS && *load_size > 0) + efi_info("Loaded initrd from command line option\n"); + } + if (status != EFI_SUCCESS) { + efi_err("Failed to load initrd: 0x%lx\n", status); + *load_addr = *load_size = 0; + } } return status; diff --git a/drivers/firmware/efi/libstub/efi-stub.c b/drivers/firmware/efi/libstub/efi-stub.c index 26e69788f27a..e87e7f1b1a33 100644 --- a/drivers/firmware/efi/libstub/efi-stub.c +++ b/drivers/firmware/efi/libstub/efi-stub.c @@ -134,7 +134,6 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, enum efi_secureboot_mode secure_boot; struct screen_info *si; efi_properties_table_t *prop_tbl; - unsigned long max_addr; efi_system_table = sys_table_arg; @@ -240,13 +239,8 @@ efi_status_t __efiapi efi_pe_entry(efi_handle_t handle, if (!fdt_addr) efi_info("Generating empty DTB\n"); - if (!efi_noinitrd) { - max_addr = efi_get_max_initrd_addr(image_addr); - status = efi_load_initrd(image, &initrd_addr, &initrd_size, - ULONG_MAX, max_addr); - if (status != EFI_SUCCESS) - efi_err("Failed to load initrd!\n"); - } + efi_load_initrd(image, &initrd_addr, &initrd_size, ULONG_MAX, + efi_get_max_initrd_addr(image_addr)); efi_random_get_seed(); diff --git a/drivers/firmware/efi/libstub/efistub.h b/drivers/firmware/efi/libstub/efistub.h index cde0a2ef507d..edb77b0621ea 100644 --- a/drivers/firmware/efi/libstub/efistub.h +++ b/drivers/firmware/efi/libstub/efistub.h @@ -31,7 +31,6 @@ extern bool efi_nochunk; extern bool efi_nokaslr; -extern bool efi_noinitrd; extern int efi_loglevel; extern bool efi_novamap; @@ -667,6 +666,29 @@ union apple_properties_protocol { typedef u32 efi_tcg2_event_log_format; +#define INITRD_EVENT_TAG_ID 0x8F3B22ECU +#define EV_EVENT_TAG 0x00000006U +#define EFI_TCG2_EVENT_HEADER_VERSION 0x1 + +struct efi_tcg2_event { + u32 event_size; + struct { + u32 header_size; + u16 header_version; + u32 pcr_index; + u32 event_type; + } __packed event_header; + /* u8[] event follows here */ +} __packed; + +struct efi_tcg2_tagged_event { + u32 tagged_event_id; + u32 tagged_event_data_size; + /* u8 tagged event data follows here */ +} __packed; + +typedef struct efi_tcg2_event efi_tcg2_event_t; +typedef struct efi_tcg2_tagged_event efi_tcg2_tagged_event_t; typedef union efi_tcg2_protocol efi_tcg2_protocol_t; union efi_tcg2_protocol { @@ -677,7 +699,11 @@ union efi_tcg2_protocol { efi_physical_addr_t *, efi_physical_addr_t *, efi_bool_t *); - void *hash_log_extend_event; + efi_status_t (__efiapi *hash_log_extend_event)(efi_tcg2_protocol_t *, + u64, + efi_physical_addr_t, + u64, + const efi_tcg2_event_t *); void *submit_command; void *get_active_pcr_banks; void *set_active_pcr_banks; diff --git a/drivers/firmware/efi/libstub/x86-stub.c b/drivers/firmware/efi/libstub/x86-stub.c index f14c4ff5839f..01ddd4502e28 100644 --- a/drivers/firmware/efi/libstub/x86-stub.c +++ b/drivers/firmware/efi/libstub/x86-stub.c @@ -673,6 +673,7 @@ unsigned long efi_main(efi_handle_t handle, unsigned long bzimage_addr = (unsigned long)startup_32; unsigned long buffer_start, buffer_end; struct setup_header *hdr = &boot_params->hdr; + unsigned long addr, size; efi_status_t status; efi_system_table = sys_table_arg; @@ -761,22 +762,15 @@ unsigned long efi_main(efi_handle_t handle, * arguments will be processed only if image is not NULL, which will be * the case only if we were loaded via the PE entry point. */ - if (!efi_noinitrd) { - unsigned long addr, size; - - status = efi_load_initrd(image, &addr, &size, - hdr->initrd_addr_max, ULONG_MAX); - - if (status != EFI_SUCCESS) { - efi_err("Failed to load initrd!\n"); - goto fail; - } - if (size > 0) { - efi_set_u64_split(addr, &hdr->ramdisk_image, - &boot_params->ext_ramdisk_image); - efi_set_u64_split(size, &hdr->ramdisk_size, - &boot_params->ext_ramdisk_size); - } + status = efi_load_initrd(image, &addr, &size, hdr->initrd_addr_max, + ULONG_MAX); + if (status != EFI_SUCCESS) + goto fail; + if (size > 0) { + efi_set_u64_split(addr, &hdr->ramdisk_image, + &boot_params->ext_ramdisk_image); + efi_set_u64_split(size, &hdr->ramdisk_size, + &boot_params->ext_ramdisk_size); } /* diff --git a/drivers/firmware/efi/runtime-map.c b/drivers/firmware/efi/runtime-map.c index ad9ddefc9dcb..92a3d45a795c 100644 --- a/drivers/firmware/efi/runtime-map.c +++ b/drivers/firmware/efi/runtime-map.c @@ -79,6 +79,7 @@ static struct attribute *def_attrs[] = { &map_attribute_attr.attr, NULL }; +ATTRIBUTE_GROUPS(def); static const struct sysfs_ops map_attr_ops = { .show = map_attr_show, @@ -94,7 +95,7 @@ static void map_release(struct kobject *kobj) static struct kobj_type __refdata map_ktype = { .sysfs_ops = &map_attr_ops, - .default_attrs = def_attrs, + .default_groups = def_groups, .release = map_release, }; |