[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 1/2] vpci/msi: split code to bind pirq
And put it in a separate update function. This is required in order to improve binding of MSI PIRQs when using vPCI. No functional change. Signed-off-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- Cc: Jan Beulich <jbeulich@xxxxxxxx> Cc: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/hvm/vmsi.c | 73 +++++++++++++++++++++++++---------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 900d4f67d4..6e19851439 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -663,6 +663,42 @@ void vpci_msi_arch_mask(struct vpci_msi *msi, const struct pci_dev *pdev, vpci_mask_pirq(pdev->domain, msi->arch.pirq + entry, mask); } +static int vpci_msi_update(const struct pci_dev *pdev, uint32_t data, + uint64_t address, unsigned int vectors, + unsigned int pirq, uint32_t mask) +{ + unsigned int i; + + ASSERT(pcidevs_locked()); + + for ( i = 0; i < vectors; i++ ) + { + uint8_t vector = MASK_EXTR(data, MSI_DATA_VECTOR_MASK); + uint8_t vector_mask = 0xff >> (8 - fls(vectors) + 1); + struct xen_domctl_bind_pt_irq bind = { + .machine_irq = pirq + i, + .irq_type = PT_IRQ_TYPE_MSI, + .u.msi.gvec = (vector & ~vector_mask) | + ((vector + i) & vector_mask), + .u.msi.gflags = msi_gflags(data, address, (mask >> i) & 1), + }; + int rc = pt_irq_create_bind(pdev->domain, &bind); + + if ( rc ) + { + gdprintk(XENLOG_ERR, + "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n", + pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pirq + i, rc); + while ( bind.machine_irq-- ) + pt_irq_destroy_bind(pdev->domain, &bind); + return rc; + } + } + + return 0; +} + static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data, uint64_t address, unsigned int nr, paddr_t table_base, uint32_t mask) @@ -674,7 +710,7 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data, .table_base = table_base, .entry_nr = nr, }; - unsigned int i, vectors = table_base ? 1 : nr; + unsigned vectors = table_base ? 1 : nr; int rc, pirq = INVALID_PIRQ; /* Get a PIRQ. */ @@ -690,36 +726,17 @@ static int vpci_msi_enable(const struct pci_dev *pdev, uint32_t data, return rc; } - for ( i = 0; i < vectors; i++ ) + pcidevs_lock(); + rc = vpci_msi_update(pdev, data, address, vectors, pirq, mask); + if ( rc ) { - uint8_t vector = MASK_EXTR(data, MSI_DATA_VECTOR_MASK); - uint8_t vector_mask = 0xff >> (8 - fls(vectors) + 1); - struct xen_domctl_bind_pt_irq bind = { - .machine_irq = pirq + i, - .irq_type = PT_IRQ_TYPE_MSI, - .u.msi.gvec = (vector & ~vector_mask) | - ((vector + i) & vector_mask), - .u.msi.gflags = msi_gflags(data, address, (mask >> i) & 1), - }; - - pcidevs_lock(); - rc = pt_irq_create_bind(pdev->domain, &bind); - if ( rc ) - { - gdprintk(XENLOG_ERR, - "%04x:%02x:%02x.%u: failed to bind PIRQ %u: %d\n", - pdev->seg, pdev->bus, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pirq + i, rc); - while ( bind.machine_irq-- ) - pt_irq_destroy_bind(pdev->domain, &bind); - spin_lock(&pdev->domain->event_lock); - unmap_domain_pirq(pdev->domain, pirq); - spin_unlock(&pdev->domain->event_lock); - pcidevs_unlock(); - return rc; - } + spin_lock(&pdev->domain->event_lock); + unmap_domain_pirq(pdev->domain, pirq); + spin_unlock(&pdev->domain->event_lock); pcidevs_unlock(); + return rc; } + pcidevs_unlock(); return pirq; } -- 2.17.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |