]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Enable KVM when probing capabilities
authorJiri Denemark <jdenemar@redhat.com>
Fri, 10 Jun 2016 15:16:21 +0000 (17:16 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 25 Nov 2016 19:34:26 +0000 (20:34 +0100)
CPU related capabilities may differ depending on accelerator used when
probing. Let's use KVM if available when probing QEMU and fall back to
TCG. The created capabilities already contain all we need to distinguish
whether KVM or TCG was used:

    - KVM was used when probing capabilities:
        QEMU_CAPS_KVM is set
        QEMU_CAPS_ENABLE_KVM is not set

    - TCG was used and QEMU supports KVM, but it failed (e.g., missing
      kernel module or wrong /dev/kvm permissions)
        QEMU_CAPS_KVM is not set
        QEMU_CAPS_ENABLE_KVM is set

    - KVM was not used and QEMU does not support it
        QEMU_CAPS_KVM is not set
        QEMU_CAPS_ENABLE_KVM is not set

Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
src/qemu/qemu_capabilities.c
src/qemu/qemu_capabilities.h
src/qemu/qemu_capspriv.h
tests/qemucapabilitiestest.c

index f224bad63209497fa83636a3197393ad9d0cc872..3d62fc520f0837a73e6d7776df5edecb8089e4a2 100644 (file)
@@ -4028,6 +4028,25 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
 }
 
 
+int
+virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps ATTRIBUTE_UNUSED,
+                             qemuMonitorPtr mon)
+{
+    int ret = -1;
+
+    if (qemuMonitorSetCapabilities(mon) < 0) {
+        VIR_DEBUG("Failed to set monitor capabilities %s",
+                  virGetLastErrorMessage());
+        ret = 0;
+        goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+
 typedef struct _virQEMUCapsInitQMPCommand virQEMUCapsInitQMPCommand;
 typedef virQEMUCapsInitQMPCommand *virQEMUCapsInitQMPCommandPtr;
 struct _virQEMUCapsInitQMPCommand {
@@ -4151,13 +4170,21 @@ virQEMUCapsInitQMPCommandNew(char *binary,
  *          1 when probing QEMU failed
  */
 static int
-virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd)
+virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd,
+                             bool forceTCG)
 {
     virDomainXMLOptionPtr xmlopt = NULL;
+    const char *machine;
     int status = 0;
     int ret = -1;
 
-    VIR_DEBUG("Try to probe capabilities of '%s' via QMP", cmd->binary);
+    if (forceTCG)
+        machine = "none,accel=tcg";
+    else
+        machine = "none,accel=kvm:tcg";
+
+    VIR_DEBUG("Try to probe capabilities of '%s' via QMP, machine %s",
+              cmd->binary, machine);
 
     /*
      * We explicitly need to use -daemonize here, rather than
@@ -4171,7 +4198,7 @@ virQEMUCapsInitQMPCommandRun(virQEMUCapsInitQMPCommandPtr cmd)
                                     "-no-user-config",
                                     "-nodefaults",
                                     "-nographic",
-                                    "-machine", "none",
+                                    "-machine", machine,
                                     "-qmp", cmd->monarg,
                                     "-pidfile", cmd->pidfile,
                                     "-daemonize",
@@ -4240,7 +4267,7 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
                                              runUid, runGid, qmperr)))
         goto cleanup;
 
-    if ((rc = virQEMUCapsInitQMPCommandRun(cmd)) != 0) {
+    if ((rc = virQEMUCapsInitQMPCommandRun(cmd, false)) != 0) {
         if (rc == 1)
             ret = 0;
         goto cleanup;
@@ -4249,6 +4276,18 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
     if (virQEMUCapsInitQMPMonitor(qemuCaps, cmd->mon) < 0)
         goto cleanup;
 
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM)) {
+        virQEMUCapsInitQMPCommandAbort(cmd);
+        if ((rc = virQEMUCapsInitQMPCommandRun(cmd, true)) != 0) {
+            if (rc == 1)
+                ret = 0;
+            goto cleanup;
+        }
+
+        if (virQEMUCapsInitQMPMonitorTCG(qemuCaps, cmd->mon) < 0)
+            goto cleanup;
+    }
+
     ret = 0;
 
  cleanup:
index 5255815876dee7467c7de667b9cf2cffac430ff9..cfd00663bf0d0a30c59e767fa7c720bc634eb323 100644 (file)
@@ -400,9 +400,6 @@ typedef virQEMUCapsCache *virQEMUCapsCachePtr;
 
 virQEMUCapsPtr virQEMUCapsNew(void);
 
-int virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
-                              qemuMonitorPtr mon);
-
 int virQEMUCapsProbeQMP(virQEMUCapsPtr qemuCaps,
                         qemuMonitorPtr mon);
 
index f8ee47efdf7e7c0b0b26147a7bec2d30d011f48f..38b971e0e0b849250eaa69504af287656dfd7126 100644 (file)
@@ -57,6 +57,14 @@ char *virQEMUCapsFormatCache(virQEMUCapsPtr qemuCaps,
                              time_t selfCTime,
                              unsigned long selfVersion);
 
+int
+virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
+                          qemuMonitorPtr mon);
+
+int
+virQEMUCapsInitQMPMonitorTCG(virQEMUCapsPtr qemuCaps,
+                             qemuMonitorPtr mon);
+
 void
 virQEMUCapsSetArch(virQEMUCapsPtr qemuCaps,
                    virArch arch);
index 10cfa437683d95ffd7ff66e53c554769c8d34117..fe41fc496bf05e0b8a1716c0053a97d878727090 100644 (file)
@@ -61,6 +61,11 @@ testQemuCaps(const void *opaque)
                                   qemuMonitorTestGetMonitor(mon)) < 0)
         goto cleanup;
 
+    if (virQEMUCapsGet(capsActual, QEMU_CAPS_KVM) &&
+        virQEMUCapsInitQMPMonitorTCG(capsActual,
+                                     qemuMonitorTestGetMonitor(mon)) < 0)
+        goto cleanup;
+
     if (!(actual = virQEMUCapsFormatCache(capsActual, 0, 0)))
         goto cleanup;