Message ID | 1398693585-15928-1-git-send-email-mst@redhat.com |
---|---|
State | New |
Headers | show |
On Mon, 2014-04-28 at 17:02 +0300, Michael S. Tsirkin wrote: > KVM only supports MSIX table size up to 256 vectors, > but some assigned devices support more vectors, > at the moment attempts to assign them fail with EINVAL. > > Tweak the MSIX capability exposed to guest to limit table size > to a supported value. > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com> > Tested-by: Gonglei <arei.gonglei@huawei.com> > --- > hw/i386/kvm/pci-assign.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) Acked-by: Alex Williamson <alex.williamson@redhat.com> > diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c > index a825871..76aa86e 100644 > --- a/hw/i386/kvm/pci-assign.c > +++ b/hw/i386/kvm/pci-assign.c > @@ -1258,6 +1258,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > if (pos != 0 && kvm_device_msix_supported(kvm_state)) { > int bar_nr; > uint32_t msix_table_entry; > + uint16_t msix_max; > > if (!check_irqchip_in_kernel()) { > return -ENOTSUP; > @@ -1269,9 +1270,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > } > pci_dev->msix_cap = pos; > > - pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, > - pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & > - PCI_MSIX_FLAGS_QSIZE); > + msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & > + PCI_MSIX_FLAGS_QSIZE) + 1; > + msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV); > + pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1); > > /* Only enable and function mask bits are writable */ > pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS, > @@ -1281,9 +1283,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; > msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; > dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry; > - dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS); > - dev->msix_max &= PCI_MSIX_FLAGS_QSIZE; > - dev->msix_max += 1; > + dev->msix_max = msix_max; > } > > /* Minimal PM support, nothing writable, device appears to NAK changes */
Il 28/04/2014 16:02, Michael S. Tsirkin ha scritto: > KVM only supports MSIX table size up to 256 vectors, > but some assigned devices support more vectors, > at the moment attempts to assign them fail with EINVAL. > > Tweak the MSIX capability exposed to guest to limit table size > to a supported value. > > Signed-off-by: Michael S. Tsirkin <mst@redhat.com> > Tested-by: Gonglei <arei.gonglei@huawei.com> > --- > hw/i386/kvm/pci-assign.c | 12 ++++++------ > 1 file changed, 6 insertions(+), 6 deletions(-) > > diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c > index a825871..76aa86e 100644 > --- a/hw/i386/kvm/pci-assign.c > +++ b/hw/i386/kvm/pci-assign.c > @@ -1258,6 +1258,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > if (pos != 0 && kvm_device_msix_supported(kvm_state)) { > int bar_nr; > uint32_t msix_table_entry; > + uint16_t msix_max; > > if (!check_irqchip_in_kernel()) { > return -ENOTSUP; > @@ -1269,9 +1270,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > } > pci_dev->msix_cap = pos; > > - pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, > - pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & > - PCI_MSIX_FLAGS_QSIZE); > + msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & > + PCI_MSIX_FLAGS_QSIZE) + 1; > + msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV); > + pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1); > > /* Only enable and function mask bits are writable */ > pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS, > @@ -1281,9 +1283,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) > bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; > msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; > dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry; > - dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS); > - dev->msix_max &= PCI_MSIX_FLAGS_QSIZE; > - dev->msix_max += 1; > + dev->msix_max = msix_max; > } > > /* Minimal PM support, nothing writable, device appears to NAK changes */ > Applying to uq/master, thanks. Paolo
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c index a825871..76aa86e 100644 --- a/hw/i386/kvm/pci-assign.c +++ b/hw/i386/kvm/pci-assign.c @@ -1258,6 +1258,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) if (pos != 0 && kvm_device_msix_supported(kvm_state)) { int bar_nr; uint32_t msix_table_entry; + uint16_t msix_max; if (!check_irqchip_in_kernel()) { return -ENOTSUP; @@ -1269,9 +1270,10 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) } pci_dev->msix_cap = pos; - pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, - pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & - PCI_MSIX_FLAGS_QSIZE); + msix_max = (pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS) & + PCI_MSIX_FLAGS_QSIZE) + 1; + msix_max = MIN(msix_max, KVM_MAX_MSIX_PER_DEV); + pci_set_word(pci_dev->config + pos + PCI_MSIX_FLAGS, msix_max - 1); /* Only enable and function mask bits are writable */ pci_set_word(pci_dev->wmask + pos + PCI_MSIX_FLAGS, @@ -1281,9 +1283,7 @@ static int assigned_device_pci_cap_init(PCIDevice *pci_dev) bar_nr = msix_table_entry & PCI_MSIX_FLAGS_BIRMASK; msix_table_entry &= ~PCI_MSIX_FLAGS_BIRMASK; dev->msix_table_addr = pci_region[bar_nr].base_addr + msix_table_entry; - dev->msix_max = pci_get_word(pci_dev->config + pos + PCI_MSIX_FLAGS); - dev->msix_max &= PCI_MSIX_FLAGS_QSIZE; - dev->msix_max += 1; + dev->msix_max = msix_max; } /* Minimal PM support, nothing writable, device appears to NAK changes */