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