|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen staging] x86/PCI: read maximum MSI vector count early
commit 93a78101260b22510c5f823577ff826fbfc46136
Author: Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Sep 25 16:01:31 2019 +0200
Commit: Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Sep 25 16:01:31 2019 +0200
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@xxxxxxxx>
Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx>
Reviewed-by: Paul Durrant <paul.durrant@xxxxxxxxxx>
Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
xen/arch/x86/msi.c | 13 +++++--------
xen/drivers/passthrough/pci.c | 9 +++++++++
xen/drivers/vpci/msi.c | 9 ++++-----
xen/include/xen/pci.h | 3 ++-
xen/include/xen/vpci.h | 6 ++----
5 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/xen/arch/x86/msi.c b/xen/arch/x86/msi.c
index 5297059936..76d4034c4f 100644
--- a/xen/arch/x86/msi.c
+++ b/xen/arch/x86/msi.c
@@ -664,7 +664,7 @@ static int msi_capability_init(struct pci_dev *dev,
{
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);
@@ -675,9 +675,8 @@ static int msi_capability_init(struct pci_dev *dev,
if ( !pos )
return -ENODEV;
control = pci_conf_read16(dev->sbdf, 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);
@@ -711,7 +710,7 @@ static int msi_capability_init(struct pci_dev *dev,
/* All MSIs are unmasked by default, Mask them all */
maskbits = pci_conf_read32(dev->sbdf, mpos);
- maskbits |= ~(u32)0 >> (32 - maxvec);
+ maskbits |= ~(uint32_t)0 >> (32 - dev->msi_maxvec);
pci_conf_write32(dev->sbdf, mpos, maskbits);
}
list_add_tail(&entry->list, &dev->msi_list);
@@ -1284,7 +1283,6 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev,
unsigned int reg,
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;
@@ -1297,8 +1295,7 @@ int pci_msi_conf_write_intercept(struct pci_dev *pdev,
unsigned int reg,
if ( reg < entry->msi.mpos || reg >= entry->msi.mpos + 4 || size != 4 )
return -EACCES;
- cntl = pci_conf_read16(pdev->sbdf, 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 =
diff --git a/xen/drivers/passthrough/pci.c b/xen/drivers/passthrough/pci.c
index d28f17af75..b3c4c9166a 100644
--- a/xen/drivers/passthrough/pci.c
+++ b/xen/drivers/passthrough/pci.c
@@ -341,6 +341,15 @@ static struct pci_dev *alloc_pdev(struct pci_seg *pseg, u8
bus, u8 devfn)
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(pdev->sbdf, 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 )
{
diff --git a/xen/drivers/vpci/msi.c b/xen/drivers/vpci/msi.c
index 5b6602f3c2..75010762ed 100644
--- a/xen/drivers/vpci/msi.c
+++ b/xen/drivers/vpci/msi.c
@@ -27,7 +27,7 @@ static uint32_t control_read(const struct pci_dev *pdev,
unsigned int reg,
{
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 pci_dev *pdev,
unsigned int reg,
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;
/*
@@ -215,8 +215,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;
@@ -298,7 +297,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);
}
diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h
index 8148f5b2e7..393cb45de3 100644
--- a/xen/include/xen/pci.h
+++ b/xen/include/xen/pci.h
@@ -94,7 +94,8 @@ struct pci_dev {
pci_sbdf_t sbdf;
};
- u8 phantom_stride;
+ uint8_t msi_maxvec;
+ uint8_t phantom_stride;
nodeid_t node; /* NUMA node */
diff --git a/xen/include/xen/vpci.h b/xen/include/xen/vpci.h
index 4cf233c779..5295d4c990 100644
--- 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. */
--
generated by git-patchbot for /home/xen/git/xen.git#staging
_______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |