RE: [PATCH 05/20] cxl: Expose BAR index and offset from register map

From: Manish Honap

Date: Fri Mar 13 2026 - 06:14:28 EST




> -----Original Message-----
> From: Dave Jiang <dave.jiang@xxxxxxxxx>
> Sent: 13 March 2026 02:29
> To: Manish Honap <mhonap@xxxxxxxxxx>; Aniket Agashe <aniketa@xxxxxxxxxx>;
> Ankit Agrawal <ankita@xxxxxxxxxx>; Alex Williamson
> <alwilliamson@xxxxxxxxxx>; Vikram Sethi <vsethi@xxxxxxxxxx>; Jason
> Gunthorpe <jgg@xxxxxxxxxx>; Matt Ochs <mochs@xxxxxxxxxx>; Shameer Kolothum
> Thodi <skolothumtho@xxxxxxxxxx>; alejandro.lucero-palau@xxxxxxx;
> dave@xxxxxxxxxxxx; jonathan.cameron@xxxxxxxxxx;
> alison.schofield@xxxxxxxxx; vishal.l.verma@xxxxxxxxx; ira.weiny@xxxxxxxxx;
> dan.j.williams@xxxxxxxxx; jgg@xxxxxxxx; Yishai Hadas <yishaih@xxxxxxxxxx>;
> kevin.tian@xxxxxxxxx
> Cc: Neo Jia <cjia@xxxxxxxxxx>; Tarun Gupta (SW-GPU) <targupta@xxxxxxxxxx>;
> Zhi Wang <zhiw@xxxxxxxxxx>; Krishnakant Jaju <kjaju@xxxxxxxxxx>; linux-
> kernel@xxxxxxxxxxxxxxx; linux-cxl@xxxxxxxxxxxxxxx; kvm@xxxxxxxxxxxxxxx
> Subject: Re: [PATCH 05/20] cxl: Expose BAR index and offset from register
> map
>
> External email: Use caution opening links or attachments
>
>
> On 3/11/26 1:34 PM, mhonap@xxxxxxxxxx wrote:
> > From: Manish Honap <mhonap@xxxxxxxxxx>
> >
> > The Register Locator DVSEC (CXL 2.0 8.1.9) describes register blocks
> > by
>
> CXL r4.0
>
> Let's keep it to the latest spec version.

Okay, I will update the spec version references to r4.0

>
> > BAR index (BIR) and offset within the BAR. CXL core currently only
> > stores the resolved HPA (resource + offset) in struct
> > cxl_register_map, so callers that need to use pci_iomap() or report
> > the BAR to userspace must reverse-engineer the BAR from the HPA.
> >
> > Add bar_index and bar_offset to struct cxl_register_map and fill them
> > in cxl_decode_regblock() when the regblock is BAR-backed (BIR 0-5).
> > Add cxl_regblock_get_bar_info() so callers (e.g. vfio-cxl) can get BAR
> > index and offset directly and use pci_iomap() instead of ioremap(HPA).
> >
> > Signed-off-by: Manish Honap <mhonap@xxxxxxxxxx>
> > ---
> > drivers/cxl/core/regs.c | 29 +++++++++++++++++++++++++++++
> > include/cxl/cxl.h | 11 +++++++++++
> > 2 files changed, 40 insertions(+)
> >
> > diff --git a/drivers/cxl/core/regs.c b/drivers/cxl/core/regs.c index
> > 20c2d9fbcfe7..720eb6eb5a45 100644
> > --- a/drivers/cxl/core/regs.c
> > +++ b/drivers/cxl/core/regs.c
> > @@ -287,9 +287,37 @@ static bool cxl_decode_regblock(struct pci_dev
> *pdev, u32 reg_lo, u32 reg_hi,
> > map->reg_type = reg_type;
> > map->resource = pci_resource_start(pdev, bar) + offset;
> > map->max_size = pci_resource_len(pdev, bar) - offset;
> > + map->bar_index = (bar >= 0 && bar < PCI_STD_NUM_BARS) ? (u8)bar
> > + : 0xFF;
>
> map->bar_index = bar should be fine. Otherwise the pci_resource_start()
> and pci_resource_len() would also be invalid.

Okay, I will update this.

>
>
> > + map->bar_offset = offset;
> > return true;
> > }
> >
> > +/**
> > + * cxl_regblock_get_bar_info() - Get BAR index and offset for a
> > +BAR-backed regblock
> > + * @map: Register map from cxl_find_regblock() or
> > +cxl_find_regblock_instance()
> > + * @bar_index: Output BAR index (0-5). Optional, may be NULL.
> > + * @bar_offset: Output offset within the BAR. Optional, may be NULL.
> > + *
> > + * When the register block was found via the Register Locator DVSEC
> > +and
> > + * lives in a PCI BAR (BIR 0-5), this returns the BAR index and the
> > +offset
> > + * within that BAR. Callers can use pci_iomap(pdev, bar_index, size)
> > +and
> > + * base + bar_offset instead of ioremap(map->resource).
> > + *
> > + * Return: 0 if the regblock is BAR-backed (bar_index <= 5), -EINVAL
> otherwise.
> > + */
> > +int cxl_regblock_get_bar_info(const struct cxl_register_map *map, u8
> *bar_index,
> > + resource_size_t *bar_offset) {
> > + if (!map || map->bar_index > PCI_STD_NUM_BARS - 1)
>
> map->bar_index == 0xff? Otherwise it's probably a hardware issue right?
>

Okay, agreed.

> DJ
>
> > + return -EINVAL;
> > + if (bar_index)
> > + *bar_index = map->bar_index;
> > + if (bar_offset)
> > + *bar_offset = map->bar_offset;
> > + return 0;
> > +}
> > +EXPORT_SYMBOL_NS_GPL(cxl_regblock_get_bar_info, "CXL");
> > +
> > /*
> > * __cxl_find_regblock_instance() - Locate a register block or count
> instances by type / index
> > * Use CXL_INSTANCES_COUNT for @index if counting instances.
> > @@ -308,6 +336,7 @@ static int __cxl_find_regblock_instance(struct
> > pci_dev *pdev, enum cxl_regloc_ty
> >
> > *map = (struct cxl_register_map) {
> > .host = &pdev->dev,
> > + .bar_index = 0xFF,
> > .resource = CXL_RESOURCE_NONE,
> > };
> >
> > diff --git a/include/cxl/cxl.h b/include/cxl/cxl.h index
> > 684603799fb1..08e327a929ba 100644
> > --- a/include/cxl/cxl.h
> > +++ b/include/cxl/cxl.h
> > @@ -134,9 +134,16 @@ 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
> > + * @bar_index: PCI BAR index (0-5) when regblock is BAR-backed; 0xFF
> > + otherwise
> > + * @bar_offset: offset within the BAR; only valid when bar_index <= 5
> > * @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
> > + *
> > + * When the register block is described by the Register Locator DVSEC
> > + with
> > + * a BAR Indicator (BIR 0-5), bar_index and bar_offset are set so
> > + callers can
> > + * use pci_iomap(pdev, bar_index, size) and base + bar_offset instead
> > + of
> > + * ioremap(resource).
> > */
> > struct cxl_register_map {
> > struct device *host;
> > @@ -144,6 +151,8 @@ struct cxl_register_map {
> > resource_size_t resource;
> > resource_size_t max_size;
> > u8 reg_type;
> > + u8 bar_index;
> > + resource_size_t bar_offset;
> > union {
> > struct cxl_component_reg_map component_map;
> > struct cxl_device_reg_map device_map; @@ -319,6 +328,8
> > @@ int cxl_get_hdm_reg_info(struct cxl_dev_state *cxlds, u32 *count,
> > resource_size_t *offset, resource_size_t
> > *size); struct pci_dev; enum cxl_regloc_type;
> > +int cxl_regblock_get_bar_info(const struct cxl_register_map *map, u8
> *bar_index,
> > + resource_size_t *bar_offset);
> > int cxl_find_regblock(struct pci_dev *pdev, enum cxl_regloc_type type,
> > struct cxl_register_map *map); void
> > cxl_probe_component_regs(struct device *dev, void __iomem *base,