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