From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:40148) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Wj17o-0004c9-Rr for qemu-devel@nongnu.org; Sat, 10 May 2014 02:51:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Wj17k-0002AL-39 for qemu-devel@nongnu.org; Sat, 10 May 2014 02:51:12 -0400 Sender: Paolo Bonzini From: Paolo Bonzini Date: Sat, 10 May 2014 08:50:48 +0200 Message-Id: <1399704652-6827-5-git-send-email-pbonzini@redhat.com> In-Reply-To: <1399704652-6827-1-git-send-email-pbonzini@redhat.com> References: <1399704652-6827-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PULL 4/8] pci-assign: limit # of msix vectors List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org, "Michael S. Tsirkin" From: "Michael S. Tsirkin" 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 Tested-by: Gonglei Cc: qemu-stable@nongnu.org Acked-by: Alex Williamson Signed-off-by: Paolo Bonzini --- 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 570333f..ca58508 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 */ -- 1.8.3.1