Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:FrontRunner
xen.23271
5d80e857-x86-PCI-read-MSI-X-table-entry-count-e...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5d80e857-x86-PCI-read-MSI-X-table-entry-count-early.patch of Package xen.23271
References: bsc#1135799 # Commit 27ddc58d42a7848dbe60ba9f127ddd052906d487 # Date 2019-09-17 16:06:15 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/PCI: read MSI-X table entry count early Rather than doing this every time we set up interrupts for a device anew (and then in two distinct places) fill this invariant field right after allocating struct arch_msix. While at it also obtain the MSI-X capability structure position just once, in msix_capability_init(), rather than in each caller. Furthermore take the opportunity and eliminate the multi_msix_capable() alias of msix_table_size(). Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Acked-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -783,10 +783,8 @@ static u64 read_pci_mem_bar(u16 seg, u8 * requested MSI-X entries with allocated irqs or non-zero for otherwise. **/ static int msix_capability_init(struct pci_dev *dev, - unsigned int pos, struct msi_info *msi, - struct msi_desc **desc, - unsigned int nr_entries) + struct msi_desc **desc) { struct arch_msix *msix = dev->msix; struct msi_desc *entry = NULL; @@ -798,6 +796,11 @@ static int msix_capability_init(struct p u8 slot = PCI_SLOT(dev->devfn); u8 func = PCI_FUNC(dev->devfn); bool maskall = msix->host_maskall, zap_on_error = false; + unsigned int pos = pci_find_cap_offset(seg, bus, slot, func, + PCI_CAP_ID_MSIX); + + if ( !pos ) + return -ENODEV; ASSERT(pcidevs_locked()); @@ -875,10 +878,9 @@ static int msix_capability_init(struct p } table_paddr += table_offset & ~PCI_MSIX_BIRMASK; - msix->nr_entries = nr_entries; msix->table.first = PFN_DOWN(table_paddr); msix->table.last = PFN_DOWN(table_paddr + - nr_entries * PCI_MSIX_ENTRY_SIZE - 1); + msix->nr_entries * PCI_MSIX_ENTRY_SIZE - 1); WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->table.first, msix->table.last)); @@ -891,7 +893,7 @@ static int msix_capability_init(struct p msix->pba.first = PFN_DOWN(pba_paddr); msix->pba.last = PFN_DOWN(pba_paddr + - BITS_TO_LONGS(nr_entries) - 1); + BITS_TO_LONGS(msix->nr_entries) - 1); WARN_ON(rangeset_overlaps_range(mmio_ro_ranges, msix->pba.first, msix->pba.last)); @@ -983,7 +985,6 @@ static int msix_capability_init(struct p /* XXX How to deal with existing mappings? */ } } - WARN_ON(msix->nr_entries != nr_entries); WARN_ON(msix->table.first != (table_paddr >> PAGE_SHIFT)); ++msix->used_entries; @@ -1077,23 +1078,17 @@ static void __pci_disable_msi(struct msi **/ static int __pci_enable_msix(struct msi_info *msi, struct msi_desc **desc) { - int pos, nr_entries; struct pci_dev *pdev; - u16 control; u8 slot = PCI_SLOT(msi->devfn); u8 func = PCI_FUNC(msi->devfn); struct msi_desc *old_desc; ASSERT(pcidevs_locked()); pdev = pci_get_pdev(msi->seg, msi->bus, msi->devfn); - pos = pci_find_cap_offset(msi->seg, msi->bus, slot, func, PCI_CAP_ID_MSIX); - if ( !pdev || !pos ) + if ( !pdev || !pdev->msix ) return -ENODEV; - control = pci_conf_read16(msi->seg, msi->bus, slot, func, - msix_control_reg(pos)); - nr_entries = multi_msix_capable(control); - if ( msi->entry_nr >= nr_entries ) + if ( msi->entry_nr >= pdev->msix->nr_entries ) return -EINVAL; old_desc = find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX); @@ -1112,7 +1107,7 @@ static int __pci_enable_msix(struct msi_ __pci_disable_msi(old_desc); } - return msix_capability_init(pdev, pos, msi, desc, nr_entries); + return msix_capability_init(pdev, msi, desc); } static void _pci_cleanup_msix(struct arch_msix *msix) @@ -1177,16 +1172,10 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 { int rc; struct pci_dev *pdev; - u8 slot = PCI_SLOT(devfn), func = PCI_FUNC(devfn); - unsigned int pos = pci_find_cap_offset(seg, bus, slot, func, - PCI_CAP_ID_MSIX); if ( !use_msi ) return 0; - if ( !pos ) - return -ENODEV; - pcidevs_lock(); pdev = pci_get_pdev(seg, bus, devfn); if ( !pdev ) @@ -1199,13 +1188,7 @@ int pci_prepare_msix(u16 seg, u8 bus, u8 rc = 0; } else - { - u16 control = pci_conf_read16(seg, bus, slot, func, - msix_control_reg(pos)); - - rc = msix_capability_init(pdev, pos, NULL, NULL, - multi_msix_capable(control)); - } + rc = msix_capability_init(pdev, NULL, NULL); pcidevs_unlock(); return rc; --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -330,6 +330,7 @@ static void apply_quirks(struct pci_dev static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8 bus, u8 devfn) { struct pci_dev *pdev; + unsigned int pos; list_for_each_entry ( pdev, &pseg->alldevs_list, alldevs_list ) if ( pdev->bus == bus && pdev->devfn == devfn ) @@ -345,10 +346,12 @@ static struct pci_dev *alloc_pdev(struct 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) ) + pos = pci_find_cap_offset(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), + PCI_CAP_ID_MSIX); + if ( pos ) { struct arch_msix *msix = xzalloc(struct arch_msix); + uint16_t ctrl; if ( !msix ) { @@ -356,6 +359,11 @@ static struct pci_dev *alloc_pdev(struct return NULL; } spin_lock_init(&msix->table_lock); + + ctrl = pci_conf_read16(pseg->nr, bus, PCI_SLOT(devfn), PCI_FUNC(devfn), + msix_control_reg(pos)); + msix->nr_entries = msix_table_size(ctrl); + pdev->msix = msix; } @@ -364,7 +372,6 @@ static struct pci_dev *alloc_pdev(struct /* update bus2bridge */ switch ( pdev->type = pdev_type(pseg->nr, bus, devfn) ) { - int pos; unsigned int cap, sec_bus, sub_bus; case DEV_TYPE_PCIe2PCI_BRIDGE: --- a/xen/include/asm-x86/msi.h +++ b/xen/include/asm-x86/msi.h @@ -172,7 +172,6 @@ int msi_free_irq(struct msi_desc *entry) #define msix_enable(control) control |= PCI_MSIX_FLAGS_ENABLE #define msix_disable(control) control &= ~PCI_MSIX_FLAGS_ENABLE #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) -#define multi_msix_capable msix_table_size #define msix_unmask(address) (address & ~PCI_MSIX_VECTOR_BITMASK) #define msix_mask(address) (address | PCI_MSIX_VECTOR_BITMASK)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor