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