On Thu, 27 Nov 2025 22:55:23 +0000 Alireza Sanaee <[email protected]> wrote:
> Add alias direct mapping into the fixed memory window. Say more on why, plus provide sequence of commands to do this. > > Signed-off-by: Alireza Sanaee <[email protected]> > diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c > index b785553225..15114a5314 100644 > --- a/hw/cxl/cxl-mailbox-utils.c > +++ b/hw/cxl/cxl-mailbox-utils.c > @@ -3123,6 +3141,7 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const struct > cxl_cmd *cmd, > } > > mr = host_memory_backend_get_memory(hmb_dc); > + > if (!mr) { > qemu_log("Could not get memory region from host memory " > "backend\n"); > @@ -3132,11 +3151,32 @@ static CXLRetCode cmd_dcd_add_dyn_cap_rsp(const > struct cxl_cmd *cmd, > memory_region_set_nonvolatile(mr, false); > memory_region_set_enabled(mr, true); > host_memory_backend_set_mapped(hmb_dc, true); > + > + if (ct3d->direct_mr_enabled) { > + g_autofree char *direct_mapping_name = > + g_strdup_printf("cxl-direct-mapping-%d", mr_idx); > + int region_offset = dpa - ct3d->dc.regions[rid].base; > + MemoryRegion *dr_dc_mr = &ct3d->dc.dc_direct_mr[mr_idx]; > + memory_region_init_alias(dr_dc_mr, OBJECT(ct3d), > + direct_mapping_name, mr, > region_offset, > + ct3d->dc.dc_decoder_window.size); > + memory_region_add_subregion(&fw->mr, > + ct3d->dc.dc_decoder_window.base - > + fw->base + offset, > + dr_dc_mr); > + /* > + * for now assuming 4 extents and 4 direct mapping memory > + * regions. > + */ > + ct3d->dc.cur_direct_region_idx = > + (ct3d->dc.cur_direct_region_idx + 1) % 4; Don't do a modulo as that'll just overwrite someone else. Just check if we are out of space. Ultimately they will come and go in random orders so you'll need a different data structure to avoid running out too early. > + } > diff --git a/include/hw/cxl/cxl_device.h b/include/hw/cxl/cxl_device.h > index fe0c44e8d7..1a521df881 100644 > --- a/include/hw/cxl/cxl_device.h > +++ b/include/hw/cxl/cxl_device.h > @@ -524,6 +524,7 @@ typedef struct CXLDCExtent { > uint16_t shared_seq; > uint8_t rsvd[0x6]; > int rid; > + uint64_t offset; > > QTAILQ_ENTRY(CXLDCExtent) node; > } CXLDCExtent; > @@ -589,6 +590,7 @@ struct CXLType3Dev { > > /* State */ > MemoryRegion direct_mr[CXL_HDM_DECODER_COUNT]; > + bool direct_mr_enabled; > AddressSpace hostvmem_as; > AddressSpace hostpmem_as; > CXLComponentState cxl_cstate; > @@ -633,6 +635,14 @@ struct CXLType3Dev { > HostMemoryBackend *host_dc; > AddressSpace host_dc_as; > struct CXLFixedWindow *fw; > + int cur_direct_region_idx; > + /* > + * dc_decoder_window represents the CXL Decoder Window What decoder? Needs more info on why this exists. There is no particular reason a decoder maps to a DCD region but that's probably the largest granularity we'll get. Could well point to just part of a dc region. I don't mind rejecting fast path in those corner cases but we need to make the slow path work then. > + */ > + struct decoder_window { > + hwaddr base; > + hwaddr size; > + } dc_decoder_window; > /* > * total_capacity is equivalent to the dynamic capability > * memory region size. > @@ -647,6 +657,11 @@ struct CXLType3Dev { > > uint8_t num_regions; /* 0-8 regions */ > CXLDCRegion regions[DCD_MAX_NUM_REGION]; > + /* > + * Assume 4 now but many possible, each region is one alias an extent > + * to allow performance translation in KVM. The KVM bit doesn't matter. It is better with this in TCG as well. I think we'll ultimately want a list for these - but this is fine for now. > + */ > + MemoryRegion dc_direct_mr[4]; > } dc;
