> -----Original Message-----
> From: Alex Williamson <[email protected]>
> Sent: Tuesday, September 22, 2026 7:43 AM
> To: Manish Honap <[email protected]>
> Cc: [email protected]; Ankit Agrawal <[email protected]>; [email protected];
> [email protected]; [email protected]; Srirangan
> Madhavan <[email protected]>; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; Yishai
> Hadas <[email protected]>; Shameer Kolothum Thodi
> <[email protected]>; [email protected]; [email protected];
> [email protected]; [email protected]; [email protected]; Neo Jia
> <[email protected]>; Krishnakant Jaju <[email protected]>; Vikram Sethi
> <[email protected]>; Zhi Wang <[email protected]>; linux-
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected]; linux-
> [email protected]; [email protected]; [email protected]
> Subject: Re: [PATCH v5 22/27] vfio/cxl: Clear the HDM access gate after a hot
> reset
> 
> External email: Use caution opening links or attachments
> 
> 
> On Thu, 17 Sep 2026 00:05:35 +0530
> <[email protected]> wrote:
> 
> > From: Manish Honap <[email protected]>
> >
> > The HDM memory fault inserts a PFN only when the decoder is in a
> > known-good state (cxl->hdm_valid), so the host CPU never faults the
> > coherent range into a disabled decoder.
> >
> > VFIO_DEVICE_PCI_HOT_RESET drives a plain secondary bus reset rather
> > than the CXL reset sequence, so nothing restores the decoder in the
> > reset_done handler. A secondary bus reset only reaches a CXL endpoint
> > when the upstream port has SBR unmasked (CXL r3.1 sec 8.1.5.2); in
> > that case the reset decommits the decoder, so clear cxl->hdm_valid to
> > keep a later fault from inserting a PFN into a dead decoder.
> >
> > A subsequent VFIO_DEVICE_RESET runs the CXL reset sequence and
> > restores it, and a masked SBR is a no-op that leaves the decoder intact.
> >
> > vfio_cxl_sbr_unmasked() mirrors the cxl_sbr_masked() check the PCI
> > core uses (drivers/pci/pci.c) for its own CXL bus reset.
> 
> This all sounds very broken.  If a hot reset is masked, it should fail, not 
> silently
> do nothing.  If a hot reset is unmasked, we can't just invent that the user
> needs to follow it with a reset ioctl, and the decoder is dead for the 
> remainder
> of their session otherwise.
> 
> So on one hand, we have a reset we can't use because it doesn't do anything,
> and on the other we have a reset that we can't use because in doing
> something it makes the device effectively unrecoverable, without some
> assumption to perform a reset ioctl.
> 
> Are bus resets just not supported on CXL devices through vfio-pci?
> Thanks,

I will try to handle both these cases in v6 correctly:

1. Masked
with Unmask SBR clear in the port's CXL DVSEC, the SBR does nothing to the
device (CXL r3.1 sec 8.1.5.2). The PCI core already refuses 
pci_reset_bus_function()
in that case. I will add the same check to the bus and slot reset paths and 
their probes, so
VFIO_DEVICE_GET_PCI_HOT_RESET_INFO and VFIO_DEVICE_PCI_HOT_RESET fail for the
device instead of doing nothing. A VMM will then use VFIO_DEVICE_RESET, which 
runs the
CXL reset. I will add the PCI core change in its own patch.

2. Unmasked
The reset clears the decoder, so vfio-cxl's reset_done restores it with the 
same cxl-core
helper the PCI core's cxl_bus reset method calls after its SBR, and reopens the 
HDM gate. If the
restore fails, the hot reset ioctl returns the error. No follow-up  
VFIO_DEVICE_RESET is needed.

> 
> Alex
> 
> 
> > Assisted-by: LLM
> > Signed-off-by: Manish Honap <[email protected]>
> > ---
> >  drivers/vfio/pci/cxl/vfio_cxl_core.c | 38
> > ++++++++++++++++++++++++++++
> >  1 file changed, 38 insertions(+)
> >
> > diff --git a/drivers/vfio/pci/cxl/vfio_cxl_core.c
> > b/drivers/vfio/pci/cxl/vfio_cxl_core.c
> > index 37e8a3b54cfb..395b4a5b0956 100644
> > --- a/drivers/vfio/pci/cxl/vfio_cxl_core.c
> > +++ b/drivers/vfio/pci/cxl/vfio_cxl_core.c
> > @@ -514,8 +514,46 @@ static void vfio_cxl_reset_prepare(struct
> > vfio_pci_core_device *vdev)  {  }
> >
> > +/*
> > + * A secondary bus reset only reaches a CXL endpoint when the
> > +upstream port
> > + * has SBR unmasked (CXL r3.1 sec 8.1.5.2); otherwise the Bridge
> > +Control SBR
> > + * bit is ignored and the decoder is left intact. Mirrors the
> > +cxl_sbr_masked()
> > + * check the PCI core uses for its own CXL bus reset.
> > + */
> > +static bool vfio_cxl_sbr_unmasked(struct pci_dev *pdev) {
> > +     struct pci_dev *bridge = pci_upstream_bridge(pdev);
> > +     u16 dvsec, ctl;
> > +
> > +     if (!bridge)
> > +             return false;
> > +
> > +     dvsec = pci_find_dvsec_capability(bridge, PCI_VENDOR_ID_CXL,
> > +                                       PCI_DVSEC_CXL_PORT);
> > +     if (!dvsec)
> > +             return false;
> > +
> > +     if (pci_read_config_word(bridge, dvsec + PCI_DVSEC_CXL_PORT_CTL,
> &ctl))
> > +             return false;
> > +
> > +     return ctl & PCI_DVSEC_CXL_PORT_CTL_UNMASK_SBR;
> > +}
> > +
> >  static void vfio_cxl_reset_done(struct vfio_pci_core_device *vdev)  {
> > +     struct vfio_cxl_state *cxl = vdev->cxl;
> > +
> > +     /*
> > +      * VFIO_DEVICE_PCI_HOT_RESET drives a plain secondary bus reset, not
> the
> > +      * CXL-aware cxl_reset_bus_function(), so nothing restores the HDM
> > +      * decoder here. When the upstream port has SBR unmasked the reset
> > +      * decommits the decoder; gate host access to the HDM range so a later
> > +      * fault cannot insert a PFN into a dead decoder. A VFIO_DEVICE_RESET
> > +      * then runs the CXL reset sequence and restores it. A masked SBR is a
> > +      * no-op and leaves the decoder intact.
> > +      */
> > +     if (vfio_cxl_sbr_unmasked(vdev->pdev))
> > +             cxl->hdm_valid = false;
> >  }
> >
> >  static const struct vfio_cxl_ops vfio_cxl_ops = {


Reply via email to