|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 1/2] xen/x86: Patch re-factors MSI/X config code from, drivers/passthrough/pci.c to x86 specific
On Mon, 13 Apr 2015, Manish Jaggi wrote:
> This patch re-factors msi specific code to x86 specific files from
> xen/drivers/passthrough/pci.c.
>
> Signed-off-by: Manish Jaggi <manish.jaggi@xxxxxxxxxxxxxxxxxx>
> ---
> xen/drivers/passthrough/pci.c | 102 +-----------------------------
> xen/drivers/passthrough/x86/Makefile | 1 +
> xen/drivers/passthrough/x86/pci.c | 115
> ++++++++++++++++++++++++++++++++++
> xen/include/asm-x86/msi.h | 1 -
> xen/include/xen/pci.h | 20 +++++-
> 5 files changed, 137 insertions(+), 102 deletions(-)
>
> diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
> index ecd061e..004aba9 100644
> --- a/xen/drivers/passthrough/pci.c
> +++ b/xen/drivers/passthrough/pci.c
> @@ -23,7 +23,6 @@
> #include <xen/iommu.h>
> #include <xen/irq.h>
> #include <asm/hvm/iommu.h>
> -#include <asm/hvm/irq.h>
> #include <xen/delay.h>
> #include <xen/keyhandler.h>
> #include <xen/event.h>
> @@ -33,21 +32,6 @@
> #include <xen/softirq.h>
> #include <xen/tasklet.h>
> #include <xsm/xsm.h>
> -#include <asm/msi.h>
> -
> -struct pci_seg {
> - struct list_head alldevs_list;
> - u16 nr;
> - unsigned long *ro_map;
> - /* bus2bridge_lock protects bus2bridge array */
> - spinlock_t bus2bridge_lock;
> -#define MAX_BUSES 256
> - struct {
> - u8 map;
> - u8 bus;
> - u8 devfn;
> - } bus2bridge[MAX_BUSES];
> -};
> spinlock_t pcidevs_lock = SPIN_LOCK_UNLOCKED;
> static struct radix_tree_root pci_segments;
> @@ -282,22 +266,10 @@ 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);
> -
> - if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
> PCI_FUNC(devfn),
> - PCI_CAP_ID_MSIX) )
> + if (!pci_alloc_msix (pdev, pseg, bus, devfn))
> {
> - struct arch_msix *msix = xzalloc(struct arch_msix);
> -
> - if ( !msix )
> - {
> - xfree(pdev);
> - return NULL;
> - }
> - spin_lock_init(&msix->table_lock);
> - pdev->msix = msix;
> + return NULL;
> }
> -
From the look of it, this code doesn't seem x86 specific
> list_add(&pdev->alldevs_list, &pseg->alldevs_list);
> /* update bus2bridge */
> @@ -755,54 +727,6 @@ int pci_remove_device(u16 seg, u8 bus, u8 devfn)
> return ret;
> }
> -static int pci_clean_dpci_irq(struct domain *d,
> - struct hvm_pirq_dpci *pirq_dpci, void *arg)
> -{
> - struct dev_intx_gsi_link *digl, *tmp;
> -
> - pirq_guest_unbind(d, dpci_pirq(pirq_dpci));
> -
> - if ( pt_irq_need_timer(pirq_dpci->flags) )
> - kill_timer(&pirq_dpci->timer);
> -
> - list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list )
> - {
> - list_del(&digl->list);
> - xfree(digl);
> - }
> -
> - return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0;
> -}
> -
> -static int pci_clean_dpci_irqs(struct domain *d)
> -{
> - struct hvm_irq_dpci *hvm_irq_dpci = NULL;
> -
> - if ( !iommu_enabled )
> - return 0;
> -
> - if ( !is_hvm_domain(d) )
> - return 0;
> -
> - spin_lock(&d->event_lock);
> - hvm_irq_dpci = domain_get_irq_dpci(d);
> - if ( hvm_irq_dpci != NULL )
> - {
> - int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
> -
> - if ( ret )
> - {
> - spin_unlock(&d->event_lock);
> - return ret;
> - }
> -
> - d->arch.hvm_domain.irq.dpci = NULL;
> - free_hvm_irq_dpci(hvm_irq_dpci);
> - }
> - spin_unlock(&d->event_lock);
> - return 0;
> -}
..but these two functions do
> int pci_release_devices(struct domain *d)
> {
> struct pci_dev *pdev;
> @@ -1186,28 +1110,6 @@ bool_t pcie_aer_get_firmware_first(const struct
> pci_dev *pdev)
> }
> #endif
> -static int _dump_pci_devices(struct pci_seg *pseg, void *arg)
> -{
> - struct pci_dev *pdev;
> - struct msi_desc *msi;
> -
> - printk("==== segment %04x ====\n", pseg->nr);
> -
> - list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
> - {
> - printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
> - pseg->nr, pdev->bus,
> - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
> - pdev->domain ? pdev->domain->domain_id : -1,
> - (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
> - list_for_each_entry ( msi, &pdev->msi_list, list )
> - printk("%d ", msi->irq);
> - printk(">\n");
> - }
> -
> - return 0;
> -}
> -
> static void dump_pci_devices(unsigned char ch)
> {
> printk("==== PCI devices ====\n");
> diff --git a/xen/drivers/passthrough/x86/Makefile
> b/xen/drivers/passthrough/x86/Makefile
> index a70cf94..a2bcf94 100644
> --- a/xen/drivers/passthrough/x86/Makefile
> +++ b/xen/drivers/passthrough/x86/Makefile
> @@ -1,2 +1,3 @@
> obj-y += ats.o
> obj-y += iommu.o
> +obj-$(HAS_PCI) += pci.o
> diff --git a/xen/drivers/passthrough/x86/pci.c
> b/xen/drivers/passthrough/x86/pci.c
> new file mode 100644
> index 0000000..cf37b0a
> --- /dev/null
> +++ b/xen/drivers/passthrough/x86/pci.c
> @@ -0,0 +1,115 @@
> +/*
> + * x86 specific code for PCI MSI
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
> USA.
> + *
> + * Copyright (C) 2015 Cavium Networks
> + *
> + * Author: Manish Jaggi <manish.jaggi@xxxxxxxxxx>
> + */
> +#include <xen/pci.h>
> +#include <xen/sched.h>
> +#include <asm/hvm/irq.h>
> +#include <asm/msi.h>
> +
> +int _dump_pci_devices(struct pci_seg *pseg, void *arg)
> +{
> + struct pci_dev *pdev;
> + struct msi_desc *msi;
> +
> + printk("==== segment %04x ====\n", pseg->nr);
> +
> + list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list )
> + {
> + printk("%04x:%02x:%02x.%u - dom %-3d - node %-3d - MSIs < ",
> + pseg->nr, pdev->bus,
> + PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
> + pdev->domain ? pdev->domain->domain_id : -1,
> + (pdev->node != NUMA_NO_NODE) ? pdev->node : -1);
> + list_for_each_entry ( msi, &pdev->msi_list, list )
> + printk("%d ", msi->irq);
> + printk(">\n");
> + }
> +
> + return 0;
> +}
> +
> +int pci_clean_dpci_irq(struct domain *d,
> + struct hvm_pirq_dpci *pirq_dpci, void *arg)
> +{
> + struct dev_intx_gsi_link *digl, *tmp;
> +
> + pirq_guest_unbind(d, dpci_pirq(pirq_dpci));
> +
> + if ( pt_irq_need_timer(pirq_dpci->flags) )
> + kill_timer(&pirq_dpci->timer);
> +
> + list_for_each_entry_safe ( digl, tmp, &pirq_dpci->digl_list, list )
> + {
> + list_del(&digl->list);
> + xfree(digl);
> + }
> +
> + return pt_pirq_softirq_active(pirq_dpci) ? -ERESTART : 0;
> +}
> +
> +int pci_clean_dpci_irqs(struct domain *d)
> +{
> + struct hvm_irq_dpci *hvm_irq_dpci = NULL;
> +
> + if ( !iommu_enabled )
> + return 0;
> +
> + if ( !is_hvm_domain(d) )
> + return 0;
> +
> + spin_lock(&d->event_lock);
> + hvm_irq_dpci = domain_get_irq_dpci(d);
> + if ( hvm_irq_dpci != NULL )
> + {
> + int ret = pt_pirq_iterate(d, pci_clean_dpci_irq, NULL);
> +
> + if ( ret )
> + {
> + spin_unlock(&d->event_lock);
> + return ret;
> + }
> +
> + d->arch.hvm_domain.irq.dpci = NULL;
> + free_hvm_irq_dpci(hvm_irq_dpci);
> + }
> + spin_unlock(&d->event_lock);
> + return 0;
> +}
> +
> +struct pci_dev* pci_alloc_msix(struct pci_dev *pdev, struct pci_seg *pseg,
> u8 bus, u8 devfn)
> +{
> + INIT_LIST_HEAD(&pdev->msi_list);
> +
> + if ( pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn),
> PCI_FUNC(devfn),
> + PCI_CAP_ID_MSIX) )
> + {
> + struct arch_msix *msix = xzalloc(struct arch_msix);
> +
> + if ( !msix )
> + {
> + xfree(pdev);
> + return NULL;
> + }
> + spin_lock_init(&msix->table_lock);
> + pdev->msix = msix;
> + }
> +
> + return pdev;
> +}
> diff --git a/xen/include/asm-x86/msi.h b/xen/include/asm-x86/msi.h
> index 4c62a3a..9b2b4a3 100644
> --- a/xen/include/asm-x86/msi.h
> +++ b/xen/include/asm-x86/msi.h
> @@ -78,7 +78,6 @@ struct msi_desc;
> extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
> extern void pci_disable_msi(struct msi_desc *desc);
> extern int pci_prepare_msix(u16 seg, u8 bus, u8 devfn, bool_t off);
> -extern void pci_cleanup_msi(struct pci_dev *pdev);
> extern int setup_msi_irq(struct irq_desc *, struct msi_desc *);
> extern int __setup_msi_irq(struct irq_desc *, struct msi_desc *,
> const struct hw_interrupt_type *);
> diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
> index 4377f3e..07e60fe 100644
> --- a/xen/include/xen/pci.h
> +++ b/xen/include/xen/pci.h
> @@ -43,6 +43,20 @@ struct pci_dev_info {
> } physfn;
> };
> +struct pci_seg {
> + struct list_head alldevs_list;
> + u16 nr;
> + unsigned long *ro_map;
> + /* bus2bridge_lock protects bus2bridge array */
> + spinlock_t bus2bridge_lock;
> +#define MAX_BUSES 256
> + struct {
> + u8 map;
> + u8 bus;
> + u8 devfn;
> + } bus2bridge[MAX_BUSES];
> +};
> +
> struct pci_dev {
> struct list_head alldevs_list;
> struct list_head domain_list;
> @@ -155,5 +169,9 @@ struct pirq;
> int msixtbl_pt_register(struct domain *, struct pirq *, uint64_t gtable);
> void msixtbl_pt_unregister(struct domain *, struct pirq *);
> void msixtbl_pt_cleanup(struct domain *d);
> -
> +struct pci_dev* pci_alloc_msix(struct pci_dev *pdev, struct pci_seg *pseg,
> + u8 bus, u8 devfn);
> +int pci_clean_dpci_irqs(struct domain *d);
> +void pci_cleanup_msi(struct pci_dev *pdev);
> +int _dump_pci_devices(struct pci_seg *pseg, void *arg);
> #endif /* __XEN_PCI_H__ */
> --
> 1.7.9.5
>
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |