This controller is implicit on q35 machinetypes. It provides 31 PCIe
(*not* PCI) slots as controller 0.
Currently there are no devices that can connect to pcie-root. For a
usable q35 system, we still need to add a "dmi-to-pci-bridge" pci
controller, which can connect to pcie-root, and provides pci slots.
This patch still requires a test case, which willbe coming up, but I
wanted to include it along with the previous patch to show that it's
simpler to add new controller types now.
---
docs/formatdomain.html.in | 17 ++++++++++++++---
src/conf/domain_conf.c | 4 +++-
src/conf/domain_conf.h | 1 +
src/qemu/qemu_command.c | 17 +++++++++++++----
src/qemu/qemu_command.h | 2 ++
src/qemu/qemu_domain.c | 23 +++++++++++++++++------
6 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 7601aaa..41e3e2a 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2338,10 +2338,14 @@
<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-root has no address.
+ For machine types which provide an implicit PCI Express (PCIe)
+ bus, the pcie-root controller with index=0 is auto-added and
+ required to use PCIe devices. pcie-root has also 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.
@@ -2361,6 +2365,13 @@
</devices>
...</pre>
+<pre>
+ ...
+ <devices>
+ <controller type='pci' index='0'
model='pcie-root'/>
+ </devices>
+ ...</pre>
+
<h4><a name="elementsLease">Device leases</a></h4>
<p>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 10cb7f6..605f706 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -310,6 +310,7 @@ VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
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,
@@ -5715,9 +5716,10 @@ virDomainControllerDefParseXML(xmlNodePtr node,
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;
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index abf024c..68f36fd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -768,6 +768,7 @@ enum virDomainControllerType {
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
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 64787b6..7fccb98 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1519,6 +1519,12 @@ qemuDomainPCIAddressBusSetModel(qemuDomainPCIAddressBusPtr bus,
bus->minSlot = 1;
bus->maxSlot = QEMU_PCI_ADDRESS_SLOT_LAST;
break;
+ case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
+ bus->flags = (QEMU_PCI_CONNECT_HOTPLUGGABLE |
+ 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);
@@ -2277,7 +2283,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def,
/* PCI controllers */
for (i = 0; i < def->ncontrollers; i++) {
if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_PCI) {
- if (def->controllers[i]->model ==
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT)
+ if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT
||
+ def->controllers[i]->model ==
VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)
continue;
if (def->controllers[i]->info.type !=
VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
continue;
@@ -4211,8 +4218,9 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
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;
@@ -7490,9 +7498,10 @@ qemuBuildCommandLine(virConnectPtr conn,
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;
}
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index ede67fe..a4574f2 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -233,6 +233,8 @@ typedef enum {
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
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index da3b768..34fed56 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -700,6 +700,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
void *opaque ATTRIBUTE_UNUSED)
{
bool addPCIRoot = false;
+ bool addPCIeRoot = false;
/* check for emulator and create a default one if needed */
if (!def->emulator &&
@@ -712,10 +713,13 @@ qemuDomainDefPostParse(virDomainDefPtr def,
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"))
break;
+ if (STRPREFIX(def->os.machine, "pc-q35") ||
+ STREQ(def->os.machine, "q35")) {
+ addPCIeRoot = true;
+ break;
+ }
if (!STRPREFIX(def->os.machine, "pc-0.") &&
!STRPREFIX(def->os.machine, "pc-1.") &&
!STRPREFIX(def->os.machine, "pc-i440") &&
@@ -743,6 +747,12 @@ qemuDomainDefPostParse(virDomainDefPtr def,
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;
}
@@ -1408,9 +1418,10 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
}
if (pci && pci->idx == 0 &&
- pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
- VIR_DEBUG("Removing default 'pci-root' from domain
'%s'"
- " for migration compatibility", def->name);
+ (pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT ||
+ pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT)) {
+ VIR_DEBUG("Removing default pci-root/pcie-root controller from "
+ "domain '%s' for migration compatibility",
def->name);
toremove++;
} else {
pci = NULL;
--
1.7.11.7