[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 |