[PATCH] Make virtio devices multi-function

Anthony Liguori
2008-04-22T14:15:28Z

This patch changes virtio devices to be multi-function devices whenever
possible. This increases the number of virtio devices we can support now by
a factor of 8.

With this patch, I've been able to launch a guest with either 220 disks or 220
network adapters.

I haven't tested the Windows virtio drivers.

Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>

diff --git a/qemu/hw/pci.h b/qemu/hw/pci.h
index 60e4094..df3a878 100644
--- a/qemu/hw/pci.h
+++ b/qemu/hw/pci.h
@@ -33,7 +33,7 @@ typedef struct PCIIORegion {
#define PCI_ROM_SLOT 6
#define PCI_NUM_REGIONS 7

-#define PCI_DEVICES_MAX 64
+#define PCI_DEVICES_MAX 256

#define PCI_VENDOR_ID 0x00 /* 16 bits */
#define PCI_DEVICE_ID 0x02 /* 16 bits */
diff --git a/qemu/hw/virtio.c b/qemu/hw/virtio.c
index 9100bb1..9ea14d3 100644
--- a/qemu/hw/virtio.c
+++ b/qemu/hw/virtio.c
@@ -405,9 +405,18 @@ VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,
PCIDevice *pci_dev;
uint8_t *config;
uint32_t size;
+ static int devfn = 7;
+
+ if ((devfn % 8) == 7)
+ devfn = -1;
+ else
+ devfn++;

pci_dev = pci_register_device(bus, name, struct_size,
- -1, NULL, NULL);
+ devfn, NULL, NULL);
+
+ devfn = pci_dev->devfn;
+
vdev = to_virtio_device(pci_dev);

vdev->status = 0;
@@ -435,6 +444,10 @@ VirtIODevice *virtio_init_pci(PCIBus *bus, const char *name,

config[0x3d] = 1;

+ /* Mark device as multi-function */
+ if ((devfn % 8) == 0)
+ config[0x0e] |= 0x80;
+
vdev->name = name;
vdev->config_len = config_size;
if (vdev->config_len)
diff --git a/qemu/net.h b/qemu/net.h
index 13daa27..3bada75 100644
--- a/qemu/net.h
+++ b/qemu/net.h
@@ -42,7 +42,7 @@ void net_client_uninit(NICInfo *nd);

/* NIC info */

-#define MAX_NICS 8
+#define MAX_NICS 256

struct NICInfo {
uint8_t macaddr[6];
diff --git a/qemu/sysemu.h b/qemu/sysemu.h
index b645fb7..7992a77 100644
--- a/qemu/sysemu.h
+++ b/qemu/sysemu.h
@@ -151,7 +151,7 @@ typedef struct DriveInfo {

#define MAX_IDE_DEVS 2
#define MAX_SCSI_DEVS 7
-#define MAX_DRIVES 32
+#define MAX_DRIVES 256

int nb_drives;
DriveInfo drives_table[MAX_DRIVES+1];
diff --git a/qemu/vl.c b/qemu/vl.c
index 7dd0094..e203a4d 100644
--- a/qemu/vl.c
+++ b/qemu/vl.c
@@ -8754,7 +8754,7 @@ static BOOL WINAPI qemu_ctrl_handler(DWORD type)
}
#endif

-#define MAX_NET_CLIENTS 32
+#define MAX_NET_CLIENTS 512

static int saved_argc;
static char **saved_argv;