[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v3 3/3] xen/pci: Refactor MSI code that implements MSI functionality within XEN
On Mon, Apr 26, 2021 at 05:21:27PM +0100, Rahul Singh wrote: > MSI code that implements MSI functionality to support MSI within XEN is > not usable on ARM. Move the code under CONFIG_PCI_MSI_INTERCEPT flag to > gate the code for ARM. > > Currently, we have no idea how MSI functionality will be supported for > other architecture therefore we have decided to move the code under > CONFIG_PCI_MSI_INTERCEPT. We know this is not the right flag to gate the > code but to avoid an extra flag we decided to use this. > > No functional change intended. > > Signed-off-by: Rahul Singh <rahul.singh@xxxxxxx> I think this is fine, as we don't really want to add another Kconfig option (ie: CONFIG_PCI_MSI) for just the non explicitly intercept MSI code. Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> Some nits below... > --- > Changes since v2: > - This patch is added in this version. > --- > xen/drivers/passthrough/msi-intercept.c | 41 +++++++++++++++++++++++++ > xen/drivers/passthrough/pci.c | 34 ++++---------------- > xen/include/xen/msi-intercept.h | 7 +++++ > xen/include/xen/pci.h | 11 ++++--- > 4 files changed, 61 insertions(+), 32 deletions(-) > > diff --git a/xen/drivers/passthrough/msi-intercept.c > b/xen/drivers/passthrough/msi-intercept.c > index 1edae6d4e8..33ab71514d 100644 > --- a/xen/drivers/passthrough/msi-intercept.c > +++ b/xen/drivers/passthrough/msi-intercept.c > @@ -19,6 +19,47 @@ > #include <asm/msi.h> > #include <asm/hvm/io.h> > > +int pdev_msi_init(struct pci_dev *pdev) > +{ > + unsigned int pos; > + > + INIT_LIST_HEAD(&pdev->msi_list); > + > + pos = pci_find_cap_offset(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn), PCI_CAP_ID_MSI); > + if ( pos ) > + { > + uint16_t ctrl = pci_conf_read16(pdev->sbdf, msi_control_reg(pos)); > + > + pdev->msi_maxvec = multi_msi_capable(ctrl); > + } > + > + pos = pci_find_cap_offset(pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), > + PCI_FUNC(pdev->devfn), PCI_CAP_ID_MSIX); > + if ( pos ) > + { > + struct arch_msix *msix = xzalloc(struct arch_msix); > + uint16_t ctrl; > + > + if ( !msix ) > + return -ENOMEM; > + > + spin_lock_init(&msix->table_lock); > + > + ctrl = pci_conf_read16(pdev->sbdf, msix_control_reg(pos)); > + msix->nr_entries = msix_table_size(ctrl); > + > + pdev->msix = msix; > + } > + > + return 0; > +} > + > +void pdev_msi_deinit(struct pci_dev *pdev) > +{ > + XFREE(pdev->msix); > +} > + > int pdev_msix_assign(struct domain *d, struct pci_dev *pdev) > { > int rc; > diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c > index 298be21b5b..b1e3c711ad 100644 > --- a/xen/drivers/passthrough/pci.c > +++ b/xen/drivers/passthrough/pci.c > @@ -314,6 +314,7 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, > u8 bus, u8 devfn) > { > struct pci_dev *pdev; > unsigned int pos; > + int rc; > > list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) > if ( pdev->bus == bus && pdev->devfn == devfn ) > @@ -327,35 +328,12 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, > u8 bus, u8 devfn) > *((u8*) &pdev->bus) = bus; > *((u8*) &pdev->devfn) = devfn; > pdev->domain = NULL; > - INIT_LIST_HEAD(&pdev->msi_list); > - > - pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), > PCI_FUNC(devfn), > - PCI_CAP_ID_MSI); > - if ( pos ) > - { > - uint16_t ctrl = pci_conf_read16(pdev->sbdf, msi_control_reg(pos)); > > - pdev->msi_maxvec = multi_msi_capable(ctrl); > - } > - > - pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), > PCI_FUNC(devfn), > - PCI_CAP_ID_MSIX); > - if ( pos ) > + rc = pdev_msi_init(pdev); > + if ( rc ) > { > - struct arch_msix *msix = xzalloc(struct arch_msix); > - uint16_t ctrl; > - > - if ( !msix ) > - { > - xfree(pdev); > - return NULL; > - } > - spin_lock_init(&msix->table_lock); > - > - ctrl = pci_conf_read16(pdev->sbdf, msix_control_reg(pos)); > - msix->nr_entries = msix_table_size(ctrl); > - > - pdev->msix = msix; > + XFREE(pdev); There's no need to use XFREE here, plain xfree is fine since pdev is a local variable so makes no sense to assign to NULL before returning. > + return NULL; > } > > list_add(&pdev->alldevs_list, &pseg->alldevs_list); > @@ -449,7 +427,7 @@ static void free_pdev(struct pci_seg *pseg, struct > pci_dev *pdev) > } > > list_del(&pdev->alldevs_list); > - xfree(pdev->msix); > + pdev_msi_deinit(pdev); > xfree(pdev); > } > > diff --git a/xen/include/xen/msi-intercept.h b/xen/include/xen/msi-intercept.h > index 77c105e286..38ff7a09e1 100644 > --- a/xen/include/xen/msi-intercept.h > +++ b/xen/include/xen/msi-intercept.h > @@ -21,16 +21,23 @@ > > #include <asm/msi.h> > > +int pdev_msi_init(struct pci_dev *pdev); > +void pdev_msi_deinit(struct pci_dev *pdev); > int pdev_msix_assign(struct domain *d, struct pci_dev *pdev); > void pdev_dump_msi(const struct pci_dev *pdev); > > #else /* !CONFIG_PCI_MSI_INTERCEPT */ > +static inline int pdev_msi_init(struct pci_dev *pdev) > +{ > + return 0; > +} > > static inline int pdev_msix_assign(struct domain *d, struct pci_dev *pdev) > { > return 0; > } > > +static inline void pdev_msi_deinit(struct pci_dev *pdev) {} > static inline void pdev_dump_msi(const struct pci_dev *pdev) {} > static inline void pci_cleanup_msi(struct pci_dev *pdev) {} > > diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h > index 8e3d4d9454..f5b57270be 100644 > --- a/xen/include/xen/pci.h > +++ b/xen/include/xen/pci.h > @@ -79,10 +79,6 @@ struct pci_dev { > struct list_head alldevs_list; > struct list_head domain_list; > > - struct list_head msi_list; > - > - struct arch_msix *msix; > - > struct domain *domain; > > const union { > @@ -94,7 +90,14 @@ struct pci_dev { > pci_sbdf_t sbdf; > }; > > +#ifdef CONFIG_PCI_MSI_INTERCEPT > + struct list_head msi_list; > + > + struct arch_msix *msix; > + > uint8_t msi_maxvec; > +#endif This seems to introduce some padding between the sbdf and the msi_list field. I guess that's better than having two different CONFIG_PCI_MSI_INTERCEPT guarded regions? Thanks, Roger.
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |