qemu: make PCI multifunction support more manual

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).
This commit is contained in:
Laine Stump 2011-09-29 13:00:32 -04:00
parent be7bc4d5cc
commit c329db7180
16 changed files with 183 additions and 65 deletions

View File

@ -1118,10 +1118,14 @@
The <code>type</code> attribute is mandatory, and is typically The <code>type</code> attribute is mandatory, and is typically
"pci" or "drive". For a "pci" controller, additional "pci" or "drive". For a "pci" controller, additional
attributes for <code>bus</code>, <code>slot</code>, attributes for <code>bus</code>, <code>slot</code>,
and <code>function</code> must be present, as well as an and <code>function</code> must be present, as well as
optional <code>domain</code>. For a "drive" controller, optional <code>domain</code> and <code>multifunction</code>.
additional attributes <code>controller</code>, <code>bus</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. and <code>unit</code> are available, each defaulting to 0.
</dd> </dd>
</dl> </dl>
@ -1298,7 +1302,7 @@
&lt;/controller&gt; &lt;/controller&gt;
&lt;controller type='usb' index='0' model='ich9-uhci1'&gt; &lt;controller type='usb' index='0' model='ich9-uhci1'&gt;
&lt;master startport='0'/&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;/controller&gt;
... ...
&lt;/devices&gt; &lt;/devices&gt;
@ -1431,10 +1435,16 @@
with <code>virsh nodedev-list</code>. The with <code>virsh nodedev-list</code>. The
<code>bus</code> attribute allows the hexadecimal values 0 to ff, 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 <code>slot</code> attribute allows the hexadecimal values 0 to 1f, and
the <code>function</code> attribute allows the hexadecimal values 0 to the <code>function</code> attribute allows the hexadecimal values 0 to 7.
7. There is also an optional <code>domain</code> attribute for the The <code>multifunction</code> attribute controls turning on the
PCI domain, with hexadecimal values 0 to ffff, but it is currently multifunction bit for a particular slot/function in the PCI
not used by qemu.</dd> 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> </dl>
<h4><a name="elementsRedir">Redirected devices</a></h4> <h4><a name="elementsRedir">Redirected devices</a></h4>
@ -1602,7 +1612,8 @@
the interface to a particular pci slot, with the interface to a particular pci slot, with
attribute <code>type='pci'</code> and additional attribute <code>type='pci'</code> and additional
attributes <code>domain</code>, <code>bus</code>, <code>slot</code>, 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> </p>
<h5><a name="elementsNICSVirtual">Virtual network</a></h5> <h5><a name="elementsNICSVirtual">Virtual network</a></h5>

View File

@ -2118,6 +2118,14 @@
<attribute name="function"> <attribute name="function">
<ref name="pciFunc"/> <ref name="pciFunc"/>
</attribute> </attribute>
<optional>
<attribute name="multifunction">
<choice>
<value>on</value>
<value>off</value>
</choice>
</attribute>
</optional>
</define> </define>
<define name="driveaddress"> <define name="driveaddress">
<optional> <optional>

View File

@ -138,6 +138,12 @@ VIR_ENUM_IMPL(virDomainDeviceAddress, VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST,
"ccid", "ccid",
"usb") "usb")
VIR_ENUM_IMPL(virDomainDeviceAddressPciMulti,
VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST,
"default",
"on",
"off")
VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST, VIR_ENUM_IMPL(virDomainDisk, VIR_DOMAIN_DISK_TYPE_LAST,
"block", "block",
"file", "file",
@ -1652,6 +1658,10 @@ virDomainDeviceInfoFormat(virBufferPtr buf,
info->addr.pci.bus, info->addr.pci.bus,
info->addr.pci.slot, info->addr.pci.slot,
info->addr.pci.function); info->addr.pci.function);
if (info->addr.pci.multi) {
virBufferAsprintf(buf, " multifunction='%s'",
virDomainDeviceAddressPciMultiTypeToString(info->addr.pci.multi));
}
break; break;
case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE: case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE:
@ -1696,7 +1706,7 @@ static int
virDomainDevicePCIAddressParseXML(xmlNodePtr node, virDomainDevicePCIAddressParseXML(xmlNodePtr node,
virDomainDevicePCIAddressPtr addr) virDomainDevicePCIAddressPtr addr)
{ {
char *domain, *slot, *bus, *function; char *domain, *slot, *bus, *function, *multi;
int ret = -1; int ret = -1;
memset(addr, 0, sizeof(*addr)); memset(addr, 0, sizeof(*addr));
@ -1705,6 +1715,7 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
bus = virXMLPropString(node, "bus"); bus = virXMLPropString(node, "bus");
slot = virXMLPropString(node, "slot"); slot = virXMLPropString(node, "slot");
function = virXMLPropString(node, "function"); function = virXMLPropString(node, "function");
multi = virXMLPropString(node, "multifunction");
if (domain && if (domain &&
virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) { virStrToLong_ui(domain, NULL, 0, &addr->domain) < 0) {
@ -1734,6 +1745,14 @@ virDomainDevicePCIAddressParseXML(xmlNodePtr node,
goto cleanup; 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)) { if (!virDomainDevicePCIAddressIsValid(addr)) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Insufficient specification for PCI address")); _("Insufficient specification for PCI address"));
@ -1747,6 +1766,7 @@ cleanup:
VIR_FREE(bus); VIR_FREE(bus);
VIR_FREE(slot); VIR_FREE(slot);
VIR_FREE(function); VIR_FREE(function);
VIR_FREE(multi);
return ret; return ret;
} }

View File

@ -74,6 +74,14 @@ enum virDomainDeviceAddressType {
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_LAST 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 struct _virDomainDevicePCIAddress virDomainDevicePCIAddress;
typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr; typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr;
struct _virDomainDevicePCIAddress { struct _virDomainDevicePCIAddress {
@ -81,6 +89,7 @@ struct _virDomainDevicePCIAddress {
unsigned int bus; unsigned int bus;
unsigned int slot; unsigned int slot;
unsigned int function; unsigned int function;
int multi; /* enum virDomainDeviceAddressPciMulti */
}; };
typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress; typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress;
@ -1830,6 +1839,7 @@ VIR_ENUM_DECL(virDomainLifecycle)
VIR_ENUM_DECL(virDomainLifecycleCrash) VIR_ENUM_DECL(virDomainLifecycleCrash)
VIR_ENUM_DECL(virDomainDevice) VIR_ENUM_DECL(virDomainDevice)
VIR_ENUM_DECL(virDomainDeviceAddress) VIR_ENUM_DECL(virDomainDeviceAddress)
VIR_ENUM_DECL(virDomainDeviceAddressPciMulti)
VIR_ENUM_DECL(virDomainDisk) VIR_ENUM_DECL(virDomainDisk)
VIR_ENUM_DECL(virDomainDiskDevice) VIR_ENUM_DECL(virDomainDiskDevice)
VIR_ENUM_DECL(virDomainDiskBus) VIR_ENUM_DECL(virDomainDiskBus)

View File

@ -269,6 +269,8 @@ virDomainDefParseNode;
virDomainDefParseString; virDomainDefParseString;
virDomainDeleteConfig; virDomainDeleteConfig;
virDomainDeviceAddressIsValid; virDomainDeviceAddressIsValid;
virDomainDeviceAddressPciMultiTypeFromString;
virDomainDeviceAddressPciMultiTypeToString;
virDomainDeviceAddressTypeToString; virDomainDeviceAddressTypeToString;
virDomainDeviceDefFree; virDomainDeviceDefFree;
virDomainDeviceDefParse; virDomainDeviceDefParse;

View File

@ -774,22 +774,65 @@ static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
virDomainDeviceInfoPtr dev, virDomainDeviceInfoPtr dev,
void *opaque) void *opaque)
{ {
int ret = -1;
char *addr = NULL;
qemuDomainPCIAddressSetPtr addrs = opaque; qemuDomainPCIAddressSetPtr addrs = opaque;
if (dev->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { if (dev->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
char *addr = qemuPCIAddressAsString(dev); return 0;
if (!addr)
return -1;
VIR_DEBUG("Remembering PCI addr %s", addr); addr = qemuPCIAddressAsString(dev);
if (!addr)
goto cleanup;
if (virHashAddEntry(addrs->used, addr, addr) < 0) { if (virHashLookup(addrs->used, addr)) {
VIR_FREE(addr); if (dev->addr.pci.function != 0) {
return -1; 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;
} }
@ -1376,7 +1419,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
if (info->addr.pci.function != 0) { if (info->addr.pci.function != 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Only PCI device addresses with function=0 " _("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; return -1;
} }
} }
@ -1391,11 +1440,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
virBufferAsprintf(buf, ",bus=pci.0"); virBufferAsprintf(buf, ",bus=pci.0");
else else
virBufferAsprintf(buf, ",bus=pci"); virBufferAsprintf(buf, ",bus=pci");
if (qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_MULTIFUNCTION)) if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_ON)
virBufferAsprintf(buf, ",multifunction=on,addr=0x%x.0x%x", virBufferAddLit(buf, ",multifunction=on");
info->addr.pci.slot, info->addr.pci.function); else if (info->addr.pci.multi == VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_OFF)
else virBufferAddLit(buf, ",multifunction=off");
virBufferAsprintf(buf, ",addr=0x%x", info->addr.pci.slot); 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) { } else if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
virBufferAsprintf(buf, ",bus="); virBufferAsprintf(buf, ",bus=");
qemuUsbId(buf, info->addr.usb.bus); qemuUsbId(buf, info->addr.usb.bus);

View File

@ -1,15 +1,15 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ 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 \ pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \ -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=scsi0,bus=pci.0,multifunction=off,addr=0x3 \
-device lsi,id=scsi1,bus=pci.0,multifunction=on,addr=0x4.0x0 \ -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=scsi2,bus=pci.0,multifunction=on,addr=0x4.0x1 \
-device lsi,id=scsi3,bus=pci.0,multifunction=on,addr=0x4.0x2 \ -device lsi,id=scsi3,bus=pci.0,addr=0x4.0x2 \
-device lsi,id=scsi4,bus=pci.0,multifunction=on,addr=0x4.0x3 \ -device lsi,id=scsi4,bus=pci.0,addr=0x4.0x3 \
-device lsi,id=scsi5,bus=pci.0,multifunction=on,addr=0x4.0x4 \ -device lsi,id=scsi5,bus=pci.0,addr=0x4.0x4 \
-device lsi,id=scsi6,bus=pci.0,multifunction=on,addr=0x4.0x5 \ -device lsi,id=scsi6,bus=pci.0,addr=0x4.0x5 \
-device lsi,id=scsi7,bus=pci.0,multifunction=on,addr=0x4.0x6 \ -device lsi,id=scsi7,bus=pci.0,addr=0x4.0x6 \
-device lsi,id=scsi8,bus=pci.0,multifunction=on,addr=0x4.0x7 \ -device lsi,id=scsi8,bus=pci.0,addr=0x4.0x7 \
-drive file=/tmp/scsidisk.img,if=none,id=drive-scsi0-0-0 \ -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 \ -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

View File

@ -20,13 +20,13 @@
<address type='drive' controller='0' bus='0' unit='0'/> <address type='drive' controller='0' bus='0' unit='0'/>
</disk> </disk>
<controller type='scsi' index='0'> <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>
<controller type='scsi' index='1'> <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>
<controller type='scsi' index='2'> <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>
<controller type='scsi' index='3'> <controller type='scsi' index='3'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>

View 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 \ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
-device ich9-usb-ehci1,id=usb,bus=pci.0,multifunction=on,addr=0x4.0x7 \ -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
-device ich9-usb-uhci1,masterbus=usb.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \ -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
-device ich9-usb-uhci2,masterbus=usb.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \ -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
-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 virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0 -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

View File

@ -15,7 +15,7 @@
</controller> </controller>
<controller type='usb' index='0' model='ich9-uhci1'> <controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/> <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>
<controller type='usb' index='0' model='ich9-uhci2'> <controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/> <master startport='2'/>

View 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

View 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

View 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 \ 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-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.0x0 \ -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,multifunction=on,addr=0x4.0x1 \ -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,multifunction=on,addr=0x4.0x2 \ -device ich9-usb-uhci3,masterbus=usb.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
-chardev socket,id=charredir0,host=localhost,port=4000 \ -chardev socket,id=charredir0,host=localhost,port=4000 \
-device usb-redir,chardev=charredir0,id=redir0 \ -device usb-redir,chardev=charredir0,id=redir0 \
-chardev spicevmc,id=charredir1,name=usbredir \ -chardev spicevmc,id=charredir1,name=usbredir \
-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=4 \ -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

View File

@ -19,7 +19,7 @@
</controller> </controller>
<controller type='usb' index='0' model='ich9-uhci1'> <controller type='usb' index='0' model='ich9-uhci1'>
<master startport='0'/> <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>
<controller type='usb' index='0' model='ich9-uhci2'> <controller type='usb' index='0' model='ich9-uhci2'>
<master startport='2'/> <master startport='2'/>

View 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 \ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S \
-device piix3-usb-uhci,id=usb,bus=pci.0,multifunction=on,addr=0x1.0x2 \ -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults \
-device ich9-usb-ehci1,id=usb1,bus=pci.0,multifunction=on,addr=0x4.0x7 \ -chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
-device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4.0x0 \ -mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
-device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,multifunction=on,addr=0x4.0x1 \ -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
-device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,multifunction=on,addr=0x4.0x2 \ -device ich9-usb-ehci1,id=usb1,bus=pci.0,addr=0x4.0x7 \
-device ich9-usb-ehci1,id=usb2,bus=pci.0,multifunction=on,addr=0x5.0x7 \ -device ich9-usb-uhci1,masterbus=usb1.0,firstport=0,bus=pci.0,multifunction=on,addr=0x4 \
-device ich9-usb-uhci1,masterbus=usb2.0,firstport=0,bus=pci.0,multifunction=on,addr=0x5.0x0 \ -device ich9-usb-uhci2,masterbus=usb1.0,firstport=2,bus=pci.0,addr=0x4.0x1 \
-device ich9-usb-uhci2,masterbus=usb2.0,firstport=2,bus=pci.0,multifunction=on,addr=0x5.0x1 \ -device ich9-usb-uhci3,masterbus=usb1.0,firstport=4,bus=pci.0,addr=0x4.0x2 \
-device ich9-usb-uhci3,masterbus=usb2.0,firstport=4,bus=pci.0,multifunction=on,addr=0x5.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-hub,id=hub0,bus=usb1.0,port=1 \
-device usb-tablet,id=input0,bus=usb.0,port=2 \ -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=6,id=hostdev0,bus=usb2.0,port=1 \
-device usb-host,hostbus=14,hostaddr=7,id=hostdev1,bus=usb2.0,port=2 \ -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

View File

@ -21,7 +21,7 @@
</controller> </controller>
<controller type='usb' index='1' model='ich9-uhci1'> <controller type='usb' index='1' model='ich9-uhci1'>
<master startport='0'/> <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>
<controller type='usb' index='1' model='ich9-uhci2'> <controller type='usb' index='1' model='ich9-uhci2'>
<master startport='2'/> <master startport='2'/>
@ -37,7 +37,7 @@
</controller> </controller>
<controller type='usb' index='2' model='ich9-uhci1'> <controller type='usb' index='2' model='ich9-uhci1'>
<master startport='0'/> <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>
<controller type='usb' index='2' model='ich9-uhci2'> <controller type='usb' index='2' model='ich9-uhci2'>
<master startport='2'/> <master startport='2'/>