Blame SOURCES/libvirt-qemu-Forbid-config-when-topology-based-cpu-count-doesn-t-match-the-config.patch

6ae9ed
From c2cacc36d72728ed214e92928535611f79515695 Mon Sep 17 00:00:00 2001
6ae9ed
Message-Id: <c2cacc36d72728ed214e92928535611f79515695@dist-git>
6ae9ed
From: Peter Krempa <pkrempa@redhat.com>
6ae9ed
Date: Wed, 24 Aug 2016 16:11:20 -0400
6ae9ed
Subject: [PATCH] qemu: Forbid config when topology based cpu count doesn't
6ae9ed
 match the config
6ae9ed
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1097930
6ae9ed
https://bugzilla.redhat.com/show_bug.cgi?id=1224341
6ae9ed
6ae9ed
As of qemu commit:
6ae9ed
commit a32ef3bfc12c8d0588f43f74dcc5280885bbdb30
6ae9ed
Author: Thomas Huth <thuth@redhat.com>
6ae9ed
Date:   Wed Jul 22 15:59:50 2015 +0200
6ae9ed
6ae9ed
    vl: Add another sanity check to smp_parse() function
6ae9ed
6ae9ed
v2.4.0-952-ga32ef3b
6ae9ed
6ae9ed
configuration where the maximum CPU count doesn't match the topology is
6ae9ed
rejected. Prior to that only configurations where the topology would
6ae9ed
contain more cpus than the maximum count would be rejected.
6ae9ed
6ae9ed
Use QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS as a relevant recent enough
6ae9ed
witness to avoid breaking old configs.
6ae9ed
6ae9ed
(cherry picked from commit ffa536e0f885783b1577cf1378629980104ea946)
6ae9ed
---
6ae9ed
 src/qemu/qemu_domain.c | 38 ++++++++++++++++++++++++++++++++------
6ae9ed
 1 file changed, 32 insertions(+), 6 deletions(-)
6ae9ed
6ae9ed
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
6ae9ed
index 52e9c1e..be602ef 100644
6ae9ed
--- a/src/qemu/qemu_domain.c
6ae9ed
+++ b/src/qemu/qemu_domain.c
6ae9ed
@@ -2308,12 +2308,21 @@ qemuDomainDefPostParse(virDomainDefPtr def,
6ae9ed
 static int
6ae9ed
 qemuDomainDefValidate(const virDomainDef *def,
6ae9ed
                       virCapsPtr caps ATTRIBUTE_UNUSED,
6ae9ed
-                      void *opaque ATTRIBUTE_UNUSED)
6ae9ed
+                      void *opaque)
6ae9ed
 {
6ae9ed
+    virQEMUDriverPtr driver = opaque;
6ae9ed
+    virQEMUCapsPtr qemuCaps = NULL;
6ae9ed
+    size_t topologycpus;
6ae9ed
+    int ret = -1;
6ae9ed
+
6ae9ed
+    if (!(qemuCaps = virQEMUCapsCacheLookup(driver->qemuCapsCache,
6ae9ed
+                                            def->emulator)))
6ae9ed
+        goto cleanup;
6ae9ed
+
6ae9ed
     if (def->mem.min_guarantee) {
6ae9ed
         virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
                        _("Parameter 'min_guarantee' not supported by QEMU."));
6ae9ed
-        return -1;
6ae9ed
+        goto cleanup;
6ae9ed
     }
6ae9ed
 
6ae9ed
     if (def->os.loader &&
6ae9ed
@@ -2324,7 +2333,7 @@ qemuDomainDefValidate(const virDomainDef *def,
6ae9ed
         if (!qemuDomainMachineIsQ35(def)) {
6ae9ed
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
                            _("Secure boot is supported with q35 machine types only"));
6ae9ed
-            return -1;
6ae9ed
+            goto cleanup;
6ae9ed
         }
6ae9ed
 
6ae9ed
         /* Now, technically it is possible to have secure boot on
6ae9ed
@@ -2333,17 +2342,34 @@ qemuDomainDefValidate(const virDomainDef *def,
6ae9ed
         if (def->os.arch != VIR_ARCH_X86_64) {
6ae9ed
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
                            _("Secure boot is supported for x86_64 architecture only"));
6ae9ed
-            return -1;
6ae9ed
+            goto cleanup;
6ae9ed
         }
6ae9ed
 
6ae9ed
         if (def->features[VIR_DOMAIN_FEATURE_SMM] != VIR_TRISTATE_SWITCH_ON) {
6ae9ed
             virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
                            _("Secure boot requires SMM feature enabled"));
6ae9ed
-            return -1;
6ae9ed
+            goto cleanup;
6ae9ed
         }
6ae9ed
     }
6ae9ed
 
6ae9ed
-    return 0;
6ae9ed
+    /* qemu as of 2.5.0 rejects SMP topologies that don't match the cpu count */
6ae9ed
+    if (def->cpu && def->cpu->sockets) {
6ae9ed
+        topologycpus = def->cpu->sockets * def->cpu->cores * def->cpu->threads;
6ae9ed
+        if (topologycpus != virDomainDefGetVcpusMax(def)) {
6ae9ed
+            /* presence of query-hotpluggable-cpus should be a good enough witness */
6ae9ed
+            if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_QUERY_HOTPLUGGABLE_CPUS)) {
6ae9ed
+                virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
6ae9ed
+                               _("CPU topology doesn't match maximum vcpu count"));
6ae9ed
+                goto cleanup;
6ae9ed
+            }
6ae9ed
+        }
6ae9ed
+    }
6ae9ed
+
6ae9ed
+    ret = 0;
6ae9ed
+
6ae9ed
+ cleanup:
6ae9ed
+    virObjectUnref(qemuCaps);
6ae9ed
+    return ret;
6ae9ed
 }
6ae9ed
 
6ae9ed
 
6ae9ed
-- 
6ae9ed
2.10.0
6ae9ed