[PATCH v5 4/5] vPCI/ReBAR: improve cleanup

Jan Beulich posted 5 patches 4 months, 2 weeks ago
[PATCH v5 4/5] vPCI/ReBAR: improve cleanup
Posted by Jan Beulich 4 months, 2 weeks ago
We cannot assume extended config space to (still) be accessible when
cleaning up. Necessary value need caching instead. In fact, as the caller
also cannot look up extended capabilities, the cleanup function needs to
cope with being called when there's no ReBAR capability at all.

As kind of a side effect nbars being 0 (which init_rebar() doesn't
explicitly reject) no longer results in a bogus call to
vpci_remove_registers().

Fixes: ee459aeac096 ("vpci/rebar: Implement cleanup function for Rebar")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v5: New.

--- a/xen/drivers/vpci/rebar.c
+++ b/xen/drivers/vpci/rebar.c
@@ -53,17 +53,12 @@ static void cf_check rebar_ctrl_write(co
 static int cf_check cleanup_rebar(const struct pci_dev *pdev, bool hide)
 {
     int rc;
-    uint32_t ctrl;
-    unsigned int nbars;
-    unsigned int rebar_offset = pci_find_ext_capability(pdev,
-                                                        PCI_EXT_CAP_ID_REBAR);
+    unsigned int nbars = pdev->vpci->rebar.nbars;
+    unsigned int rebar_offset = pdev->vpci->rebar.offset;
 
-    if ( !hide )
+    if ( !rebar_offset || !nbars || !hide )
         return 0;
 
-    ctrl = pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL(0));
-    nbars = MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK);
-
     rc = vpci_remove_registers(pdev->vpci, rebar_offset + PCI_REBAR_CAP(0),
                                PCI_REBAR_CTRL(nbars - 1));
     if ( rc )
@@ -121,6 +116,10 @@ static int cf_check init_rebar(struct pc
 
     ctrl = pci_conf_read32(pdev->sbdf, rebar_offset + PCI_REBAR_CTRL(0));
     nbars = MASK_EXTR(ctrl, PCI_REBAR_CTRL_NBAR_MASK);
+
+    pdev->vpci->rebar.offset = rebar_offset;
+    pdev->vpci->rebar.nbars  = nbars;
+
     for ( unsigned int i = 0; i < nbars; i++ )
     {
         int rc;
--- a/xen/include/xen/vpci.h
+++ b/xen/include/xen/vpci.h
@@ -135,6 +135,13 @@ struct vpci {
             struct vpci_arch_msix_entry arch;
         } entries[];
     } *msix;
+
+    /* Resizable BARs data */
+    struct vpci_rebar {
+        unsigned int offset:12;
+        unsigned int nbars:3;
+    } rebar;
+
 #ifdef CONFIG_HAS_VPCI_GUEST_SUPPORT
     /* Guest SBDF of the device. */
 #define INVALID_GUEST_SBDF ((pci_sbdf_t){ .sbdf = ~0U })
Re: [PATCH v5 4/5] vPCI/ReBAR: improve cleanup
Posted by Roger Pau Monné 4 months, 1 week ago
On Wed, Feb 25, 2026 at 12:44:22PM +0100, Jan Beulich wrote:
> We cannot assume extended config space to (still) be accessible when
> cleaning up. Necessary value need caching instead. In fact, as the caller
> also cannot look up extended capabilities, the cleanup function needs to
> cope with being called when there's no ReBAR capability at all.

I see that you adjust the code in vpci_cleanup_capabilities() in the
next patch, so that it also doesn't check for extended capability
presence as part of cleanup.

> As kind of a side effect nbars being 0 (which init_rebar() doesn't
> explicitly reject) no longer results in a bogus call to
> vpci_remove_registers().
> 
> Fixes: ee459aeac096 ("vpci/rebar: Implement cleanup function for Rebar")
> Signed-off-by: Jan Beulich <jbeulich@suse.com>

Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Thanks, Roger.