<p>
PCI controllers have an optional <code>model</code> attribute with
- possible values <code>pci-root</code> or <code>pci-bridge</code>.
- For machine types which provide an implicit pci bus, the pci-root
+ possible values <code>pci-root</code>, <code>pcie-root</code>
+ or <code>pci-bridge</code>.
+ For machine types which provide an implicit PCI bus, the pci-root
controller with index=0 is auto-added and required to use PCI devices.
- PCI root has no address.
- PCI bridges are auto-added if there are too many devices to fit on
- the one bus provided by pci-root, or a PCI bus number greater than zero
- was specified.
+ pci-root has no address.
PCI bridges can also be specified manually, but their addresses should
only refer to PCI buses provided by already specified PCI controllers.
Leaving gaps in the PCI controller indexes might lead to an invalid
configuration.
- (<span class="since">since 1.0.5</span>)
+ (pci-root and pci-bridge <span class="since">since 1.0.5</span>)
</p>
<pre>
...
<devices>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='1' model='pci-bridge'>
- <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction=off'/>
+ <address type='pci' domain='0' bus='0' slot='5' function='0' multifunction='off'/>
</controller>
</devices>
+ ...</pre>
+
+ <p>
+ For machine types which provide an implicit PCI Express (PCIe)
+ bus (for example, the machine types based on the Q35 chipset),
+ the pcie-root controller with index=0 is auto-added to the
+ domain's configuration. pcie-root has also no address, provides
+ 31 slots (numbered 1-31) and can only be used to attach PCIe
+ devices. (<span class="since">since 1.1.2</span>).
+ </p>
+<pre>
+ ...
+ <devices>
+ <controller type='pci' index='0' model='pcie-root'/>
+ </devices>
...</pre>
<h4><a name="elementsLease">Device leases</a></h4>
<attribute name="model">
<choice>
<value>pci-root</value>
+ <value>pcie-root</value>
<value>pci-bridge</value>
</choice>
</attribute>
VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
"pci-root",
+ "pcie-root",
"pci-bridge")
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
case VIR_DOMAIN_CONTROLLER_TYPE_PCI:
switch (def->model) {
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("pci-root controller should not "
+ _("pci-root and pcie-root controllers should not "
"have an address"));
goto error;
}
if (def->idx != 0) {
virReportError(VIR_ERR_XML_ERROR, "%s",
- _("pci-root controller should have "
- "index 0"));
+ _("pci-root and pcie-root controllers "
+ "should have index 0"));
goto error;
}
typedef enum {
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT,
+ VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT,
VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE,
VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
"device. Device requires a standard PCI slot, "
"which is not provided by this bus"),
addr->domain, addr->bus);
+ } else if (devFlags & QEMU_PCI_CONNECT_TYPE_PCIE) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("PCI bus %.4x:%.2x is not compatible with the "
+ "device. Device requires a PCI Express slot, "
+ "which is not provided by this bus"),
+ addr->domain, addr->bus);
} else {
/* this should never happen. If it does, there is a
* bug in the code that sets the flag bits for devices.
bus->minSlot = 1;
bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+ /* slots 1 - 31, PCIe devices only, no hotplug */
+ bus->flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ bus->minSlot = 1;
+ bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid PCI controller model %d"), model);
continue;
switch (def->controllers[i]->model) {
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
- /* pci-root is implicit in the machine,
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+ /* pci-root and pcie-root are implicit in the machine,
* and needs no address */
continue;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE:
def->idx, def->idx);
break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("wrong function called for pci-root"));
+ _("wrong function called for pci-root/pcie-root"));
return NULL;
}
break;
continue;
}
- /* Skip pci-root */
+ /* Skip pci-root/pcie-root */
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
- cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
+ (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
+ cont->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
continue;
}
QEMU_PCI_CONNECT_TYPE_PCI = 1 << 2,
/* PCI devices can connect to this bus */
+ QEMU_PCI_CONNECT_TYPE_PCIE = 1 << 3,
+ /* PCI Express devices can connect to this bus */
} qemuDomainPCIConnectFlags;
/* a combination of all bit that describe the type of connections
* allowed, e.g. PCI, PCIe, switch
*/
# define QEMU_PCI_CONNECT_TYPES_MASK \
- QEMU_PCI_CONNECT_TYPE_PCI
+ (QEMU_PCI_CONNECT_TYPE_PCI | QEMU_PCI_CONNECT_TYPE_PCIE)
int qemuDomainAssignPCIAddresses(virDomainDefPtr def,
{
bool addDefaultUSB = true;
bool addPCIRoot = false;
+ bool addPCIeRoot = false;
/* check for emulator and create a default one if needed */
if (!def->emulator &&
case VIR_ARCH_X86_64:
if (!def->os.machine)
break;
- if (STRPREFIX(def->os.machine, "pc-q35") ||
- STREQ(def->os.machine, "q35") ||
- STREQ(def->os.machine, "isapc")) {
+ if (STREQ(def->os.machine, "isapc")) {
addDefaultUSB = false;
break;
}
+ if (STRPREFIX(def->os.machine, "pc-q35") ||
+ STREQ(def->os.machine, "q35")) {
+ addPCIeRoot = true;
+ addDefaultUSB = false;
+ break;
+ }
if (!STRPREFIX(def->os.machine, "pc-0.") &&
!STRPREFIX(def->os.machine, "pc-1.") &&
!STRPREFIX(def->os.machine, "pc-i440") &&
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
return -1;
+ if (addPCIeRoot &&
+ virDomainDefMaybeAddController(
+ def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
+ VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) < 0)
+ return -1;
+
return 0;
}
if (pci && pci->idx == 0 &&
pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
- VIR_DEBUG("Removing default 'pci-root' from domain '%s'"
+ VIR_DEBUG("Removing default pci-root from domain '%s'"
" for migration compatibility", def->name);
toremove++;
} else {
--- /dev/null
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/libexec/qemu-kvm \
+-S -M q35 -m 2048 -smp 2 -nographic -nodefaults \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c \
+-device pci-bridge,chassis_nr=1,id=pci.1,bus=pci.1,addr=0x1 -usb
--- /dev/null
+<domain type='qemu'>
+ <name>q35-test</name>
+ <uuid>11dbdcdd-4c3b-482b-8903-9bdb8c0a2774</uuid>
+ <memory unit='KiB'>2097152</memory>
+ <currentMemory unit='KiB'>2097152</currentMemory>
+ <vcpu placement='static' cpuset='0-1'>2</vcpu>
+ <os>
+ <type arch='x86_64' machine='q35'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/libexec/qemu-kvm</emulator>
+ <controller type='pci' index='0' model='pcie-root'/>
+ <controller type='usb' index='0'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
DO_TEST("pci-autoadd-idx", QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
DO_TEST("pci-bridge-many-disks",
QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
+ DO_TEST("pcie-root",
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE);
DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_DRIVE,
QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
DO_TEST_DIFFERENT("pci-bridge-many-disks");
DO_TEST_DIFFERENT("pci-autoadd-addr");
DO_TEST_DIFFERENT("pci-autoadd-idx");
+ DO_TEST("pcie-root");
DO_TEST("hostdev-scsi-lsi");
DO_TEST("hostdev-scsi-virtio-scsi");