From: Shuai Xue <[email protected]> The .io sub-region of the component register block was created with NULL ops, so a read falling into it (e.g. a vfio passthrough pread of a non-decoder dword of the component BAR) failed the bus transaction. Under TCG this raises a synchronous external abort on Arm guests (ESR DFSC=0x10).
CXL r4.0 Table 8-73 reserves the range, and reserved registers read 0, so attach read-0/write-ignore ops to .io. Signed-off-by: Shuai Xue <[email protected]> [ mhonap: drop the comment above the .io region init ] Signed-off-by: Manish Honap <[email protected]> --- hw/cxl/cxl-component-utils.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/hw/cxl/cxl-component-utils.c b/hw/cxl/cxl-component-utils.c index a624357978..fc32be77a9 100644 --- a/hw/cxl/cxl-component-utils.c +++ b/hw/cxl/cxl-component-utils.c @@ -264,6 +264,23 @@ static const MemoryRegionOps cache_mem_ops = { }, }; +/* CXL r4.0 Table 8-73: the CXL.io range is reserved */ +static uint64_t cxl_io_reg_read(void *opaque, hwaddr addr, unsigned size) +{ + return 0; +} + +static void cxl_io_reg_write(void *opaque, hwaddr addr, uint64_t val, + unsigned size) +{ +} + +static const MemoryRegionOps cxl_io_reg_ops = { + .read = cxl_io_reg_read, + .write = cxl_io_reg_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + void cxl_component_register_block_init(Object *obj, CXLComponentState *cxl_cstate, const char *type) @@ -273,8 +290,7 @@ void cxl_component_register_block_init(Object *obj, memory_region_init(&cregs->component_registers, obj, type, CXL2_COMPONENT_BLOCK_SIZE); - /* io registers controls link which we don't care about in QEMU */ - memory_region_init_io(&cregs->io, obj, NULL, NULL, ".io", + memory_region_init_io(&cregs->io, obj, &cxl_io_reg_ops, NULL, ".io", CXL2_COMPONENT_IO_REGION_SIZE); memory_region_init_io(&cregs->cache_mem, obj, &cache_mem_ops, cxl_cstate, ".cache_mem", CXL2_COMPONENT_CM_REGION_SIZE); -- 2.53.0
