// SPDX-License-Identifier: GPL-2.0 #include #include #include #include "efistub.h" static efi_guid_t loader_entry_guid = LINUX_EFI_LOADER_ENTRY_GUID; static const struct efi_hd_dev_path * efi_bli_find_hd_node(const struct efi_dev_path *path) { const struct efi_dev_path *node; u16 node_len; for (node = path; node->header.type != EFI_DEV_END_PATH && node->header.type != EFI_DEV_END_PATH2; node = (const void *)node + node_len) { node_len = get_unaligned_le16(&node->header.length); if (node_len < sizeof(node->header)) return NULL; if (node->header.type != EFI_DEV_MEDIA || node->header.sub_type != EFI_DEV_MEDIA_HARD_DRIVE) continue; if (node_len < sizeof(node->hd)) return NULL; if (node->hd.partition_format != EFI_HD_PARTITION_FORMAT_GPT || node->hd.signature_type != EFI_HD_SIGNATURE_TYPE_GUID) continue; return &node->hd; } return NULL; } static void efi_bli_populate_loader_part_uuid(const efi_loaded_image_t *image) { static efi_guid_t device_path_guid = EFI_DEVICE_PATH_PROTOCOL_GUID; efi_char16_t partuuid[UUID_STRING_LEN + 1]; const struct efi_hd_dev_path *hd_node; const struct efi_dev_path *path; if (efi_bs_call(handle_protocol, efi_table_attr(image, device_handle), &device_path_guid, (void **)&path) != EFI_SUCCESS) return; hd_node = efi_bli_find_hd_node(path); if (!hd_node) return; if (efi_snprintf(partuuid, ARRAY_SIZE(partuuid), "%pUl", &hd_node->signature) != UUID_STRING_LEN) return; set_efi_var(L"LoaderDevicePartUUID", &loader_entry_guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(partuuid), partuuid); } void efi_bli_set_variables(const efi_loaded_image_t *image) { static efi_char16_t loader_info[] = L"Linux EFI stub " UTS_RELEASE; unsigned long size = 0; if (!image) return; if (get_efi_var(L"LoaderInfo", &loader_entry_guid, NULL, &size, NULL) != EFI_NOT_FOUND) return; if (set_efi_var(L"LoaderInfo", &loader_entry_guid, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, sizeof(loader_info), loader_info) != EFI_SUCCESS) return; efi_bli_populate_loader_part_uuid(image); }