From 542f05e7756cc5614eb2ee7b0bac9aabb7aa016c Mon Sep 17 00:00:00 2001 From: Andrea Bolognani Date: Thu, 11 Jan 2018 17:28:43 +0100 Subject: [PATCH] qemu: Implement pcie-to-pci-bridge controller The new controller will not yet be used automatically by libvirt, but at this point it's already possible to configure a guest to use it. Signed-off-by: Andrea Bolognani Reviewed-by: John Ferlan --- docs/formatdomain.html.in | 4 ++++ docs/schemas/domaincommon.rng | 3 +++ src/conf/domain_addr.c | 25 ++++++++++++++++++++----- src/conf/domain_addr.h | 4 +++- src/conf/domain_conf.c | 3 +++ src/conf/domain_conf.h | 2 ++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 17 +++++++++++++++++ src/qemu/qemu_domain_address.c | 4 ++++ 9 files changed, 57 insertions(+), 6 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index e4524b525b..84059737d5 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -3956,6 +3956,10 @@ pci-expander-bus, pcie-expander-bus (since 1.3.4) +
  • + pcie-to-pci-bridge + (since 4.3.0) +
  • The root controllers (pci-root diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index a72c9190d2..4cab55f05d 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2102,6 +2102,8 @@ pci-bridge i82801b11-bridge + + pcie-pci-bridge ioh3420 pcie-root-port @@ -2172,6 +2174,7 @@ pci-bridge dmi-to-pci-bridge + pcie-to-pci-bridge pcie-root-port pcie-switch-upstream-port pcie-switch-downstream-port diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 182ee9de5f..8065853f03 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -62,6 +62,9 @@ virDomainPCIControllerModelToConnectType(virDomainControllerModelPCI model) case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: return VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: + return VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: return VIR_PCI_CONNECT_TYPE_PCIE_ROOT_PORT | VIR_PCI_CONNECT_AGGREGATE_SLOT; @@ -160,6 +163,8 @@ virDomainPCIAddressFlagsCompatible(virPCIDeviceAddressPtr addr, connectStr = "pci-switch-downstream-port"; } else if (devFlags & VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE) { connectStr = "dmi-to-pci-bridge"; + } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE) { + connectStr = "pcie-to-pci-bridge"; } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS) { connectStr = "pci-expander-bus"; } else if (devFlags & VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS) { @@ -316,14 +321,24 @@ virDomainPCIAddressBusSetModel(virDomainPCIAddressBusPtr bus, bus->minSlot = 0; bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: + /* Same as pci-bridge: 32 hotpluggable traditional PCI slots (0-31), + * the first of which is not usable because of the SHPC */ + bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | + VIR_PCI_CONNECT_TYPE_PCI_DEVICE | + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE); + bus->minSlot = 1; + bus->maxSlot = VIR_PCI_ADDRESS_SLOT_LAST; + break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: /* provides one slot which is pcie, can be used by endpoint - * devices and pcie-switch-upstream-ports, and is hotpluggable - */ - bus->flags = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE - | VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT - | VIR_PCI_CONNECT_HOTPLUGGABLE; + * devices, pcie-switch-upstream-ports or pcie-to-pci-bridges, + * and is hotpluggable */ + bus->flags = (VIR_PCI_CONNECT_HOTPLUGGABLE | + VIR_PCI_CONNECT_TYPE_PCIE_DEVICE | + VIR_PCI_CONNECT_TYPE_PCIE_SWITCH_UPSTREAM_PORT | + VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE); bus->minSlot = 0; bus->maxSlot = 0; break; diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 87986c2bb7..87248a4fb8 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -49,6 +49,7 @@ typedef enum { VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS = 1 << 8, VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS = 1 << 9, VIR_PCI_CONNECT_TYPE_PCI_BRIDGE = 1 << 10, + VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE = 1 << 11, } virDomainPCIConnectFlags; /* a combination of all bits that describe the type of connections @@ -62,7 +63,8 @@ typedef enum { VIR_PCI_CONNECT_TYPE_DMI_TO_PCI_BRIDGE | \ VIR_PCI_CONNECT_TYPE_PCI_EXPANDER_BUS | \ VIR_PCI_CONNECT_TYPE_PCIE_EXPANDER_BUS | \ - VIR_PCI_CONNECT_TYPE_PCI_BRIDGE) + VIR_PCI_CONNECT_TYPE_PCI_BRIDGE | \ + VIR_PCI_CONNECT_TYPE_PCIE_TO_PCI_BRIDGE) /* combination of all bits that could be used to connect a normal * endpoint device (i.e. excluding the connection possible between an diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index ef16431aaf..aacd06a87a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -335,6 +335,7 @@ VIR_ENUM_IMPL(virDomainControllerModelPCI, VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST, "pcie-root", "pci-bridge", "dmi-to-pci-bridge", + "pcie-to-pci-bridge", "pcie-root-port", "pcie-switch-upstream-port", "pcie-switch-downstream-port", @@ -353,6 +354,7 @@ VIR_ENUM_IMPL(virDomainControllerPCIModelName, "pxb-pcie", "pcie-root-port", "spapr-pci-host-bridge", + "pcie-pci-bridge", ); VIR_ENUM_IMPL(virDomainControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, @@ -10188,6 +10190,7 @@ virDomainControllerDefParseXML(virDomainXMLOptionPtr xmlopt, } case VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index bd17bd99ae..68473c309e 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -690,6 +690,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT, VIR_DOMAIN_CONTROLLER_MODEL_PCI_BRIDGE, VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE, + VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE, VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT, VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT, VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT, @@ -710,6 +711,7 @@ typedef enum { VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_ROOT_PORT, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE, + VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE, VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST } virDomainControllerPCIModelName; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index bbd3cd0a7d..514c3ab2ef 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2795,6 +2795,7 @@ qemuBuildControllerDevStr(const virDomainDef *domainDef, break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: virBufferAsprintf(&buf, "%s,id=%s", modelName, def->info.alias); break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 9d1c33b54a..f03aa03e8a 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -4400,6 +4400,8 @@ virDomainControllerPCIModelNameToQEMUCaps(int modelName) return QEMU_CAPS_DEVICE_PCIE_ROOT_PORT; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE: return QEMU_CAPS_DEVICE_SPAPR_PCI_HOST_BRIDGE; + case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE: + return QEMU_CAPS_DEVICE_PCIE_PCI_BRIDGE; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE: return 0; case VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_LAST: @@ -4457,6 +4459,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: /* modelName should have been set automatically */ if (pciopts->modelName == VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_NONE) { virReportControllerMissingOption(cont, model, modelName, "modelName"); @@ -4561,6 +4564,13 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, } break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: + if (pciopts->modelName != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE) { + virReportControllerInvalidValue(cont, model, modelName, "modelName"); + return -1; + } + break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST: default: @@ -4577,6 +4587,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (cont->idx == 0) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Index for '%s' controllers must be > 0"), @@ -4638,6 +4649,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->targetIndex != -1) { virReportControllerInvalidOption(cont, model, modelName, "targetIndex"); return -1; @@ -4671,6 +4683,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->pcihole64 || pciopts->pcihole64size != 0) { virReportControllerInvalidOption(cont, model, modelName, "pcihole64"); @@ -4702,6 +4715,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->busNr != -1) { virReportControllerInvalidOption(cont, model, modelName, "busNr"); return -1; @@ -4746,6 +4760,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_DOWNSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->numaNode != -1) { virReportControllerInvalidOption(cont, model, modelName, "numaNode"); return -1; @@ -4776,6 +4791,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->chassisNr != -1) { virReportControllerInvalidOption(cont, model, modelName, "chassisNr"); return -1; @@ -4810,6 +4826,7 @@ qemuDomainDeviceDefValidateControllerPCI(const virDomainControllerDef *cont, case VIR_DOMAIN_CONTROLLER_MODEL_PCI_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_EXPANDER_BUS: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: if (pciopts->chassis != -1) { virReportControllerInvalidOption(cont, model, modelName, "chassis"); return -1; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 40fb540adc..86d9807908 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -2171,6 +2171,9 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont, case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_I82801B11_BRIDGE; break; + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: + *modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PCIE_PCI_BRIDGE; + break; case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT_PORT: /* Use generic PCIe Root Ports if available, falling back to * ioh3420 otherwise */ @@ -2582,6 +2585,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def, } break; case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE: + case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_TO_PCI_BRIDGE: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT: case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT: case VIR_DOMAIN_CONTROLLER_MODEL_PCI_DEFAULT: -- GitLab