qemuDomainValidateDevicePCISlotsQ35 is renamed to virDomainValidateDevicePCISlotsQ35 and moved from qemu_domain_addr.c to domain_addr.c All these functions are being moved because they don't depend on qemu, so they have the potential to be reused for more hypervisors. --- src/conf/domain_addr.c | 191 ++++++++++++++++++++++++++++++++++++++++ src/conf/domain_addr.h | 6 ++ src/libvirt_private.syms | 1 + src/qemu/qemu_domain_address.c | 193 +---------------------------------------- 4 files changed, 199 insertions(+), 192 deletions(-) diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c index 17b60e4..aecad04 100644 --- a/src/conf/domain_addr.c +++ b/src/conf/domain_addr.c @@ -1521,3 +1521,194 @@ virDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr def, VIR_FREE(addrStr); return ret; } + + +int +virDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, + virDomainPCIAddressSetPtr addrs, + bool videoPrimaryEnabled) +{ + int ret = -1; + size_t i; + virPCIDeviceAddress tmp_addr; + char *addrStr = NULL; + virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; + + for (i = 0; i < def->ncontrollers; i++) { + switch (def->controllers[i]->type) { + case VIR_DOMAIN_CONTROLLER_TYPE_SATA: + /* Verify that the first SATA controller is at 00:1F.2 the + * q35 machine type *always* has a SATA controller at this + * address. + */ + if (def->controllers[i]->idx == 0) { + if (virDeviceInfoPCIAddressPresent(&def->controllers[i]->info)) { + if (def->controllers[i]->info.addr.pci.domain != 0 || + def->controllers[i]->info.addr.pci.bus != 0 || + def->controllers[i]->info.addr.pci.slot != 0x1F || + def->controllers[i]->info.addr.pci.function != 2) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Primary SATA controller must have PCI address 0:0:1f.2")); + goto cleanup; + } + } else { + def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + def->controllers[i]->info.addr.pci.domain = 0; + def->controllers[i]->info.addr.pci.bus = 0; + def->controllers[i]->info.addr.pci.slot = 0x1F; + def->controllers[i]->info.addr.pci.function = 2; + } + } + break; + + case VIR_DOMAIN_CONTROLLER_TYPE_USB: + if ((def->controllers[i]->model + == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1) && + (def->controllers[i]->info.type + == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) { + /* Try to assign the first found USB2 controller to + * 00:1D.0 and 2nd to 00:1A.0 (because that is their + * standard location on real Q35 hardware) unless they + * are already taken, but don't insist on it. + * + * (NB: all other controllers at the same index will + * get assigned to the same slot as the UHCI1 when + * addresses are later assigned to all devices.) + */ + bool assign = false; + + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 0x1D; + if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + assign = true; + } else { + tmp_addr.slot = 0x1A; + if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) + assign = true; + } + if (assign) { + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, + flags, false, true) < 0) + goto cleanup; + def->controllers[i]->info.type + = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + def->controllers[i]->info.addr.pci.domain = 0; + def->controllers[i]->info.addr.pci.bus = 0; + def->controllers[i]->info.addr.pci.slot = tmp_addr.slot; + def->controllers[i]->info.addr.pci.function = 0; + def->controllers[i]->info.addr.pci.multi + = VIR_TRISTATE_SWITCH_ON; + } + } + break; + + case VIR_DOMAIN_CONTROLLER_TYPE_PCI: + if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE && + def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + /* Try to assign this bridge to 00:1E.0 (because that + * is its standard location on real hardware) unless + * it's already taken, but don't insist on it. + */ + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 0x1E; + if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, + flags, true, false) < 0) + goto cleanup; + def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + def->controllers[i]->info.addr.pci.domain = 0; + def->controllers[i]->info.addr.pci.bus = 0; + def->controllers[i]->info.addr.pci.slot = 0x1E; + def->controllers[i]->info.addr.pci.function = 0; + } + } + break; + } + } + + /* Reserve slot 0x1F function 0 (ISA bridge, not in config model) + * and function 3 (SMBus, also not (yet) in config model). As with + * the SATA controller, these devices are always present in a q35 + * machine; there is no way to not have them. + */ + if (addrs->nbuses) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 0x1F; + tmp_addr.function = 0; + tmp_addr.multi = VIR_TRISTATE_SWITCH_ON; + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, + false, false) < 0) + goto cleanup; + tmp_addr.function = 3; + tmp_addr.multi = VIR_TRISTATE_SWITCH_ABSENT; + if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, + false, false) < 0) + goto cleanup; + } + + if (def->nvideos > 0) { + /* NB: unlike the pc machinetypes, on q35 machinetypes the + * integrated devices are at slot 0x1f, so when qemu looks for + * the first free lot for the first VGA, it will always be at + * slot 1 (which was used up by the integrated PIIX3 devices + * on pc machinetypes). + */ + virDomainVideoDefPtr primaryVideo = def->videos[0]; + if (virDeviceInfoPCIAddressWanted(&primaryVideo->info)) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 1; + + if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr))) + goto cleanup; + if (!virDomainPCIAddressValidate(addrs, &tmp_addr, + addrStr, flags, false)) + goto cleanup; + + if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + if (videoPrimaryEnabled) { + if (virDomainPCIAddressReserveNextSlot(addrs, + &primaryVideo->info, + flags) < 0) + goto cleanup; + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("PCI address 0:0:1.0 is in use, " + "QEMU needs it for primary video")); + goto cleanup; + } + } else { + if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) + goto cleanup; + primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; + primaryVideo->info.addr.pci = tmp_addr; + } + } else if (!videoPrimaryEnabled) { + if (primaryVideo->info.addr.pci.domain != 0 || + primaryVideo->info.addr.pci.bus != 0 || + primaryVideo->info.addr.pci.slot != 1 || + primaryVideo->info.addr.pci.function != 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Primary video card must have PCI address 0:0:1.0")); + goto cleanup; + } + /* If TYPE == PCI, then virDomainCollectPCIAddress() function + * has already reserved the address, so we must skip */ + } + } else if (addrs->nbuses && !videoPrimaryEnabled) { + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_addr.slot = 1; + + if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { + VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video" + " device will not be possible without manual" + " intervention"); + virResetLastError(); + } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) { + goto cleanup; + } + } + ret = 0; + cleanup: + VIR_FREE(addrStr); + return ret; +} diff --git a/src/conf/domain_addr.h b/src/conf/domain_addr.h index 0995e7b..55c4e83 100644 --- a/src/conf/domain_addr.h +++ b/src/conf/domain_addr.h @@ -250,6 +250,12 @@ virDomainValidateDevicePCISlotsPIIX3(virDomainDefPtr def, bool videoPrimaryEnabled) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); +int +virDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, + virDomainPCIAddressSetPtr addrs, + bool videoPrimaryEnabled) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + #endif /* __DOMAIN_ADDR_H__ */ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index c154a83..89c1710 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -110,6 +110,7 @@ virDomainPCIAddressSlotInUse; virDomainPCIAddressValidate; virDomainPCIControllerModelToConnectType; virDomainValidateDevicePCISlotsPIIX3; +virDomainValidateDevicePCISlotsQ35; virDomainVirtioSerialAddrAssign; virDomainVirtioSerialAddrAutoAssign; virDomainVirtioSerialAddrIsComplete; diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index abf1a26..dcdd4e2 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -419,197 +419,6 @@ qemuDomainPCIAddressSetCreate(virDomainDefPtr def, static int -qemuDomainValidateDevicePCISlotsQ35(virDomainDefPtr def, - virDomainPCIAddressSetPtr addrs, - bool videoPrimaryEnabled) -{ - int ret = -1; - size_t i; - virPCIDeviceAddress tmp_addr; - char *addrStr = NULL; - virDomainPCIConnectFlags flags = VIR_PCI_CONNECT_TYPE_PCIE_DEVICE; - - for (i = 0; i < def->ncontrollers; i++) { - switch (def->controllers[i]->type) { - case VIR_DOMAIN_CONTROLLER_TYPE_SATA: - /* Verify that the first SATA controller is at 00:1F.2 the - * q35 machine type *always* has a SATA controller at this - * address. - */ - if (def->controllers[i]->idx == 0) { - if (virDeviceInfoPCIAddressPresent(&def->controllers[i]->info)) { - if (def->controllers[i]->info.addr.pci.domain != 0 || - def->controllers[i]->info.addr.pci.bus != 0 || - def->controllers[i]->info.addr.pci.slot != 0x1F || - def->controllers[i]->info.addr.pci.function != 2) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Primary SATA controller must have PCI address 0:0:1f.2")); - goto cleanup; - } - } else { - def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - def->controllers[i]->info.addr.pci.domain = 0; - def->controllers[i]->info.addr.pci.bus = 0; - def->controllers[i]->info.addr.pci.slot = 0x1F; - def->controllers[i]->info.addr.pci.function = 2; - } - } - break; - - case VIR_DOMAIN_CONTROLLER_TYPE_USB: - if ((def->controllers[i]->model - == VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_UHCI1) && - (def->controllers[i]->info.type - == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)) { - /* Try to assign the first found USB2 controller to - * 00:1D.0 and 2nd to 00:1A.0 (because that is their - * standard location on real Q35 hardware) unless they - * are already taken, but don't insist on it. - * - * (NB: all other controllers at the same index will - * get assigned to the same slot as the UHCI1 when - * addresses are later assigned to all devices.) - */ - bool assign = false; - - memset(&tmp_addr, 0, sizeof(tmp_addr)); - tmp_addr.slot = 0x1D; - if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { - assign = true; - } else { - tmp_addr.slot = 0x1A; - if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) - assign = true; - } - if (assign) { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, - flags, false, true) < 0) - goto cleanup; - def->controllers[i]->info.type - = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - def->controllers[i]->info.addr.pci.domain = 0; - def->controllers[i]->info.addr.pci.bus = 0; - def->controllers[i]->info.addr.pci.slot = tmp_addr.slot; - def->controllers[i]->info.addr.pci.function = 0; - def->controllers[i]->info.addr.pci.multi - = VIR_TRISTATE_SWITCH_ON; - } - } - break; - - case VIR_DOMAIN_CONTROLLER_TYPE_PCI: - if (def->controllers[i]->model == VIR_DOMAIN_CONTROLLER_MODEL_DMI_TO_PCI_BRIDGE && - def->controllers[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - /* Try to assign this bridge to 00:1E.0 (because that - * is its standard location on real hardware) unless - * it's already taken, but don't insist on it. - */ - memset(&tmp_addr, 0, sizeof(tmp_addr)); - tmp_addr.slot = 0x1E; - if (!virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, - flags, true, false) < 0) - goto cleanup; - def->controllers[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - def->controllers[i]->info.addr.pci.domain = 0; - def->controllers[i]->info.addr.pci.bus = 0; - def->controllers[i]->info.addr.pci.slot = 0x1E; - def->controllers[i]->info.addr.pci.function = 0; - } - } - break; - } - } - - /* Reserve slot 0x1F function 0 (ISA bridge, not in config model) - * and function 3 (SMBus, also not (yet) in config model). As with - * the SATA controller, these devices are always present in a q35 - * machine; there is no way to not have them. - */ - if (addrs->nbuses) { - memset(&tmp_addr, 0, sizeof(tmp_addr)); - tmp_addr.slot = 0x1F; - tmp_addr.function = 0; - tmp_addr.multi = VIR_TRISTATE_SWITCH_ON; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, - false, false) < 0) - goto cleanup; - tmp_addr.function = 3; - tmp_addr.multi = VIR_TRISTATE_SWITCH_ABSENT; - if (virDomainPCIAddressReserveAddr(addrs, &tmp_addr, flags, - false, false) < 0) - goto cleanup; - } - - if (def->nvideos > 0) { - /* NB: unlike the pc machinetypes, on q35 machinetypes the - * integrated devices are at slot 0x1f, so when qemu looks for - * the first free lot for the first VGA, it will always be at - * slot 1 (which was used up by the integrated PIIX3 devices - * on pc machinetypes). - */ - virDomainVideoDefPtr primaryVideo = def->videos[0]; - if (virDeviceInfoPCIAddressWanted(&primaryVideo->info)) { - memset(&tmp_addr, 0, sizeof(tmp_addr)); - tmp_addr.slot = 1; - - if (!(addrStr = virDomainPCIAddressAsString(&tmp_addr))) - goto cleanup; - if (!virDomainPCIAddressValidate(addrs, &tmp_addr, - addrStr, flags, false)) - goto cleanup; - - if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { - if (videoPrimaryEnabled) { - if (virDomainPCIAddressReserveNextSlot(addrs, - &primaryVideo->info, - flags) < 0) - goto cleanup; - } else { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("PCI address 0:0:1.0 is in use, " - "QEMU needs it for primary video")); - goto cleanup; - } - } else { - if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) - goto cleanup; - primaryVideo->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; - primaryVideo->info.addr.pci = tmp_addr; - } - } else if (!videoPrimaryEnabled) { - if (primaryVideo->info.addr.pci.domain != 0 || - primaryVideo->info.addr.pci.bus != 0 || - primaryVideo->info.addr.pci.slot != 1 || - primaryVideo->info.addr.pci.function != 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("Primary video card must have PCI address 0:0:1.0")); - goto cleanup; - } - /* If TYPE == PCI, then virDomainCollectPCIAddress() function - * has already reserved the address, so we must skip */ - } - } else if (addrs->nbuses && !videoPrimaryEnabled) { - memset(&tmp_addr, 0, sizeof(tmp_addr)); - tmp_addr.slot = 1; - - if (virDomainPCIAddressSlotInUse(addrs, &tmp_addr)) { - VIR_DEBUG("PCI address 0:0:1.0 in use, future addition of a video" - " device will not be possible without manual" - " intervention"); - virResetLastError(); - } else if (virDomainPCIAddressReserveSlot(addrs, &tmp_addr, flags) < 0) { - goto cleanup; - } - } - ret = 0; - cleanup: - VIR_FREE(addrStr); - return ret; -} - - -static int qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, virDomainPCIAddressSetPtr addrs, bool videoPrimaryEnabled) @@ -620,7 +429,7 @@ qemuDomainValidateDevicePCISlotsChipsets(virDomainDefPtr def, } if (virDomainMachineIsQ35(def) && - qemuDomainValidateDevicePCISlotsQ35(def, addrs, videoPrimaryEnabled) < 0) { + virDomainValidateDevicePCISlotsQ35(def, addrs, videoPrimaryEnabled) < 0) { return -1; } -- 2.7.4 (Apple Git-66) -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list