提交 6e42d83f 编写于 作者: A Andrea Bolognani

qemu: Automatically pick target index and model for pci-root controllers

pSeries guests will soon need the new information; luckily,
we can figure it out automatically most of the time, so
users won't have to worry about it.
Signed-off-by: NAndrea Bolognani <abologna@redhat.com>
Reviewed-by: NLaine Stump <laine@laine.org>
上级 47dd6e28
......@@ -1899,6 +1899,37 @@ void virDomainControllerDefFree(virDomainControllerDefPtr def)
VIR_FREE(def);
}
/**
* virDomainControllerIsPCIHostBridge:
* @cont: controller
*
* Checks whether @cont is a PCI Host Bridge (PHB), a specific type
* of PCI controller used by pSeries guests.
*
* Returns: true if @cont is a PHB, false otherwise.
*/
bool
virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont)
{
virDomainControllerPCIModelName name;
/* PHBs are pci-root controllers */
if (cont->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI ||
cont->model != VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
return false;
}
name = cont->opts.pciopts.modelName;
/* The actual device used for PHBs is spapr-pci-host-bridge */
if (name != VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE)
return false;
return true;
}
virDomainFSDefPtr
virDomainFSDefNew(void)
{
......
......@@ -2678,10 +2678,12 @@ int virDomainDeviceFindControllerModel(const virDomainDef *def,
virDomainDiskDefPtr virDomainDiskFindByBusAndDst(virDomainDefPtr def,
int bus,
char *dst);
virDomainControllerDefPtr virDomainControllerDefNew(virDomainControllerType type);
void virDomainControllerDefFree(virDomainControllerDefPtr def);
bool virDomainControllerIsPCIHostBridge(const virDomainControllerDef *cont);
virDomainFSDefPtr virDomainFSDefNew(void);
virDomainControllerDefPtr
virDomainControllerDefNew(virDomainControllerType type);
void virDomainFSDefFree(virDomainFSDefPtr def);
void virDomainActualNetDefFree(virDomainActualNetDefPtr def);
void virDomainNetDefClear(virDomainNetDefPtr def);
......
......@@ -226,6 +226,7 @@ virDomainControllerFindByType;
virDomainControllerFindUnusedIndex;
virDomainControllerInsert;
virDomainControllerInsertPreAlloced;
virDomainControllerIsPCIHostBridge;
virDomainControllerModelPCITypeToString;
virDomainControllerModelSCSITypeFromString;
virDomainControllerModelSCSITypeToString;
......
......@@ -1848,6 +1848,7 @@ qemuDomainSupportsPCI(virDomainDefPtr def,
static void
qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
virDomainDefPtr def,
virQEMUCapsPtr qemuCaps)
{
int *modelName = &cont->opts.pciopts.modelName;
......@@ -1884,6 +1885,9 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
*modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_PXB_PCIE;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
if (qemuDomainIsPSeries(def))
*modelName = VIR_DOMAIN_CONTROLLER_PCI_MODEL_NAME_SPAPR_PCI_HOST_BRIDGE;
break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
break;
......@@ -1891,6 +1895,54 @@ qemuDomainPCIControllerSetDefaultModelName(virDomainControllerDefPtr cont,
}
/**
* qemuDomainAddressFindNewTargetIndex:
* @def: domain definition
*
* Find a target index that can be used for a PCI controller.
*
* Returns: an unused target index, or -1 if all available target
* indexes are already taken.
*/
static int
qemuDomainAddressFindNewTargetIndex(virDomainDefPtr def)
{
int targetIndex;
int ret = -1;
/* Try all indexes between 1 and 31 - QEMU only supports 32
* PHBs, and 0 is reserved for the default, implicit one */
for (targetIndex = 1; targetIndex <= 31; targetIndex++) {
bool found = false;
size_t i;
for (i = 0; i < def->ncontrollers; i++) {
virDomainControllerDefPtr cont = def->controllers[i];
/* Skip everything but PHBs */
if (!virDomainControllerIsPCIHostBridge(cont))
continue;
/* Stop looking as soon as we find a PHB that's
* already using this specific target index */
if (cont->opts.pciopts.targetIndex == targetIndex) {
found = true;
break;
}
}
/* If no existing PCI controller uses this index, great,
* it means it's free and we can return it to the caller */
if (!found) {
ret = targetIndex;
break;
}
}
return ret;
}
static int
qemuDomainAddressFindNewBusNr(virDomainDefPtr def)
{
......@@ -2151,7 +2203,7 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
* device in qemu) for any controller that doesn't yet
* have it set.
*/
qemuDomainPCIControllerSetDefaultModelName(cont, qemuCaps);
qemuDomainPCIControllerSetDefaultModelName(cont, def, qemuCaps);
/* set defaults for any other auto-generated config
* options for this controller that haven't been
......@@ -2188,9 +2240,32 @@ qemuDomainAssignPCIAddresses(virDomainDefPtr def,
goto cleanup;
}
break;
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
if (!qemuDomainIsPSeries(def))
break;
if (options->targetIndex == -1) {
if (cont->idx == 0) {
/* The pci-root controller with controller index 0
* must always be assigned target index 0, because
* it represents the implicit PHB which is treated
* differently than all other PHBs */
options->targetIndex = 0;
} else {
/* For all other PHBs the target index doesn't need
* to match the controller index or have any
* particular value, really */
options->targetIndex = qemuDomainAddressFindNewTargetIndex(def);
}
}
if (options->targetIndex == -1) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("No usable target index found for %d"),
addr->bus);
goto cleanup;
}
break;
case VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE:
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_SWITCH_UPSTREAM_PORT:
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT:
case VIR_DOMAIN_CONTROLLER_MODEL_PCIE_ROOT:
case VIR_DOMAIN_CONTROLLER_MODEL_PCI_LAST:
break;
......
......@@ -30,7 +30,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<controller type='scsi' index='0'>
<address type='spapr-vio' reg='0x2000'/>
</controller>
......
......@@ -17,7 +17,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<memballoon model='none'/>
<nvram>
<address type='spapr-vio' reg='0x4000'/>
......
......@@ -17,7 +17,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<serial type='pty'>
<target port='0'/>
<address type='spapr-vio' reg='0x30000000'/>
......
......@@ -22,7 +22,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</memballoon>
......
......@@ -22,7 +22,10 @@
<controller type='usb' index='0' model='pci-ohci'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<memballoon model='virtio'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</memballoon>
......
......@@ -17,7 +17,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<memballoon model='none'/>
<nvram>
<address type='spapr-vio' reg='0x4000'/>
......
......@@ -17,7 +17,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<serial type='pty'>
<target port='0'/>
<address type='spapr-vio' reg='0x30000000'/>
......
......@@ -17,7 +17,10 @@
<controller type='usb' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0'/>
</controller>
<controller type='pci' index='0' model='pci-root'/>
<controller type='pci' index='0' model='pci-root'>
<model name='spapr-pci-host-bridge'/>
<target index='0'/>
</controller>
<serial type='pty'>
<target port='0'/>
<address type='spapr-vio' reg='0x30000000'/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册