<p>
PCI controllers have an optional <code>model</code> attribute with
- possible values <code>pci-root</code>, <code>pcie-root</code>
- or <code>pci-bridge</code>.
+ possible values <code>pci-root</code>, <code>pcie-root</code>,
+ <code>pci-bridge</code>, or <code>dmi-to-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 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
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>).
+ devices. In order to connect standard PCI devices on a system
+ which has a pcie-root controller, a pci controller
+ with <code>model='dmi-to-pci-bridge'</code> is automatically
+ added. A dmi-to-pci-bridge controller plugs into a PCIe slot (as
+ provided by pcie-root), and itself provides 31 standard PCI
+ slots (which are not hot-pluggable). In order to have
+ hot-pluggable PCI slots in the guest system, a pci-bridge
+ controller will also be automatically created and connected to
+ one of the slots of the auto-created dmi-to-pci-bridge
+ controller; all guest devices with PCI addresses that are
+ auto-determined by libvirt will be placed on this pci-bridge
+ device. (<span class="since">since 1.1.2</span>).
</p>
<pre>
...
<devices>
<controller type='pci' index='0' model='pcie-root'/>
+ <controller type='pci' index='1' model='dmi-to-pci-bridge'>
+ <address type='pci' domain='0' bus='0' slot='0xe' function='0'/>
+ </controller>
+ <controller type='pci' index='2' model='pci-bridge'>
+ <address type='pci' domain='0' bus='1' slot='1' function='0'/>
+ </controller>
</devices>
...</pre>
<value>pci-root</value>
<value>pcie-root</value>
<value>pci-bridge</value>
+ <value>dmi-to-pci-bridge</value>
</choice>
</attribute>
</group>
VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST,
"pci-root",
"pcie-root",
- "pci-bridge")
+ "pci-bridge",
+ "dmi-to-pci-bridge")
VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST,
"auto",
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT,
VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT,
VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE,
+ VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE,
VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST
} virDomainControllerModelPCI;
"vnc-share-policy", /* 150 */
"device-del-event",
+ "dmi-to-pci-bridge",
);
struct _virQEMUCaps {
{ "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
{ "vfio-pci", QEMU_CAPS_DEVICE_VFIO_PCI },
{ "scsi-generic", QEMU_CAPS_DEVICE_SCSI_GENERIC },
+ { "i82801b11-bridge", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE },
};
static struct virQEMUCapsStringFlags virQEMUCapsObjectPropsVirtioBlk[] = {
QEMU_CAPS_MLOCK = 149, /* -realtime mlock=on|off */
QEMU_CAPS_VNC_SHARE_POLICY = 150, /* set display sharing policy */
QEMU_CAPS_DEVICE_DEL_EVENT = 151, /* DEVICE_DELETED event */
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE = 152, /* -device i82801b11-bridge */
QEMU_CAPS_LAST, /* this must always be the last item */
};
bus->minSlot = 1;
bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+ /* slots 1 - 31, standard PCI slots,
+ * but *not* hot-pluggable */
+ bus->flags = QEMU_PCI_CONNECT_TYPE_PCI;
+ bus->minSlot = 1;
+ bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
+ break;
default:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid PCI controller model %d"), model);
*/
flags = QEMU_PCI_CONNECT_TYPE_PCI;
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+ /* pci-bridge needs a PCIe slot, but it isn't
+ * hot-pluggable, so it doesn't need a hot-pluggable slot.
+ */
+ flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ break;
default:
break;
}
*/
flags = QEMU_PCI_CONNECT_TYPE_PCI;
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+ /* dmi-to-pci-bridge requires a non-hotplug PCIe
+ * slot
+ */
+ flags = QEMU_PCI_CONNECT_TYPE_PCIE;
+ break;
default:
flags = QEMU_PCI_CONNECT_HOTPLUGGABLE | QEMU_PCI_CONNECT_TYPE_PCI;
break;
virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d,id=pci.%d",
def->idx, def->idx);
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("The dmi-to-pci-bridge (i82801b11-bridge) "
+ "controller is not supported in this QEMU binary"));
+ goto error;
+ }
+ if (def->idx == 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("dmi-to-pci-bridge index should be > 0"));
+ goto error;
+ }
+ virBufferAsprintf(&buf, "i82801b11-bridge,id=pci.%d", def->idx);
+ break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
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)
+ /* When a machine has a pcie-root, make sure that there is always
+ * a dmi-to-pci-bridge controller added as bus 1, and a pci-bridge
+ * as bus 2, so that standard PCI devices can be connected
+ */
+ if (addPCIeRoot) {
+ if (virDomainDefMaybeAddController(
+ def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
+ VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT) < 0 ||
+ virDomainDefMaybeAddController(
+ def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 1,
+ VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE) < 0 ||
+ virDomainDefMaybeAddController(
+ def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 2,
+ VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE) < 0) {
return -1;
-
+ }
+ }
return 0;
}
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
+-device i82801b11-bridge,id=pci.1,bus=pci.0,addr=0x1 \
+-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 -usb
--- /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 i82801b11-bridge,id=pci.1,bus=pci.0,addr=0x1 \
+-device pci-bridge,chassis_nr=2,id=pci.2,bus=pci.1,addr=0x1 \
+-usb \
+-vga qxl -global qxl.ram_size=67108864 -global qxl.vram_size=18874368
--- /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='pci' index='1' model='dmi-to-pci-bridge'/>
+ <controller type='pci' index='2' model='pci-bridge'/>
+ <video>
+ <model type='qxl' ram='65536' vram='18432' heads='1'/>
+ </video>
+ <memballoon model='none'/>
+ </devices>
+</domain>
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);
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE);
+ DO_TEST("q35",
+ QEMU_CAPS_DEVICE, QEMU_CAPS_DEVICE_PCI_BRIDGE,
+ QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE,
+ QEMU_CAPS_VGA, QEMU_CAPS_DEVICE_VIDEO_PRIMARY,
+ QEMU_CAPS_VGA, QEMU_CAPS_VGA_QXL, QEMU_CAPS_DEVICE_QXL);
DO_TEST("hostdev-scsi-lsi", QEMU_CAPS_DRIVE,
QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
--- /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'/>
+ <controller type='pci' index='1' model='dmi-to-pci-bridge'/>
+ <controller type='pci' index='2' model='pci-bridge'/>
+ <memballoon model='none'/>
+ </devices>
+</domain>
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_DIFFERENT("pcie-root");
+ DO_TEST("q35");
DO_TEST("hostdev-scsi-lsi");
DO_TEST("hostdev-scsi-virtio-scsi");