|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 10/11] vpci/msi: Free MSI resources when init_msi() fails
When init_msi() fails, the previous new changes will hide MSI
capability, it can't rely on vpci_deassign_device() to remove
all MSI related resources anymore, those resources must be
cleaned up in failure path of init_msi.
To do that, add a new function to free MSI resources.
Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx>
---
cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx>
---
v2->v3 changes:
* Remove all fail path, and use fini_msi() hook instead.
* Change the method to calculating the size of msi registers.
v1->v2 changes:
* Added a new function fini_msi to free all MSI resources instead of using an
array to record registered registers.
Best regards,
Jiqian Chen.
---
xen/drivers/vpci/msi.c | 28 +++++++++++++++++++++++++++-
1 file changed, 27 insertions(+), 1 deletion(-)
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index ea7dc0c060ea..18b06b789827 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -193,6 +193,32 @@ static void cf_check mask_write(
msi->mask = val;
}
+static void fini_msi(struct pci_dev *pdev)
+{
+ unsigned int end, size;
+ struct vpci *vpci = pdev->vpci;
+ const unsigned int msi_pos = pdev->msi_pos;
+
+ if ( !msi_pos || !vpci->msi )
+ return;
+
+ if ( vpci->msi->masking )
+ end = msi_pending_bits_reg(msi_pos, vpci->msi->address64);
+ else
+ end = msi_mask_bits_reg(msi_pos, vpci->msi->address64) - 2;
+
+ size = end - msi_control_reg(msi_pos);
+
+ /*
+ * Remove all possible registered registers except capability ID
+ * register if guest and next capability pointer register, which
+ * will be removed in mask function.
+ */
+ vpci_remove_registers(vpci, msi_control_reg(msi_pos), size);
+ xfree(vpci->msi);
+ vpci->msi = NULL;
+}
+
static int cf_check init_msi(struct pci_dev *pdev)
{
unsigned int pos = pdev->msi_pos;
@@ -270,7 +296,7 @@ static int cf_check init_msi(struct pci_dev *pdev)
return 0;
}
-REGISTER_VPCI_LEGACY_CAP(PCI_CAP_ID_MSI, init_msi, NULL);
+REGISTER_VPCI_LEGACY_CAP(PCI_CAP_ID_MSI, init_msi, fini_msi);
void vpci_dump_msi(void)
{
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |