summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichał Kopeć <michal@nozomi.space>2026-10-17 11:03:51 +0200
committerTzung-Bi Shih <tzungbi@kernel.org>2026-11-02 02:48:43 +0000
commite094fd05defaf0b05774ea1c65fc2d0ab798c809 (patch)
tree2bd470093f0085fa621f109dfa4baae71b686133
parentf2e05ce9763feb1dd7da15afd2cc61df227ee85a (diff)
firmware: coreboot: Don't skip CBMEM entries outside of known memory
coreboot leaves CBMEM out of the /memory node of the device tree that it passes to FIT payloads, e.g. LinuxBoot on arm64 Chromebooks, and only lists it in the memory reservation block. The kernel has no resource for that memory, so region_intersects() reports it as neither System RAM nor Reserved memory, and since commit e31ecda9e3af ("firmware: coreboot: Skip no-map CBMEM entries") all CBMEM entries are skipped on such boards. That loses the coreboot log, the TPM event log and everything else that CBMEM devices expose. Also accept entries that don't intersect any memory resource. No-map regions are still skipped, as they are IORESOURCE_MEM resources, as are device regions. Fixes: e31ecda9e3af ("firmware: coreboot: Skip no-map CBMEM entries") Signed-off-by: Michał Kopeć <michal@nozomi.space> Link: https://lore.kernel.org/r/20261017090351.1266064-1-michal@nozomi.space Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
-rw-r--r--drivers/firmware/coreboot/coreboot_table.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/drivers/firmware/coreboot/coreboot_table.c b/drivers/firmware/coreboot/coreboot_table.c
index 2c8c928fbb33..5980dcc00e07 100644
--- a/drivers/firmware/coreboot/coreboot_table.c
+++ b/drivers/firmware/coreboot/coreboot_table.c
@@ -114,6 +114,30 @@ void coreboot_driver_unregister(struct coreboot_driver *driver)
}
EXPORT_SYMBOL(coreboot_driver_unregister);
+/*
+ * Whether the memory of a CBMEM entry may be mapped: it must be exclusively
+ * System RAM, or exclusively Reserved memory, as CBMEM often is on x86, or
+ * memory that the kernel doesn't know about at all. coreboot leaves CBMEM out
+ * of the /memory node of the device tree that it passes to FIT payloads, e.g.
+ * on arm64, and only lists it in the memory reservation block.
+ *
+ * Anything else, such as no-map regions on arm64, which are IORESOURCE_MEM
+ * (see request_standard_resources() in arch/arm64/kernel/setup.c), must not
+ * be mapped.
+ */
+static bool cbmem_entry_is_mappable(const struct lb_cbmem_entry *entry)
+{
+ resource_size_t start = entry->address;
+ size_t size = entry->entry_size;
+
+ return region_intersects(start, size, IORESOURCE_SYSTEM_RAM,
+ IORES_DESC_NONE) == REGION_INTERSECTS ||
+ region_intersects(start, size, IORESOURCE_MEM,
+ IORES_DESC_RESERVED) == REGION_INTERSECTS ||
+ region_intersects(start, size, IORESOURCE_MEM,
+ IORES_DESC_NONE) == REGION_DISJOINT;
+}
+
static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_t len)
{
int i, ret;
@@ -149,23 +173,7 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_
switch (device->entry.tag) {
case LB_TAG_CBMEM_ENTRY:
- /*
- * Skip entries that are not exclusively System RAM or
- * Reserved memory.
- * On ARM64, no-map regions are filtered out as they are
- * IORESOURCE_MEM (see request_standard_resources() in
- * arch/arm64/kernel/setup.c).
- * On x86, CBMEM often resides in standard reserved regions
- * (IORES_DESC_RESERVED).
- */
- if (region_intersects(device->cbmem_entry.address,
- device->cbmem_entry.entry_size,
- IORESOURCE_SYSTEM_RAM,
- IORES_DESC_NONE) != REGION_INTERSECTS &&
- region_intersects(device->cbmem_entry.address,
- device->cbmem_entry.entry_size,
- IORESOURCE_MEM,
- IORES_DESC_RESERVED) != REGION_INTERSECTS) {
+ if (!cbmem_entry_is_mappable(&device->cbmem_entry)) {
kfree(device);
continue;
}