[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v5 09/10] vpci/msi: Free MSI resources when init_msi() fails
When init_msi() fails, current logic return fail and free MSI-related resources in vpci_deassign_device(). But the previous new changes will hide MSI capability and return success, it can't reach vpci_deassign_device() to remove resources if hiding success, so those resources must be removed in cleanup function of MSI. To do that, implement cleanup function for MSI. Signed-off-by: Jiqian Chen <Jiqian.Chen@xxxxxxx> --- cc: "Roger Pau Monné" <roger.pau@xxxxxxxxxx> --- v4->v5 changes: * Change definition "static void cleanup_msi" to "static int cf_check cleanup_msi" since cleanup hook is changed to be int. * Add a read-only register for MSI Control Register in the end of cleanup_msi. v3->v4 changes: * Change function name from fini_msi() to cleanup_msi(). * Remove unnecessary comment. * Change to use XFREE to free vpci->msi. 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 | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c index 2d45c7867de7..4e106c39efae 100644 --- a/xen/drivers/vpci/msi.c +++ b/xen/drivers/vpci/msi.c @@ -193,6 +193,33 @@ static void cf_check mask_write( msi->mask = val; } +static int cf_check cleanup_msi(struct pci_dev *pdev) +{ + int rc; + unsigned int end, size; + struct vpci *vpci = pdev->vpci; + const unsigned int msi_pos = pdev->msi_pos; + const unsigned int ctrl = msi_control_reg(msi_pos); + + if ( !msi_pos || !vpci->msi ) + return 0; + + 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 - ctrl; + + rc = vpci_remove_registers(vpci, ctrl, size); + if ( rc ) + return rc; + + XFREE(vpci->msi); + + return vpci_add_register(pdev->vpci, vpci_hw_read16, NULL, ctrl, 2, NULL); +} + static int cf_check init_msi(struct pci_dev *pdev) { unsigned int pos = pdev->msi_pos; @@ -270,7 +297,7 @@ static int cf_check init_msi(struct pci_dev *pdev) return 0; } -REGISTER_VPCI_CAP(PCI_CAP_ID_MSI, init_msi, NULL); +REGISTER_VPCI_CAP(PCI_CAP_ID_MSI, init_msi, cleanup_msi); void vpci_dump_msi(void) { -- 2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |