On Mon, Oct 26, 2026 at 07:03:24PM +0900, Yukiya Takaki wrote:
> The previously added `hpa_offset` on CXLType3Dev records the offset of a
> device within its CFMW window, but there is no simple helper to obtain the
> full host physical address (HPA) range for a given Type 3 device.
> 
> This patch adds `ct3_type3_get_hpm_range()`, which returns the HPA base and
> size for a CXLType3Dev by combining the CFMW base, the per‑device offset
> and the device size. The helper is declared in the header so that other
> code can use it when building tables and regions.
> 
> Co-developed-by: Li Zhijian <[email protected]>
> Signed-off-by: Yukiya Takaki <[email protected]>
> ---
>  hw/mem/cxl_type3.c          | 40 +++++++++++++++++++++++++++++++++++++
>  include/hw/cxl/cxl_device.h |  1 +
>  2 files changed, 41 insertions(+)
> 
> diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c
> index d08a4255c9..811f8e247d 100644
> --- a/hw/mem/cxl_type3.c
> +++ b/hw/mem/cxl_type3.c
> @@ -1358,6 +1358,46 @@ MemTxResult cxl_type3_write(PCIDevice *d, hwaddr 
> host_addr, uint64_t data,
>      return address_space_write(as, dpa_offset, attrs, &data, size);
>  }
>  
> +static uint64_t c3t_addr_size(DeviceState *dev)
> +{
> +    CXLType3Dev *ct3d = CXL_TYPE3(dev);
> +    MemoryRegion *vmr = host_memory_backend_get_memory(ct3d->hostvmem);
> +
I think the reason program-hdm-decoder=true fails on CXL PMEM
topologies as you mentioned in the cover letter is because this function only
calculates size from ct3d->hostvmem, which will pass NULL to
memory_region_size() here.

RAM and PMEM size is already calculated in cxl_setup_memory() in
ct3d->cxl_dstate.static_mem_size

I think this helper can be deleted by directly using static_mem_size in 
ct3_type3_get_hpm_range().

Or if you prefer not to support PMEM for this feature at all, you can
reject it in patch 2:

static bool cxl_setup_memory(CXLType3Dev *ct3d, Error **errp) {
...
if (ct3d->program_hdm_decoder &&
        (!ct3d->hostvmem || ct3d->hostpmem || ct3d->dc.num_regions)) {
        error_setg(errp, "program-hdm-decoder requires volatile-memdev "
                         "and no persistent or dynamic capacity");
        return false;
    }

}
> +    return memory_region_size(vmr);
> +}
> +
> +static uint64_t c3t_hpa_base(DeviceState *dev)
> +{
> +    GSList *cfmws_list, *iter;
> +
> +    cfmws_list = cxl_fmws_get_all_sorted();
> +    for (iter = cfmws_list; iter; iter = iter->next) {
> +        struct CXLFixedWindow *fw;
> +
> +        if (!object_dynamic_cast(iter->data, TYPE_CXL_FMW)) {
> +            continue;
> +        }
> +        fw = CXL_FMW(iter->data);
> +
> +        PXBCXLDev *pxb = fw->target_hbs[0];
> +        if (ct3d_to_cxl_pxb(dev) != pxb->cxl_host_bridge) {
> +            continue;
> +        }
> +
> +        g_slist_free(cfmws_list);
> +        return fw->base;
> +    }
> +    g_slist_free(cfmws_list);
> +
> +    return 0;
> +}
> +
> +void ct3_type3_get_hpm_range(CXLType3Dev *dev, uint64_t *base, uint64_t 
> *size)
> +{
> +    *base = c3t_hpa_base(DEVICE(dev)) + dev->hpa_offset;
> +    *size = c3t_addr_size(DEVICE(dev));
        *size = dev->cxl_dstate.static_mem_size;

Thanks,
Anisa

> +}
> +
>  static void ct3d_reset(DeviceState *dev)
>  {
>      CXLType3Dev *ct3d = CXL_TYPE3(dev);
> diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h
> index c3a729f8c5..07654f4b62 100644
> --- a/include/hw/cxl/cxl_device.h
> +++ b/include/hw/cxl/cxl_device.h
> @@ -878,6 +878,7 @@ void ct3_clear_region_block_backed(CXLType3Dev *ct3d, 
> uint64_t dpa,
>                                     uint64_t len);
>  bool ct3_test_region_block_backed(CXLType3Dev *ct3d, uint64_t dpa,
>                                    uint64_t len);
> +void ct3_type3_get_hpm_range(CXLType3Dev *dev, uint64_t *base, uint64_t 
> *size);
>  void cxl_assign_event_header(CXLEventRecordHdr *hdr,
>                               const QemuUUID *uuid, uint32_t flags,
>                               uint8_t length, uint64_t timestamp,
> -- 
> 2.52.0
> 

Reply via email to