On Wed, Jan 24, 2024 at 20:37:40 +0100, Andrea Bolognani wrote:
In addition to the code in qemuDomainControllerDefPostParse(),
which we have just factored into its own function, we also have
some code in qemuDomainDefAddDefaultDevices() that deals with
choosing the model for a USB controller, specifically for q35
guests. Integrate it into the newly-created function.
Since we want slightly different behaviors depending on whether
the USB controller that we're working on is the one that we try
to automatically add for certain new guests (addDefaultUSB),
introduce a new parameter to the function and a new possible
return value.
Signed-off-by: Andrea Bolognani <abologna(a)redhat.com>
---
src/qemu/qemu_domain.c | 74 ++++++++++++++++++++++++++++++++----------
1 file changed, 56 insertions(+), 18 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 09f572b0b5..d992b51877 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4151,9 +4151,35 @@ qemuDomainDefaultSCSIControllerModel(const virDomainDef *def,
}
+/**
+ * qemuDomainDefaultUSBControllerModel:
+ * @def: domain definition
+ * @cont: controller definition, or NULL
+ * @autoAdded: whether this controller is being automatically added
+ * @qemuCaps: QEMU capabilities, or NULL
+ * @parseFlags: parse flags
+ *
+ * Choose a reasonable model to use for a USB controller where a
+ * specific one hasn't been provided by the user.
+ *
+ * The choice is based on a number of factors, including the guest's
+ * architecture and machine type. @qemuCaps, if provided, might be
+ * taken into consideration too.
+ *
+ * @autoAdded should be true is this is a controller that libvirt is
+ * trying to automatically add on domain creation for the user's
+ * convenience: in that case, the function might decide to simply not
+ * add the controller instead of reporting a failure.
+ *
+ * Returns: >=0 (a virDomainControllerModelUSB value) on success,
+ * -1 on error, and
This is NOT an error and is misrepresenting the _DEFAULT case which has
-1, which is also a success case at least in some situations.
+ * -2 if no suitable model could be found but it's
okay to
+ * just skip the controller altogether.
IMO this should be VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE and not a new
arbitrary value. I also don't think that this function needs to know
whether the controller was auto-added, or not
+ */
static int
qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
const virDomainControllerDef *cont,
+ bool autoAdded,
virQEMUCaps *qemuCaps,
unsigned int parseFlags)
{
@@ -4169,7 +4195,7 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
* See qemuBuildControllersCommandLine() */
if (ARCH_IS_S390(def->os.arch)) {
- if (cont->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) {
+ if (cont && cont->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE)
{
/* set the default USB model to none for s390 unless an
* address is found */
return VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
@@ -4198,6 +4224,22 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
}
+ if (ARCH_IS_X86(def->os.arch)) {
+ if (qemuDomainIsQ35(def) && autoAdded) {
+ /* Prefer adding a USB3 controller if supported, fall back
+ * to USB2 if there is no USB3 available, and if that's
+ * unavailable don't add anything.
+ */
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
+ return VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+ return VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
+ return VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
+ return -2;
+ }
+ }
+
/* Default USB controller is piix3-uhci if available. */
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI))
return VIR_DOMAIN_CONTROLLER_MODEL_USB_PIIX3_UHCI;
@@ -4209,7 +4251,8 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
static int
qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
virDomainDef *def,
- virQEMUCaps *qemuCaps)
+ virQEMUCaps *qemuCaps,
+ unsigned int parseFlags)
{
bool addDefaultUSB = false;
int usbModel = -1; /* "default for machinetype" */
@@ -4243,20 +4286,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
addPCIeRoot = true;
addImplicitSATA = true;
addITCOWatchdog = true;
-
- /* Prefer adding a USB3 controller if supported, fall back
- * to USB2 if there is no USB3 available, and if that's
- * unavailable don't add anything.
- */
- if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_QEMU_XHCI))
- usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
- else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
- usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
- else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
- usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
- else
- addDefaultUSB = false;
- break;
}
if (qemuDomainIsI440FX(def))
addPCIRoot = true;
@@ -4348,6 +4377,15 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
break;
}
+ if (addDefaultUSB) {
+ usbModel = qemuDomainDefaultUSBControllerModel(def, NULL, true, qemuCaps,
parseFlags);
+ /* A return value of -2 indicates that no reasonable default
+ * could be figured out, and that we should handle that by
+ * not adding the USB controller */
+ if (usbModel == -2)
+ addDefaultUSB = false;
+ }
+
if (addDefaultUSB &&
virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_USB, 0) < 0
&&
virDomainDefAddUSBController(def, 0, usbModel) < 0)
@@ -5091,7 +5129,7 @@ qemuDomainDefPostParse(virDomainDef *def,
if (qemuDomainDefBootPostParse(def, driver, parseFlags) < 0)
return -1;
- if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps) < 0)
+ if (qemuDomainDefAddDefaultDevices(driver, def, qemuCaps, parseFlags) < 0)
return -1;
if (qemuDomainDefSetDefaultCPU(def, driver->hostarch, qemuCaps) < 0)
@@ -5695,7 +5733,7 @@ qemuDomainControllerDefPostParse(virDomainControllerDef *cont,
case VIR_DOMAIN_CONTROLLER_TYPE_USB:
if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT &&
qemuCaps) {
- cont->model = qemuDomainDefaultUSBControllerModel(def, cont, qemuCaps,
parseFlags);
+ cont->model = qemuDomainDefaultUSBControllerModel(def, cont, false,
qemuCaps, parseFlags);
The code can check here explicitly whether _NONE was returned and
report appropriate error.
}
/* forbid usb model 'qusb1' and 'qusb2' in this kind of
hyperviosr */
if (cont->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_QUSB1 ||
--
2.43.0
_______________________________________________
Devel mailing list -- devel(a)lists.libvirt.org
ws> To unsubscribe send an email
to devel-leave(a)lists.libvirt.org