982648
From 03831cca9544d9b6489f09f0f87f94a2d676829c Mon Sep 17 00:00:00 2001
982648
Message-Id: <03831cca9544d9b6489f09f0f87f94a2d676829c@dist-git>
982648
From: Erik Skultety <eskultet@redhat.com>
982648
Date: Mon, 20 Aug 2018 17:18:52 +0200
982648
Subject: [PATCH] qemu: Fix probing of AMD SEV support
982648
MIME-Version: 1.0
982648
Content-Type: text/plain; charset=UTF-8
982648
Content-Transfer-Encoding: 8bit
982648
982648
So the procedure to detect SEV support works like this:
982648
1) we detect that sev-guest is among the QOM types and set the cap flag
982648
2) we probe the monitor for SEV support
982648
    - this is tricky, because QEMU with compiled SEV support will always
982648
    report -object sev-guest and query-sev-capabilities command, that
982648
    however doesn't mean SEV is supported
982648
3) depending on what the monitor returned, we either keep or clear the
982648
capability flag for SEV
982648
982648
Commit a349c6c21c6 added an explicit check for "GenericError" in the
982648
monitor reply to prevent libvirtd to spam logs about missing
982648
'query-sev-capabilities' command. At the same time though, it returned
982648
success in this case which means that we didn't clear the capability
982648
flag afterwards and happily formatted SEV into qemuCaps. Therefore,
982648
adjust all the relevant callers to handle -1 on errors, 0 on SEV being
982648
unsupported and 1 on SEV being supported.
982648
982648
Signed-off-by: Erik Skultety <eskultet@redhat.com>
982648
Acked-by: Peter Krempa <pkrempa@redhat.com>
982648
(cherry picked from commit 764491c9dddf063292adf1433769ccccb1a50db6)
982648
982648
https://bugzilla.redhat.com/show_bug.cgi?id=1612009
982648
https://bugzilla.redhat.com/show_bug.cgi?id=1619150
982648
982648
Signed-off-by: Erik Skultety <eskultet@redhat.com>
982648
Reviewed-by: Ján Tomko <jtomko@redhat.com>
982648
---
982648
 src/qemu/qemu_capabilities.c                  | 15 ++++++++++----
982648
 src/qemu/qemu_monitor_json.c                  | 20 +++++++++++++++----
982648
 .../caps_3.0.0.x86_64.xml                     |  1 -
982648
 3 files changed, 27 insertions(+), 9 deletions(-)
982648
982648
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
982648
index d1e4fafe7d..470f25a5a6 100644
982648
--- a/src/qemu/qemu_capabilities.c
982648
+++ b/src/qemu/qemu_capabilities.c
982648
@@ -2696,18 +2696,20 @@ virQEMUCapsProbeQMPGICCapabilities(virQEMUCapsPtr qemuCaps,
982648
 }
982648
 
982648
 
982648
+/* Returns -1 on error, 0 if SEV is not supported, 1 if SEV is supported */
982648
 static int
982648
 virQEMUCapsProbeQMPSEVCapabilities(virQEMUCapsPtr qemuCaps,
982648
                                    qemuMonitorPtr mon)
982648
 {
982648
+    int rc = -1;
982648
     virSEVCapability *caps = NULL;
982648
 
982648
-    if (qemuMonitorGetSEVCapabilities(mon, &caps) < 0)
982648
-        return -1;
982648
+    if ((rc = qemuMonitorGetSEVCapabilities(mon, &caps)) <= 0)
982648
+        return rc;
982648
 
982648
     virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
982648
     qemuCaps->sevCapabilities = caps;
982648
-    return 0;
982648
+    return rc;
982648
 }
982648
 
982648
 
982648
@@ -4120,7 +4122,12 @@ virQEMUCapsInitQMPMonitor(virQEMUCapsPtr qemuCaps,
982648
 
982648
     /* Probe for SEV capabilities */
982648
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SEV_GUEST)) {
982648
-        if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0)
982648
+        int rc = virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon);
982648
+
982648
+        if (rc < 0)
982648
+            goto cleanup;
982648
+
982648
+        if (rc == 0)
982648
             virQEMUCapsClear(qemuCaps, QEMU_CAPS_SEV_GUEST);
982648
     }
982648
 
982648
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
982648
index b226a47cc9..8970d95584 100644
982648
--- a/src/qemu/qemu_monitor_json.c
982648
+++ b/src/qemu/qemu_monitor_json.c
982648
@@ -6562,6 +6562,20 @@ qemuMonitorJSONGetGICCapabilities(qemuMonitorPtr mon,
982648
 }
982648
 
982648
 
982648
+/**
982648
+ * qemuMonitorJSONGetSEVCapabilities:
982648
+ * @mon: qemu monitor object
982648
+ * @capabilities: pointer to pointer to a SEV capability structure to be filled
982648
+ *
982648
+ * This function queries and fills in AMD's SEV platform-specific data.
982648
+ * Note that from QEMU's POV both -object sev-guest and query-sev-capabilities
982648
+ * can be present even if SEV is not available, which basically leaves us with
982648
+ * checking for JSON "GenericError" in order to differentiate between
982648
+ * compiled-in support and actual SEV support on the platform.
982648
+ *
982648
+ * Returns -1 on error, 0 if SEV is not supported, and 1 if SEV is supported on
982648
+ * the platform.
982648
+ */
982648
 int
982648
 qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon,
982648
                                   virSEVCapability **capabilities)
982648
@@ -6583,8 +6597,7 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon,
982648
     if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
982648
         goto cleanup;
982648
 
982648
-    /* Both -object sev-guest and query-sev-capabilities can be present
982648
-     * even if SEV is not available */
982648
+    /* QEMU has only compiled-in support of SEV */
982648
     if (qemuMonitorJSONHasError(reply, "GenericError")) {
982648
         ret = 0;
982648
         goto cleanup;
982648
@@ -6636,8 +6649,7 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitorPtr mon,
982648
     capability->cbitpos = cbitpos;
982648
     capability->reduced_phys_bits = reduced_phys_bits;
982648
     VIR_STEAL_PTR(*capabilities, capability);
982648
-    ret = 0;
982648
-
982648
+    ret = 1;
982648
  cleanup:
982648
     virSEVCapabilitiesFree(capability);
982648
     virJSONValueFree(cmd);
982648
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
982648
index 4bc7cfeebc..8992d645e7 100644
982648
--- a/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
982648
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml
982648
@@ -212,7 +212,6 @@
982648
   <flag name='tpm-emulator'/>
982648
   <flag name='mch'/>
982648
   <flag name='mch.extended-tseg-mbytes'/>
982648
-  <flag name='sev-guest'/>
982648
   <flag name='usb-storage.werror'/>
982648
   <flag name='egl-headless'/>
982648
   <flag name='vfio-pci.display'/>
982648
-- 
982648
2.18.0
982648