ff9ada
From e9ebc159a9acf108e1ec6f622be3f256cf14aba7 Mon Sep 17 00:00:00 2001
ae23c9
From: Bandan Das <bsd@redhat.com>
ae23c9
Date: Tue, 3 Dec 2013 20:05:13 +0100
ae23c9
Subject: vfio: cap number of devices that can be assigned
ae23c9
ae23c9
RH-Author: Bandan Das <bsd@redhat.com>
ae23c9
Message-id: <1386101113-31560-3-git-send-email-bsd@redhat.com>
ae23c9
Patchwork-id: 55984
ae23c9
O-Subject: [PATCH RHEL7 qemu-kvm v2 2/2] vfio: cap number of devices that can be assigned
ae23c9
Bugzilla: 678368
ae23c9
RH-Acked-by: Alex Williamson <alex.williamson@redhat.com>
ae23c9
RH-Acked-by: Marcelo Tosatti <mtosatti@redhat.com>
ae23c9
RH-Acked-by: Michael S. Tsirkin <mst@redhat.com>
ae23c9
ae23c9
Go through all groups to get count of total number of devices
ae23c9
active to enforce limit
ae23c9
ae23c9
Reasoning from Alex for the limit(32) - Assuming 3 slots per
ae23c9
device, with 125 slots (number of memory slots for RHEL 7),
ae23c9
we can support almost 40 devices and still have few slots left
ae23c9
for other uses. Stepping down a bit, the number 32 arbitrarily
ae23c9
matches the number of slots on a PCI bus and is also a nice power
ae23c9
of two.
ae23c9
ae23c9
Signed-off-by: Bandan Das <bsd@redhat.com>
ae23c9
ae23c9
Rebase notes (2.8.0):
ae23c9
- removed return value for vfio_realize (commit 1a22aca)
ae23c9
ae23c9
Merged patches (2.9.0):
ae23c9
- 17eb774 vfio: Use error_setg when reporting max assigned device overshoot
ae23c9
ddf19c
 Merged patches (4.1.0-rc3):
ddf19c
- 2b89558 vfio: increase the cap on number of assigned devices to 64
ae23c9
---
ddf19c
 hw/vfio/pci.c | 29 ++++++++++++++++++++++++++++-
ddf19c
 hw/vfio/pci.h |  1 +
ddf19c
 2 files changed, 29 insertions(+), 1 deletion(-)
ae23c9
ae23c9
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
ff9ada
index 7b45353ce2..eb725a3aee 100644
ae23c9
--- a/hw/vfio/pci.c
ae23c9
+++ b/hw/vfio/pci.c
ff9ada
@@ -45,6 +45,9 @@
ae23c9
 
ddf19c
 #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug"
ae23c9
 
ddf19c
+/* RHEL only: Set once for the first assigned dev */
ddf19c
+static uint16_t device_limit;
ddf19c
+
ae23c9
 static void vfio_disable_interrupts(VFIOPCIDevice *vdev);
ae23c9
 static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled);
ddf19c
 
ff9ada
@@ -2807,9 +2810,30 @@ static void vfio_realize(PCIDevice *pdev, Error **errp)
ae23c9
     ssize_t len;
ae23c9
     struct stat st;
ae23c9
     int groupid;
ae23c9
-    int i, ret;
ae23c9
+    int ret, i = 0;
ddf19c
     bool is_mdev;
ddf19c
 
ddf19c
+    if (device_limit && device_limit != vdev->assigned_device_limit) {
ddf19c
+            error_setg(errp, "Assigned device limit has been redefined. "
ddf19c
+                       "Old:%d, New:%d",
ddf19c
+                       device_limit, vdev->assigned_device_limit);
ddf19c
+            return;
ddf19c
+    } else {
ddf19c
+        device_limit = vdev->assigned_device_limit;
ddf19c
+    }
ae23c9
+
ae23c9
+    QLIST_FOREACH(group, &vfio_group_list, next) {
ae23c9
+        QLIST_FOREACH(vbasedev_iter, &group->device_list, next) {
ae23c9
+            i++;
ae23c9
+        }
ae23c9
+    }
ae23c9
+
ddf19c
+    if (i >= vdev->assigned_device_limit) {
ae23c9
+        error_setg(errp, "Maximum supported vfio devices (%d) "
ddf19c
+                     "already attached", vdev->assigned_device_limit);
ae23c9
+        return;
ae23c9
+    }
ddf19c
+
ae23c9
     if (!vdev->vbasedev.sysfsdev) {
ae23c9
         if (!(~vdev->host.domain || ~vdev->host.bus ||
ddf19c
               ~vdev->host.slot || ~vdev->host.function)) {
ff9ada
@@ -3246,6 +3270,9 @@ static Property vfio_pci_dev_properties[] = {
ddf19c
     DEFINE_PROP_BOOL("x-no-kvm-msix", VFIOPCIDevice, no_kvm_msix, false),
ddf19c
     DEFINE_PROP_BOOL("x-no-geforce-quirks", VFIOPCIDevice,
ddf19c
                      no_geforce_quirks, false),
ddf19c
+    /* RHEL only */
ddf19c
+    DEFINE_PROP_UINT16("x-assigned-device-limit", VFIOPCIDevice,
ddf19c
+                       assigned_device_limit, 64),
ddf19c
     DEFINE_PROP_BOOL("x-no-kvm-ioeventfd", VFIOPCIDevice, no_kvm_ioeventfd,
ddf19c
                      false),
ddf19c
     DEFINE_PROP_BOOL("x-no-vfio-ioeventfd", VFIOPCIDevice, no_vfio_ioeventfd,
ddf19c
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
ff9ada
index 64777516d1..e0fe6ca97e 100644
ddf19c
--- a/hw/vfio/pci.h
ddf19c
+++ b/hw/vfio/pci.h
ff9ada
@@ -139,6 +139,7 @@ struct VFIOPCIDevice {
ddf19c
     EventNotifier err_notifier;
ddf19c
     EventNotifier req_notifier;
ddf19c
     int (*resetfn)(struct VFIOPCIDevice *);
ddf19c
+    uint16_t assigned_device_limit;
ddf19c
     uint32_t vendor_id;
ddf19c
     uint32_t device_id;
ddf19c
     uint32_t sub_vendor_id;
ae23c9
-- 
ff9ada
2.27.0
ae23c9