// SPDX-License-Identifier: GPL-2.0+ /* * esrt.c * * This module exports EFI System Resource Table (ESRT) entries into userspace * through the sysfs file system. The ESRT provides a read-only catalog of * system components for which the system accepts firmware upgrades via UEFI's * "Capsule Update" feature. This module allows userland utilities to evaluate * what firmware updates can be applied to this system, and potentially arrange * for those updates to occur. * * Data is currently found below /sys/firmware/efi/esrt/...
*/ #define pr_fmt(fmt) "esrt: " fmt
/* * _count and _version are what they seem like. _max is actually just * accounting info for the firmware when creating the table; it should never * have been exposed to us. To wit, the spec says: * The maximum number of resource array entries that can be within the * table without reallocating the table, must not be zero. * Since there's no guidance about what that means in terms of memory layout, * it means nothing to us.
*/ struct efi_system_resource_table {
u32 fw_resource_count;
u32 fw_resource_count_max;
u64 fw_resource_version;
u8 entries[];
};
/* * remap the table, validate it, mark it reserved and unmap it.
*/ void __init efi_esrt_init(void)
{ void *va; struct efi_system_resource_table tmpesrt;
size_t size, max, entry_size, entries_size;
efi_memory_desc_t md; int rc;
phys_addr_t end;
if (!efi_enabled(EFI_MEMMAP) && !efi_enabled(EFI_PARAVIRT)) return;
pr_debug("esrt-init: loading.\n"); if (!esrt_table_exists()) return;
rc = efi_mem_desc_lookup(efi.esrt, &md); if (rc < 0 ||
(!(md.attribute & EFI_MEMORY_RUNTIME) &&
md.type != EFI_BOOT_SERVICES_DATA &&
md.type != EFI_RUNTIME_SERVICES_DATA &&
md.type != EFI_ACPI_RECLAIM_MEMORY &&
md.type != EFI_ACPI_MEMORY_NVS)) {
pr_warn("ESRT header is not in the memory map.\n"); return;
}
max = efi_mem_desc_end(&md) - efi.esrt;
size = sizeof(*esrt);
if (max < size) {
pr_err("ESRT header doesn't fit on single memory map entry. (size: %zu max: %zu)\n",
size, max); return;
}
va = early_memremap(efi.esrt, size); if (!va) {
pr_err("early_memremap(%p, %zu) failed.\n", (void *)efi.esrt,
size); return;
}
memcpy(&tmpesrt, va, sizeof(tmpesrt));
early_memunmap(va, size);
if (tmpesrt.fw_resource_version != 1) {
pr_err("Unsupported ESRT version %lld.\n",
tmpesrt.fw_resource_version); return;
}
entry_size = sizeof(struct efi_system_resource_entry_v1); if (tmpesrt.fw_resource_count > 0 && max - size < entry_size) {
pr_err("ESRT memory map entry can only hold the header. (max: %zu size: %zu)\n",
max - size, entry_size); return;
}
/* * The format doesn't really give us any boundary to test here, * so I'm making up 128 as the max number of individually updatable * components we support. * 128 should be pretty excessive, but there's still some chance * somebody will do that someday and we'll need to raise this.
*/ if (tmpesrt.fw_resource_count > 128) {
pr_err("ESRT says fw_resource_count has very large value %d.\n",
tmpesrt.fw_resource_count); return;
}
/* * We know it can't be larger than N * sizeof() here, and N is limited * by the previous test to a small number, so there's no overflow.
*/
entries_size = tmpesrt.fw_resource_count * entry_size; if (max < size + entries_size) {
pr_err("ESRT does not fit on single memory map entry (size: %zu max: %zu)\n",
size, max); return;
}
end = esrt_data + size;
pr_info("Reserving ESRT space from %pa to %pa.\n", &esrt_data, &end); if (md.type == EFI_BOOT_SERVICES_DATA)
efi_mem_reserve(esrt_data, esrt_data_size);
pr_debug("esrt-init: loaded.\n");
}
staticint __init register_entries(void)
{ struct efi_system_resource_entry_v1 *v1_entries = (void *)esrt->entries; int i, rc;
if (!esrt_table_exists()) return 0;
for (i = 0; i < le32_to_cpu(esrt->fw_resource_count); i++) { void *esre = NULL; if (esrt->fw_resource_version == 1) {
esre = &v1_entries[i];
} else {
pr_err("Unsupported ESRT version %lld.\n",
esrt->fw_resource_version); return -EINVAL;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.