Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:Update
xen.12874
5d8b733b-x86-PCI-read-max-MSI-vector-count-earl...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5d8b733b-x86-PCI-read-max-MSI-vector-count-early.patch of Package xen.12874
References: bsc#1135799 # Commit 93a78101260b22510c5f823577ff826fbfc46136 # Date 2019-09-25 16:01:31 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/PCI: read maximum MSI vector count early Rather than doing this every time we set up interrupts for a device anew (and then in several places) fill this invariant field right after allocating struct pci_dev. Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Roger Pau Monné <roger.pau@citrix.com> Reviewed-by: Paul Durrant <paul.durrant@citrix.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -688,7 +688,7 @@ static int msi_capability_init(struct pc { struct msi_desc *entry; int pos; - unsigned int i, maxvec, mpos; + unsigned int i, mpos; u16 control, seg = dev->seg; u8 bus = dev->bus; u8 slot = PCI_SLOT(dev->devfn); @@ -699,9 +699,8 @@ static int msi_capability_init(struct pc if ( !pos ) return -ENODEV; control = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos)); - maxvec = multi_msi_capable(control); - if ( nvec > maxvec ) - return maxvec; + if ( nvec > dev->msi_maxvec ) + return dev->msi_maxvec; control &= ~PCI_MSI_FLAGS_QSIZE; multi_msi_enable(control, nvec); @@ -735,7 +734,7 @@ static int msi_capability_init(struct pc /* All MSIs are unmasked by default, Mask them all */ maskbits = pci_conf_read32(seg, bus, slot, func, mpos); - maskbits |= ~(u32)0 >> (32 - maxvec); + maskbits |= ~(uint32_t)0 >> (32 - dev->msi_maxvec); pci_conf_write32(seg, bus, slot, func, mpos, maskbits); } list_add_tail(&entry->list, &dev->msi_list); @@ -1309,7 +1308,6 @@ int pci_msi_conf_write_intercept(struct entry = find_msi_entry(pdev, -1, PCI_CAP_ID_MSI); if ( entry && entry->msi_attrib.maskbit ) { - uint16_t cntl; uint32_t unused; unsigned int nvec = entry->msi.nvec; @@ -1322,8 +1320,7 @@ int pci_msi_conf_write_intercept(struct if ( reg < entry->msi.mpos || reg >= entry->msi.mpos + 4 || size != 4 ) return -EACCES; - cntl = pci_conf_read16(seg, bus, slot, func, msi_control_reg(pos)); - unused = ~(uint32_t)0 >> (32 - multi_msi_capable(cntl)); + unused = ~(uint32_t)0 >> (32 - pdev->msi_maxvec); for ( pos = 0; pos < nvec; ++pos, ++entry ) { entry->msi_attrib.guest_masked = --- a/xen/drivers/passthrough/pci.c +++ b/xen/drivers/passthrough/pci.c @@ -347,6 +347,16 @@ static struct pci_dev *alloc_pdev(struct 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(pseg->nr, bus, PCI_SLOT(devfn), + PCI_FUNC(devfn), 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 ) { --- a/xen/drivers/vpci/msi.c +++ b/xen/drivers/vpci/msi.c @@ -27,7 +27,7 @@ static uint32_t control_read(const struc { const struct vpci_msi *msi = data; - return MASK_INSR(fls(msi->max_vectors) - 1, PCI_MSI_FLAGS_QMASK) | + return MASK_INSR(fls(pdev->msi_maxvec) - 1, PCI_MSI_FLAGS_QMASK) | MASK_INSR(fls(msi->vectors) - 1, PCI_MSI_FLAGS_QSIZE) | (msi->enabled ? PCI_MSI_FLAGS_ENABLE : 0) | (msi->masking ? PCI_MSI_FLAGS_MASKBIT : 0) | @@ -40,7 +40,7 @@ static void control_write(const struct p struct vpci_msi *msi = data; unsigned int vectors = min_t(uint8_t, 1u << MASK_EXTR(val, PCI_MSI_FLAGS_QSIZE), - msi->max_vectors); + pdev->msi_maxvec); bool new_enabled = val & PCI_MSI_FLAGS_ENABLE; /* @@ -218,8 +218,7 @@ static int init_msi(struct pci_dev *pdev * FIXME: I've only been able to test this code with devices using a single * MSI interrupt and no mask register. */ - pdev->vpci->msi->max_vectors = multi_msi_capable(control); - ASSERT(pdev->vpci->msi->max_vectors <= 32); + ASSERT(pdev->msi_maxvec <= 32); /* The multiple message enable is 0 after reset (1 message enabled). */ pdev->vpci->msi->vectors = 1; @@ -301,7 +300,7 @@ void vpci_dump_msi(void) if ( msi->masking ) printk(" mask=%08x", msi->mask); printk(" vectors max: %u enabled: %u\n", - msi->max_vectors, msi->vectors); + pdev->msi_maxvec, msi->vectors); vpci_msi_arch_print(msi); } --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -84,7 +84,8 @@ struct pci_dev { const u8 bus; const u8 devfn; - u8 phantom_stride; + uint8_t msi_maxvec; + uint8_t phantom_stride; nodeid_t node; /* NUMA node */ --- a/xen/include/xen/vpci.h +++ b/xen/include/xen/vpci.h @@ -99,14 +99,12 @@ struct vpci { uint32_t mask; /* Data. */ uint16_t data; - /* Maximum number of vectors supported by the device. */ - uint8_t max_vectors : 6; + /* Number of vectors configured. */ + uint8_t vectors : 6; /* Supports per-vector masking? */ bool masking : 1; /* 64-bit address capable? */ bool address64 : 1; - /* Number of vectors configured. */ - uint8_t vectors : 6; /* Enabled? */ bool enabled : 1; /* Arch-specific data. */
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