// 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()) return0;
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.
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.