mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-26 13:22:20 +00:00
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: Andrea Bolognani <abologna@redhat.com> Reviewed-by: Laine Stump <laine@laine.org>
This commit is contained in:
parent
47dd6e282a
commit
6e42d83f7c
@ -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'/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user