From: Manish Honap <[email protected]> cxl_map_component_regs() claims each mapped sub-block with devm_request_mem_region(). A driver that already requested the whole component register BAR, such as vfio-cxl, would then collide with that claim and fail to map the HDM decoder and RAS blocks.
Add cxl_reg_map_add_owned_resource() so such a driver records the resource it already owns on the register map, and skip the sub-block request when the block falls within an owned resource. Assisted-by: LLM Signed-off-by: Manish Honap <[email protected]> --- drivers/cxl/core/regs.c | 17 +++++++++++++++-- include/cxl/cxl.h | 2 ++ include/cxl/pci.h | 3 +++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index d79550dbb484..58a7c5cafb45 100644 --- a/drivers/cxl/core/regs.c +++ b/drivers/cxl/core/regs.c @@ -216,6 +216,13 @@ void __iomem *devm_cxl_iomap_block(struct device *dev, resource_size_t addr, } EXPORT_SYMBOL_NS_GPL(devm_cxl_iomap_block, "CXL"); +void cxl_reg_map_add_owned_resource(struct cxl_register_map *map, + struct resource *res) +{ + map->owned = res; +} +EXPORT_SYMBOL_NS_GPL(cxl_reg_map_add_owned_resource, "CXL"); + int cxl_map_component_regs(const struct cxl_register_map *map, struct cxl_component_regs *regs, unsigned long map_mask) @@ -234,6 +241,7 @@ int cxl_map_component_regs(const struct cxl_register_map *map, struct mapinfo *mi = &mapinfo[i]; resource_size_t addr; resource_size_t length; + struct resource res; if (!mi->rmap->valid) continue; @@ -241,8 +249,13 @@ int cxl_map_component_regs(const struct cxl_register_map *map, continue; addr = map->resource + mi->rmap->offset; length = mi->rmap->size; - *(mi->addr) = devm_cxl_iomap_block(host, addr, length); - if (!*(mi->addr)) + res = DEFINE_RES_MEM(addr, length); + + if (map->owned && resource_contains(map->owned, &res)) + *mi->addr = devm_cxl_ioremap_block(host, addr, length); + else + *mi->addr = devm_cxl_iomap_block(host, addr, length); + if (!*mi->addr) return -ENOMEM; } diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h index a02792969e0a..92314f67b702 100644 --- a/include/cxl/cxl.h +++ b/include/cxl/cxl.h @@ -217,6 +217,7 @@ struct cxl_pmu_reg_map { * @resource: physical resource base of the register block * @max_size: maximum mapping size to perform register search * @reg_type: see enum cxl_regloc_type + * @owned: driver-owned resource whose sub-blocks are mapped without re-requesting * @component_map: cxl_reg_map for component registers * @device_map: cxl_reg_maps for device registers * @pmu_map: cxl_reg_maps for CXL Performance Monitoring Units @@ -227,6 +228,7 @@ struct cxl_register_map { resource_size_t resource; resource_size_t max_size; u8 reg_type; + struct resource *owned; union { struct cxl_component_reg_map component_map; struct cxl_device_reg_map device_map; diff --git a/include/cxl/pci.h b/include/cxl/pci.h index 3e0000015871..8e0b3bd0b3c1 100644 --- a/include/cxl/pci.h +++ b/include/cxl/pci.h @@ -16,7 +16,10 @@ enum cxl_regloc_type { struct cxl_register_map; struct pci_dev; +struct resource; int cxl_pci_setup_regs(struct pci_dev *pdev, enum cxl_regloc_type type, struct cxl_register_map *map); +void cxl_reg_map_add_owned_resource(struct cxl_register_map *map, + struct resource *res); #endif -- 2.25.1

