|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen master] vpci/msi: Implement cleanup function for MSI
commit fa475aa88c2610c38b74574d70646bb9f195f2af
Author: Jiqian Chen <Jiqian.Chen@xxxxxxx>
AuthorDate: Mon Dec 8 16:18:14 2025 +0800
Commit: Roger Pau Monne <roger.pau@xxxxxxxxxx>
CommitDate: Mon Feb 2 13:05:31 2026 +0100
vpci/msi: Implement cleanup function for MSI
When MSI initialization fails, vPCI hides the capability, but
removing handlers and datas won't be performed until the device is
deassigned. So, implement MSI cleanup hook that will be called to
cleanup MSI related handlers and free it's associated data when
initialization fails.
Since cleanup function of MSI is implemented, delete the open-code
in vpci_deassign_device().
Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
---
xen/drivers/vpci/msi.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-
xen/drivers/vpci/vpci.c | 1 -
2 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index c3eba4e148..737770ffa3 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -193,6 +193,66 @@ static void cf_check mask_write(
msi->mask = val;
}
+static int cf_check cleanup_msi(const struct pci_dev *pdev, bool hide)
+{
+ int rc;
+ unsigned int end;
+ struct vpci *vpci = pdev->vpci;
+ const unsigned int msi_pos = pdev->msi_pos;
+ const unsigned int ctrl = msi_control_reg(msi_pos);
+
+ if ( !hide )
+ {
+ XFREE(vpci->msi);
+ return 0;
+ }
+
+ if ( vpci->msi )
+ {
+ uint16_t control = pci_conf_read16(pdev->sbdf, ctrl);
+ bool address64 = is_64bit_address(control);
+
+ if ( is_mask_bit_support(control) )
+ end = msi_pending_bits_reg(msi_pos, address64);
+ else
+ /*
+ * "-2" here is to cut the reserved 2 bytes of Message Data when
+ * there is no masking support.
+ */
+ end = msi_mask_bits_reg(msi_pos, address64) - 2;
+
+ rc = vpci_remove_registers(vpci, ctrl, end - ctrl);
+ if ( rc )
+ {
+ printk(XENLOG_ERR "%pd %pp: fail to remove MSI handlers rc=%d\n",
+ pdev->domain, &pdev->sbdf, rc);
+ ASSERT_UNREACHABLE();
+ return rc;
+ }
+
+ XFREE(vpci->msi);
+ }
+
+ /*
+ * Unprivileged domains have a deny by default register access policy, no
+ * need to add any further handlers for them.
+ */
+ if ( !is_hardware_domain(pdev->domain) )
+ return 0;
+
+ /*
+ * The driver may not traverse the capability list and think device
+ * supports MSI by default. So here let the control register of MSI
+ * be Read-Only is to ensure MSI disabled.
+ */
+ rc = vpci_add_register(vpci, vpci_hw_read16, NULL, ctrl, 2, NULL);
+ if ( rc )
+ printk(XENLOG_ERR "%pd %pp: fail to add MSI ctrl handler rc=%d\n",
+ pdev->domain, &pdev->sbdf, rc);
+
+ return rc;
+}
+
static int cf_check init_msi(struct pci_dev *pdev)
{
unsigned int pos = pdev->msi_pos;
@@ -270,7 +330,7 @@ static int cf_check init_msi(struct pci_dev *pdev)
return 0;
}
-REGISTER_VPCI_CAP(MSI, init_msi, NULL);
+REGISTER_VPCI_CAP(MSI, init_msi, cleanup_msi);
void vpci_dump_msi(void)
{
diff --git a/xen/drivers/vpci/vpci.c b/xen/drivers/vpci/vpci.c
index d76b81e04b..063adbab9a 100644
--- a/xen/drivers/vpci/vpci.c
+++ b/xen/drivers/vpci/vpci.c
@@ -368,7 +368,6 @@ void vpci_deassign_device(struct pci_dev *pdev)
rangeset_destroy(pdev->vpci->header.bars[i].mem);
xfree(pdev->vpci->msix);
- xfree(pdev->vpci->msi);
xfree(pdev->vpci);
pdev->vpci = NULL;
}
--
generated by git-patchbot for /home/xen/git/xen.git#master
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |