]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: make PCI multifunction support more manual
authorLaine Stump <laine@laine.org>
Thu, 29 Sep 2011 17:00:32 +0000 (13:00 -0400)
committerEric Blake <eblake@redhat.com>
Wed, 16 May 2012 22:01:24 +0000 (16:01 -0600)
When support for was added for PCI multifunction cards (in commit
9f8baf, first included in libvirt 0.9.3), it was done by always
turning on the multifunction bit for all PCI devices. Since that time
it has been realized that this is not an ideal solution, and that the
multifunction bit must be selectively turned on. For example, see

  https://bugzilla.redhat.com/show_bug.cgi?id=728174

and the discussion before and after

  https://www.redhat.com/archives/libvir-list/2011-September/msg01036.html

This patch modifies multifunction support so that the multifunction=on
option is only added to the qemu commandline for a device if its PCI
<address> definition has the attribute "multifunction='on'", e.g.:

  <address type='pci' domain='0x0000' bus='0x00'
           slot='0x04' function='0x0' multifunction='on'/>

In practice, the multifunction bit should only be turned on if
function='0' AND other functions will be used in the same slot - it
usually isn't needed for functions 1-7 (although there are apparently
some exceptions, e.g. the Intel X53 according to the QEMU source
code), and should never be set if only function 0 will be used in the
slot. The test cases have been changed accordingly to illustrate.

With this patch in place, if a user attempts to assign multiple
functions in a slot without setting the multifunction bit for function
0, libvirt will issue an error when the domain is defined, and the
define operation will fail. In the future, we may decide to detect
this situation and automatically add multifunction=on to avoid the
error; even then it will still be useful to have a manual method of
turning on multifunction since, as stated above, there are some
devices that excpect it to be turned on for all functions in a slot.

A side effect of this patch is that attempts to use the same PCI
address for two different devices will now log an error (previously
this would cause the domain define operation to fail, but there would
be no log message generated). Because the function doing this log was
almost completely rewritten, I didn't think it worthwhile to make a
separate patch for that fix (the entire patch would immediately be
obsoleted).
(cherry picked from commit c329db7180d77c8077b9f9cd167a71d7f347227a)

16 files changed:
docs/formatdomain.html.in
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
src/libvirt_private.syms
src/qemu/qemu_command.c
tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.args
tests/qemuxml2argvdata/qemuxml2argv-multifunction-pci-device.xml
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.args
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-companion.xml
tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-ehci-addr.args
tests/qemuxml2argvdata/qemuxml2argv-usb-piix3-controller.args
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.args
tests/qemuxml2argvdata/qemuxml2argv-usb1-usb2.xml

index 0a7abafac4203786c9cc9e043186149065182d5b..390476d028e820d8d7c13a5e1d4c9bff71fa2f64 100644 (file)
         The <code>type</code> attribute is mandatory, and is typically
         "pci" or "drive".  For a "pci" controller, additional
         attributes for <code>bus</code>, <code>slot</code>,
-        and <code>function</code> must be present, as well as an
-        optional <code>domain</code>.  For a "drive" controller,
-        additional attributes <code>controller</code>, <code>bus</code>,
+        and <code>function</code> must be present, as well as
+        optional <code>domain</code> and <code>multifunction</code>.
+        Multifunction defaults to 'off'; any other value requires
+        QEMU 0.1.3 and <span class="since">libvirt 0.9.7</span>.  For a
+        "drive" controller, additional attributes
+        <code>controller</code>, <code>bus</code>,
         and <code>unit</code> are available, each defaulting to 0.
+
       </dd>
     </dl>
 
     &lt;/controller&gt;
     &lt;controller type='usb' index='0' model='ich9-uhci1'&gt;
       &lt;master startport='0'/&gt;
-      &lt;address type='pci' domain='0' bus='0' slot='4' function='0'/&gt;
+      &lt;address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/&gt;
     &lt;/controller&gt;
     ...
   &lt;/devices&gt;
       with <code>virsh nodedev-list</code>. The
       <code>bus</code> attribute allows the hexadecimal values 0 to ff, the
       <code>slot</code> attribute allows the hexadecimal values 0 to 1f, and
-      the <code>function</code> attribute allows the hexadecimal values 0 to
-      7. There is also an optional <code>domain</code> attribute for the
-      PCI domain, with hexadecimal values 0 to ffff, but it is currently
-      not used by qemu.</dd>
+      the <code>function</code> attribute allows the hexadecimal values 0 to 7.
+      The <code>multifunction</code> attribute controls turning on the
+      multifunction bit for a particular slot/function in the PCI
+      control register<span class="since">since 0.9.7, requires QEMU
+      0.13</span>. <code>multifunction</code> defaults to 'off', but
+      should be set to 'on' for function 0 of a slot that will have
+      multiple functions used.
+      There is also an optional <code>domain</code> attribute for
+      the PCI domain, with hexadecimal values 0 to ffff, but it is
+      currently not used by qemu.</dd>
     </dl>
 
     <h4><a name="elementsRedir">Redirected devices</a></h4>
       the interface to a particular pci slot, with
       attribute <code>type='pci'</code> and additional
       attributes <code>domain</code>, <code>bus</code>, <code>slot</code>,
-      and <code>function</code> as appropriate.
+      <code>function</code>, and <code>multifunction</code>
+      <span class="since">since 0.9.7, requires QEMU 0.13</span> as appropriate.
     </p>
 
     <h5><a name="elementsNICSVirtual">Virtual network</a></h5>
index d0da41c5837b1293f750b6043dff320e6c2e1d30..9f8d292e807197932a6a6ec71da3f363143c335b 100644 (file)
     <attribute name="function">
       <ref name="pciFunc"/>
     </attribute>
+    <optional>
+      <attribute name="multifunction">
+        <choice>
+          <value>on</value>
+          <value>off</value>
+        </choice>
+      </attribute>
+    </optional>
   </define>
   <define name="driveaddress">
     <optional>
index 7463d7c3c2d2fc9c746512332e906b50623e33cb..318f52331655002ba6dc10e5e50969c81b5f4dad 100644 (file)
@@ -138,6 +138,12 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
               "ccid",
               "usb")
 
+VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
+              VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
+              "default",
+              "on",
+              "off")
+
 VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
               "block",
               "file",
@@ -1645,6 +1651,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
                           info->addr.pci.bus,
                           info->addr.pci.slot,
                           info->addr.pci.function);
+        if (info->addr.pci.multi) {
+           virBufferAsprintf(buf, " multifunction='%s'",
+                             virDomainDeviceAddressPciMultiTypeToString(info->addr.pci.multi));
+        }
         break;
 
     case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
@@ -1689,7 +1699,7 @@ static int
 virDomainDevicePCIAddressParseXML(xmlNodePtr node,
                                   virDomainDevicePCIAddressPtr addr)
 {
-    char *domain, *slot, *bus, *function;
+    char *domain, *slot, *bus, *function, *multi;
     int ret = -1;
 
     memset(addr, 0, sizeof(*addr));
@@ -1698,6 +1708,7 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
     bus      = virXMLPropString(node, "bus");
     slot     = virXMLPropString(node, "slot");
     function = virXMLPropString(node, "function");
+    multi    = virXMLPropString(node, "multifunction");
 
     if (domain &&
         virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
@@ -1727,6 +1738,14 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
         goto cleanup;
     }
 
+    if (multi &&
+        ((addr->multi = virDomainDeviceAddressPciMultiTypeFromString(multi)) <= 0)) {
+        virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                             _("Unknown value '%s' for <address> 'multifunction' attribute"),
+                             multi);
+        goto cleanup;
+
+    }
     if (!virDomainDevicePCIAddressIsValid(addr)) {
         virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                              _("Insufficient specification for PCI address"));
@@ -1740,6 +1759,7 @@ cleanup:
     VIR_FREE(bus);
     VIR_FREE(slot);
     VIR_FREE(function);
+    VIR_FREE(multi);
     return ret;
 }
 
index f9b7bb78155d0039c193444537e3d12608025a9b..f4a38fbf3af912c16ca2d1e1d1b5d3d1ffb136c3 100644 (file)
@@ -74,6 +74,14 @@ enum virDomainDeviceAddressType {
     VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST
 };
 
+enum virDomainDeviceAddressPciMulti {
+    VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_DEFAULT = 0,
+    VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON,
+    VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF,
+
+    VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST
+};
+
 typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress;
 typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr;
 struct _virDomainDevicePCIAddress {
@@ -81,6 +89,7 @@ struct _virDomainDevicePCIAddress {
     unsigned int bus;
     unsigned int slot;
     unsigned int function;
+    int          multi;  /* enum virDomainDeviceAddressPciMulti */
 };
 
 typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress;
@@ -1820,6 +1829,7 @@ VIR_ENUM_DECL(virDomainLifecycle)
 VIR_ENUM_DECL(virDomainLifecycleCrash)
 VIR_ENUM_DECL(virDomainDevice)
 VIR_ENUM_DECL(virDomainDeviceAddress)
+VIR_ENUM_DECL(virDomainDeviceAddressPciMulti)
 VIR_ENUM_DECL(virDomainDisk)
 VIR_ENUM_DECL(virDomainDiskDevice)
 VIR_ENUM_DECL(virDomainDiskBus)
index 8235ea1276f91a34e8004d9880e94a7309a11015..da3042eece69ccbaf3677e609426e4960775c59f 100644 (file)
@@ -269,6 +269,8 @@ virDomainDefParseNode;
 virDomainDefParseString;
 virDomainDeleteConfig;
 virDomainDeviceAddressIsValid;
+virDomainDeviceAddressPciMultiTypeFromString;
+virDomainDeviceAddressPciMultiTypeToString;
 virDomainDeviceAddressTypeToString;
 virDomainDeviceDefFree;
 virDomainDeviceDefParse;
index 0adc56a5f94f75480559c6267a6c0e0879765d16..ee184c2ef0c7a74254b3ea2fd24c66e34c6fb2ba 100644 (file)
@@ -772,22 +772,65 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
                                  virDomainDeviceInfoPtr dev,
                                  void *opaque)
 {
+    int ret = -1;
+    char *addr = NULL;
     qemuDomainPCIAddressSetPtr addrs = opaque;
 
-    if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
-        char *addr = qemuPCIAddressAsString(dev);
-        if (!addr)
-            return -1;
+    if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
+        return 0;
 
-        VIR_DEBUG("Remembering PCI addr %s", addr);
+    addr = qemuPCIAddressAsString(dev);
+    if (!addr)
+        goto cleanup;
 
-        if (virHashAddEntry(addrs->used, addr, addr) < 0) {
-            VIR_FREE(addr);
-            return -1;
+    if (virHashLookup(addrs->used, addr)) {
+        if (dev->addr.pci.function != 0) {
+            qemuReportError(VIR_ERR_XML_ERROR,
+                            _("Attempted double use of PCI Address '%s' "
+                              "(may need \"multifunction='on'\" for device on function 0"),
+                            addr);
+        } else {
+            qemuReportError(VIR_ERR_XML_ERROR,
+                            _("Attempted double use of PCI Address '%s'"), addr);
         }
+        goto cleanup;
     }
 
-    return 0;
+    VIR_DEBUG("Remembering PCI addr %s", addr);
+    if (virHashAddEntry(addrs->used, addr, addr) < 0)
+        goto cleanup;
+    addr = NULL;
+
+    if ((dev->addr.pci.function == 0) &&
+        (dev->addr.pci.multi != VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)) {
+        /* a function 0 w/o multifunction=on must reserve the entire slot */
+        int function;
+        virDomainDeviceInfo temp_dev = *dev;
+
+        for (function = 1; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
+            temp_dev.addr.pci.function = function;
+            addr = qemuPCIAddressAsString(&temp_dev);
+            if (!addr)
+                goto cleanup;
+
+            if (virHashLookup(addrs->used, addr)) {
+                qemuReportError(VIR_ERR_XML_ERROR,
+                                _("Attempted double use of PCI Address '%s'"
+                                  "(need \"multifunction='off'\" for device on function 0)"),
+                                addr);
+                goto cleanup;
+            }
+
+            VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function 0)", addr);
+            if (virHashAddEntry(addrs->used, addr, addr))
+                goto cleanup;
+            addr = NULL;
+        }
+    }
+    ret = 0;
+cleanup:
+    VIR_FREE(addr);
+    return ret;
 }
 
 
@@ -1374,7 +1417,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
             if (info->addr.pci.function != 0) {
                 qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                                 _("Only PCI device addresses with function=0 "
-                                  "are supported"));
+                                  "are supported with this QEMU binary"));
+                return -1;
+            }
+            if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON) {
+                qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                                _("'multifunction=on' is not supported with "
+                                  "this QEMU binary"));
                 return -1;
             }
         }
@@ -1389,11 +1438,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
             virBufferAsprintf(buf, ",bus=pci.0");
         else
             virBufferAsprintf(buf, ",bus=pci");
-        if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION))
-            virBufferAsprintf(buf, ",multifunction=on,addr=0x%x.0x%x",
-                              info->addr.pci.slot, info->addr.pci.function);
-        else
-            virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
+        if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)
+            virBufferAddLit(buf, ",multifunction=on");
+        else if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF)
+            virBufferAddLit(buf, ",multifunction=off");
+        virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot);
+        if (info->addr.pci.function != 0)
+           virBufferAsprintf(buf, ".0x%x", info->addr.pci.function);
     } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
         virBufferAsprintf(buf, ",bus=");
         qemuUsbId(buf, info->addr.usb.bus);
index ff229f2f59e07d3b0c11c1dd279cfdee6cb5fc3c..8a2150eaed51f3209662dc2327ef65895762d963 100644 (file)
@@ -1,15 +1,15 @@
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
 pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
 -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
--device lsi,id=scsi0,bus=pci.0,multifunction=on,addr=0x3.0x0 \
--device lsi,id=scsi1,bus=pci.0,multifunction=on,addr=0x4.0x0 \
+-device lsi,id=scsi0,bus=pci.0,multifunction=off,addr=0x3 \
+-device lsi,id=scsi1,bus=pci.0,multifunction=on,addr=0x4 \
 -device lsi,id=scsi2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device lsi,id=scsi3,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device lsi,id=scsi4,bus=pci.0,multifunction=on,addr=0x4.0x3 \
--device lsi,id=scsi5,bus=pci.0,multifunction=on,addr=0x4.0x4 \
--device lsi,id=scsi6,bus=pci.0,multifunction=on,addr=0x4.0x5 \
--device lsi,id=scsi7,bus=pci.0,multifunction=on,addr=0x4.0x6 \
--device lsi,id=scsi8,bus=pci.0,multifunction=on,addr=0x4.0x7 \
+-device lsi,id=scsi3,bus=pci.0,addr=0x4.0x2 \
+-device lsi,id=scsi4,bus=pci.0,addr=0x4.0x3 \
+-device lsi,id=scsi5,bus=pci.0,addr=0x4.0x4 \
+-device lsi,id=scsi6,bus=pci.0,addr=0x4.0x5 \
+-device lsi,id=scsi7,bus=pci.0,addr=0x4.0x6 \
+-device lsi,id=scsi8,bus=pci.0,addr=0x4.0x7 \
 -drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-0 \
 -device scsi-disk,bus=scsi0.0,scsi-id=0,drive=drive-scsi0-0-0,id=scsi0-0-0 \
--usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x5.0x0
+-usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
index 672fb6119adeb4340dc88c95f3864f6fc1de5460..24b95b8933bb586b297d526a8fc619ffd7bca978 100644 (file)
       <address type='drive' controller='0' bus='0' unit='0'/>
     </disk>
     <controller type='scsi' index='0'>
-      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0' multifunction='off'/>
     </controller>
     <controller type='scsi' index='1'>
-      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
     </controller>
     <controller type='scsi' index='2'>
-      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1' multifunction='on'/>
     </controller>
     <controller type='scsi' index='3'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
index 10075448373dc4c22f67be185a2f16f8bfbe40bb..080d483b87e23f2527ef21b85173dd2b0448d6f3 100644 (file)
@@ -1,6 +1,9 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
+-m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index 05a6adf6ef460a61a8f4cedfa162698f358e0d52..5a43638be7daca4b21195f5e40ac7202753f03c1 100644 (file)
@@ -15,7 +15,7 @@
     </controller>
     <controller type='usb' index='0' model='ich9-uhci1'>
       <master startport='0'/>
-      <address type='pci' domain='0' bus='0' slot='4' function='0'/>
+      <address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/>
     </controller>
     <controller type='usb' index='0' model='ich9-uhci2'>
       <master startport='2'/>
index 0059ab590510f76f47cdd673ed4eb01133c292d3..babd4f804a5a1a07968de9d219ef743a0a17adaa 100644 (file)
@@ -1 +1,6 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index 06863bbde4c7541177968fd69adb562160902ecc..1b2d5c1e2804fdc88c2074dc189830bc86024c5d 100644 (file)
@@ -1 +1,6 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c -device piix3-usb-uhci,id=usb,bus=pci.0,multifunction=on,addr=0x1.0x2 -device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index f6270d504bb162c971365676459ff2a333016515..7d34c2a076f85bdab5917efbb1d71f3700947bac 100644 (file)
@@ -1,10 +1,10 @@
 LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
+-device ich9-usb-ehci1,id=usb,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
 -chardev socket,id=charredir0,host=localhost,port=4000 \
 -device usb-redir,chardev=charredir0,id=redir0 \
 -chardev spicevmc,id=charredir1,name=usbredir \
 -device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=4 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index 1dac3fbc937df48da71ccf2abc66ae0a72cd48d6..a359a3d4132e3bcf0772dbb84c033c976118fb58 100644 (file)
@@ -19,7 +19,7 @@
     </controller>
     <controller type='usb' index='0' model='ich9-uhci1'>
       <master startport='0'/>
-      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' multifunction='on'/>
     </controller>
     <controller type='usb' index='0' model='ich9-uhci2'>
       <master startport='2'/>
index be4a78e3a44f9efca0540cf2588e672fedc4259e..0a61af5622838cb5cd749b435b6b9e3a576d5eb0 100644 (file)
@@ -1,15 +1,18 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
--device piix3-usb-uhci,id=usb,bus=pci.0,multifunction=on,addr=0x1.0x2 \
--device ich9-usb-ehci1,id=usb1,bus=pci.0,multifunction=on,addr=0x4.0x7 \
--device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \
--device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
--device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \
--device ich9-usb-ehci1,id=usb2,bus=pci.0,multifunction=on,addr=0x5.0x7 \
--device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5.0x0 \
--device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.0,multifunction=on,addr=0x5.0x1 \
--device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.0,multifunction=on,addr=0x5.0x2 \
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
+-M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device ich9-usb-ehci1,id=usb1,bus=pci.0,addr=0x4.0x7 \
+-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
+-device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
+-device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
+-device ich9-usb-ehci1,id=usb2,bus=pci.0,addr=0x5.0x7 \
+-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5 \
+-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.0,addr=0x5.0x1 \
+-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.0,addr=0x5.0x2 \
 -device usb-hub,id=hub0,bus=usb1.0,port=1 \
 -device usb-tablet,id=input0,bus=usb.0,port=2 \
 -device usb-host,hostbus=14,hostaddr=6,id=hostdev0,bus=usb2.0,port=1 \
 -device usb-host,hostbus=14,hostaddr=7,id=hostdev1,bus=usb2.0,port=2 \
--device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
index e8ada4db0e5dfb4b47d2e218b9ed57ac5cc62988..b12b841b21082d6ad8d3b4ac158e13a9a16c57a5 100644 (file)
@@ -21,7 +21,7 @@
     </controller>
     <controller type='usb' index='1' model='ich9-uhci1'>
       <master startport='0'/>
-      <address type='pci' domain='0' bus='0' slot='4' function='0'/>
+      <address type='pci' domain='0' bus='0' slot='4' function='0' multifunction='on'/>
     </controller>
     <controller type='usb' index='1' model='ich9-uhci2'>
       <master startport='2'/>
@@ -37,7 +37,7 @@
     </controller>
     <controller type='usb' index='2' model='ich9-uhci1'>
       <master startport='0'/>
-      <address type='pci' domain='0' bus='0' slot='5' function='0'/>
+      <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='on'/>
     </controller>
     <controller type='usb' index='2' model='ich9-uhci2'>
       <master startport='2'/>