summary refs log tree commit diff stats
path: root/hw/vfio/pci.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2015-01-10 22:29:09 +0000
committerPeter Maydell <peter.maydell@linaro.org>2015-01-10 22:29:09 +0000
commit64ea8038ffbf703dcd438a108d2d5499c8ff95d9 (patch)
tree66aa5eb09f2926d7f102169e1a6637c1438beccc /hw/vfio/pci.c
parentaaf03019175949eda5087329448b8a0033b89479 (diff)
parentb3e27c3aee8f5a96debfe0346e9c0e3a641a8516 (diff)
downloadfocaccia-qemu-64ea8038ffbf703dcd438a108d2d5499c8ff95d9.tar.gz
focaccia-qemu-64ea8038ffbf703dcd438a108d2d5499c8ff95d9.zip
Merge remote-tracking branch 'remotes/awilliam/tags/vfio-update-20150109.0' into staging
VFIO fixes:
- Fix 32bit overflow in handling large PCI BARs (Alex Williamson)
- Fix interrupt shutdown ordering (Alex Williamson)

# gpg: Signature made Fri 09 Jan 2015 16:23:42 GMT using RSA key ID 3BB08B22
# gpg: Good signature from "Alex Williamson <alex.williamson@redhat.com>"
# gpg:                 aka "Alex Williamson <alex@shazbot.org>"
# gpg:                 aka "Alex Williamson <alwillia@redhat.com>"
# gpg:                 aka "Alex Williamson <alex.l.williamson@gmail.com>"

* remotes/awilliam/tags/vfio-update-20150109.0:
  vfio-pci: Fix interrupt disabling
  vfio-pci: Fix BAR size overflow

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/vfio/pci.c')
-rw-r--r--hw/vfio/pci.c25
1 files changed, 14 insertions, 11 deletions
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index b4e73d1f35..014a92ce5f 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -2129,16 +2129,19 @@ static void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr,
  */
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev)
 {
-    switch (vdev->interrupt) {
-    case VFIO_INT_INTx:
-        vfio_disable_intx(vdev);
-        break;
-    case VFIO_INT_MSI:
-        vfio_disable_msi(vdev);
-        break;
-    case VFIO_INT_MSIX:
+    /*
+     * More complicated than it looks.  Disabling MSI/X transitions the
+     * device to INTx mode (if supported).  Therefore we need to first
+     * disable MSI/X and then cleanup by disabling INTx.
+     */
+    if (vdev->interrupt == VFIO_INT_MSIX) {
         vfio_disable_msix(vdev);
-        break;
+    } else if (vdev->interrupt == VFIO_INT_MSI) {
+        vfio_disable_msi(vdev);
+    }
+
+    if (vdev->interrupt == VFIO_INT_INTx) {
+        vfio_disable_intx(vdev);
     }
 }
 
@@ -2301,7 +2304,7 @@ static void vfio_unmap_bar(VFIOPCIDevice *vdev, int nr)
 static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
 {
     VFIOBAR *bar = &vdev->bars[nr];
-    unsigned size = bar->region.size;
+    uint64_t size = bar->region.size;
     char name[64];
     uint32_t pci_bar;
     uint8_t type;
@@ -2351,7 +2354,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr)
     }
 
     if (vdev->msix && vdev->msix->table_bar == nr) {
-        unsigned start;
+        uint64_t start;
 
         start = HOST_PAGE_ALIGN(vdev->msix->table_offset +
                                 (vdev->msix->entries * PCI_MSIX_ENTRY_SIZE));