diff --git a/drivers/firmware/google/coreboot_table.c b/drivers/firmware/google/coreboot_table.c index e63933ff6747..993056a739ad 100644 --- a/drivers/firmware/google/coreboot_table.c +++ b/drivers/firmware/google/coreboot_table.c @@ -13,8 +13,10 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -123,7 +125,7 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_ ptr_end = ptr + len; ptr_entry = ptr + header->header_bytes; - for (i = 0; i < header->table_entries; i++) { + for (i = 0; i < header->table_entries; i++, ptr_entry += entry->size) { if (ptr_entry + sizeof(*entry) > ptr_end) return -EINVAL; entry = ptr_entry; @@ -147,6 +149,26 @@ 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) { + kfree(device); + continue; + } dev_set_name(&device->dev, "cbmem-%08x", device->cbmem_entry.id); break; @@ -155,8 +177,6 @@ static int coreboot_table_populate(struct device *dev, void *ptr, resource_size_ break; } - ptr_entry += entry->size; - ret = device_register(&device->dev); if (ret) { dev_warn(dev, "failed to register coreboot device: %d\n", ret);