mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 12:44:03 +02:00
firmware: coreboot: Skip no-map CBMEM entries
On ARM64 platforms, certain reserved memory regions (like those used by pKVM) are marked with the 'no-map' property. This indicates that the host kernel is forbidden from creating a structural mapping for these regions. The coreboot table may describe CBMEM entries that overlap with or are entirely contained within these no-map regions. Attempting to populate these entries as devices and subsequently remapping them can lead to system crashes or security violations. Refine the coreboot table population logic to verify that each CBMEM entry resides in 'Known Good' memory before creating a device. An entry is only considered safe if it is entirely System RAM or entirely standard Reserved memory (tagged with IORES_DESC_RESERVED). This dual-check ensures that: 1. On ARM64, no-map regions are filtered out as they are IORESOURCE_MEM (see request_standard_resources() in arch/arm64/kernel/setup.c). 2. On x86, standard reserved regions (IORES_DESC_RESERVED) remain supported. Signed-off-by: Yidi Lin <yidilin@google.com> Signed-off-by: Hsin-Te Yuan <yuanhsinte@chromium.org> Link: https://lore.kernel.org/r/20260717-coreboot-v2-1-8f8b389e3758@chromium.org Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
This commit is contained in:
parent
65a9b9b2de
commit
e31ecda9e3
|
|
@ -13,8 +13,10 @@
|
|||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/device-id/coreboot.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user