[PATCH v2 29/38] qemu: Add qemuDomainDefaultUSBControllerModelAutoAdded()

Andrea Bolognani via Devel posted 38 patches 1 week, 2 days ago
[PATCH v2 29/38] qemu: Add qemuDomainDefaultUSBControllerModelAutoAdded()
Posted by Andrea Bolognani via Devel 1 week, 2 days ago
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 USB controller model for a couple of specific
machine types.

Once again, extract the logic to a dedicated helper. The
behavior is unchanged.

Signed-off-by: Andrea Bolognani <abologna@redhat.com>
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
---
 src/qemu/qemu_domain.c    | 58 +++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h    |  2 ++
 src/qemu/qemu_postparse.c | 27 +++++++-----------
 3 files changed, 70 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e4816c78e0..f60156895a 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -4377,6 +4377,64 @@ qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
 }
 
 
+/**
+ * qemuDomainDefaultUSBControllerModelAutoAdded:
+ * @def: domain definition
+ * @qemuCaps: QEMU capabilities, or NULL
+ *
+ * Choose a reasonable model to use for a USB controller that is
+ * being automatically added to a domain.
+ *
+ * The choice is based on a number of factors, including the guest's
+ * architecture and machine type. @qemuCaps might be NULL, in which
+ * case the function must not make any decision based on device
+ * availability; it will be re-run later with a non-NULL qemuCaps.
+ *
+ * The return value can be a specific controller model, or
+ * VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT; the latter indicates that
+ * no suitable model could be identified. How to behave in that
+ * scenario is entirely up to the caller.
+ *
+ * Additionally, VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE can be returned
+ * to indicate that the caller should not auto-add the USB controller
+ * after all.
+ *
+ * Returns: the model
+ */
+virDomainControllerModelUSB
+qemuDomainDefaultUSBControllerModelAutoAdded(const virDomainDef *def,
+                                             virQEMUCaps *qemuCaps)
+{
+    virDomainControllerModelUSB model = VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
+
+    if (ARCH_IS_X86(def->os.arch)) {
+        if (qemuDomainIsQ35(def)) {
+            /* 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))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_QEMU_XHCI;
+            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NEC_USB_XHCI))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NEC_XHCI;
+            else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ICH9_USB_EHCI1))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_ICH9_EHCI1;
+            else
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE;
+        }
+    }
+
+    if (ARCH_IS_ARM(def->os.arch)) {
+        if (STREQ(def->os.machine, "versatilepb") ||
+            STRPREFIX(def->os.machine, "realview-eb"))
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
+                model = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
+    }
+
+    return model;
+}
+
+
 /**
  * qemuDomainDefNumaCPUsRectify:
  * @numa: pointer to numa definition
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index bdcfcc6e86..5ccd3b2dbb 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -845,6 +845,8 @@ virDomainControllerModelSCSI qemuDomainDefaultSCSIControllerModel(const virDomai
 virDomainControllerModelUSB qemuDomainDefaultUSBControllerModel(const virDomainDef *def,
                                                                 virQEMUCaps *qemuCaps,
                                                                 unsigned int parseFlags);
+virDomainControllerModelUSB qemuDomainDefaultUSBControllerModelAutoAdded(const virDomainDef *def,
+                                                                         virQEMUCaps *qemuCaps);
 
 int qemuDomainDefAddDefaultAudioBackend(virQEMUDriver *driver,
                                         virDomainDef *def);
diff --git a/src/qemu/qemu_postparse.c b/src/qemu/qemu_postparse.c
index 895dfa2625..e5a0913111 100644
--- a/src/qemu/qemu_postparse.c
+++ b/src/qemu/qemu_postparse.c
@@ -1189,7 +1189,7 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
                                virQEMUCaps *qemuCaps)
 {
     bool addDefaultUSB = false;
-    int usbModel = -1; /* "default for machinetype" */
+    virDomainControllerModelUSB usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT;
     int pciRoot;       /* index within def->controllers */
     bool addImplicitSATA = false;
     bool addPCIRoot = false;
@@ -1224,20 +1224,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
             if (virDomainDefGetVcpusMax(def) > QEMU_MAX_VCPUS_WITHOUT_EIM) {
                 addIOMMU = 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;
@@ -1253,8 +1239,6 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
             STRPREFIX(def->os.machine, "realview-eb")) {
             addPCIRoot = true;
             addDefaultUSB = true;
-            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_OHCI))
-                usbModel = VIR_DOMAIN_CONTROLLER_MODEL_USB_PCI_OHCI;
         }
 
         if (qemuDomainIsARMVirt(def))
@@ -1363,6 +1347,15 @@ qemuDomainDefAddDefaultDevices(virQEMUDriver *driver,
         return -1;
     }
 
+    if (addDefaultUSB && usbModel == VIR_DOMAIN_CONTROLLER_MODEL_USB_DEFAULT) {
+        usbModel = qemuDomainDefaultUSBControllerModelAutoAdded(def, qemuCaps);
+
+        /* If no reasonable model can be figured out, we should
+         * simply not add the default USB controller */
+        if (usbModel == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE)
+            addDefaultUSB = false;
+    }
+
     if (addDefaultUSB && virDomainControllerFind(def, VIR_DOMAIN_CONTROLLER_TYPE_USB, 0) < 0)
         virDomainDefAddUSBController(def, 0, usbModel);
 
-- 
2.51.0