From: Haibin Huang <haibin.huang(a)intel.com>
Generate the QMP command for query-sgx-capabilities and the command
return SGX capabilities from QMP.
{"execute":"query-sgx-capabilities"}
the right reply:
{"return":
{
"sgx": true,
"section-size": 197132288,
"flc": true
}
}
the error reply:
{"error":
{"class": "GenericError", "desc": "SGX is not
enabled in KVM"}
}
Signed-off-by: Haibin Huang <haibin.huang(a)intel.com>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
Signed-off-by: Haibin Huang <haibin.huang(a)intel.com>
---
src/qemu/qemu_monitor.c | 10 ++++
src/qemu/qemu_monitor.h | 3 ++
src/qemu/qemu_monitor_json.c | 96 ++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 4 ++
4 files changed, 113 insertions(+)
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 4739810c9b..75b7638faa 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3418,6 +3418,16 @@ qemuMonitorGetSEVCapabilities(qemuMonitor *mon,
}
+int
+qemuMonitorGetSGXCapabilities(qemuMonitor *mon,
+ virSGXCapability **capabilities)
+{
+ QEMU_CHECK_MONITOR(mon);
+
+ return qemuMonitorJSONGetSGXCapabilities(mon, capabilities);
+}
+
+
int
qemuMonitorNBDServerStart(qemuMonitor *mon,
const virStorageNetHostDef *server,
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 78e2ebf0bd..d806d3ecbc 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -824,6 +824,9 @@ int qemuMonitorGetGICCapabilities(qemuMonitor *mon,
int qemuMonitorGetSEVCapabilities(qemuMonitor *mon,
virSEVCapability **capabilities);
+int qemuMonitorGetSGXCapabilities(qemuMonitor *mon,
+ virSGXCapability **capabilities);
+
typedef enum {
QEMU_MONITOR_MIGRATE_BACKGROUND = 1 << 0,
QEMU_MONITOR_MIGRATE_NON_SHARED_DISK = 1 << 1, /* migration with non-shared
storage with full disk copy */
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index d664e827dd..cf279e98ed 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6032,6 +6032,102 @@ qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
return 1;
}
+
+/**
+ * qemuMonitorJSONGetSGXCapabilities:
+ * @mon: qemu monitor object
+ * @capabilities: pointer to pointer to a SGX capability structure to be filled
+ *
+ * This function queries and fills in INTEL's SGX platform-specific data.
+ * Note that from QEMU's POV both -object sgx-epc and query-sgx-capabilities
+ * can be present even if SGX is not available, which basically leaves us with
+ * checking for JSON "GenericError" in order to differentiate between
compiled-in
+ * support and actual SGX support on the platform.
+ *
+ * Returns: -1 on error,
+ * 0 if SGX is not supported, and
+ * 1 if SGX is supported on the platform.
+ */
+int
+qemuMonitorJSONGetSGXCapabilities(qemuMonitor *mon,
+ virSGXCapability **capabilities)
+{
+ g_autoptr(virJSONValue) cmd = NULL;
+ g_autoptr(virJSONValue) reply = NULL;
+ g_autoptr(virSGXCapability) capability = NULL;
+ virJSONValue *sgxSections = NULL;
+ virJSONValue *caps;
+ size_t i;
+
+ *capabilities = NULL;
+ capability = g_new0(virSGXCapability, 1);
+
+ if (!(cmd = qemuMonitorJSONMakeCommand("query-sgx-capabilities", NULL)))
+ return -1;
+
+ if (qemuMonitorJSONCommand(mon, cmd, &reply) < 0)
+ return -1;
+
+ /* QEMU has only compiled-in support of SGX */
+ if (qemuMonitorJSONHasError(reply, "GenericError"))
+ return 0;
+
+ if (qemuMonitorJSONCheckError(cmd, reply) < 0)
+ return -1;
+
+ caps = virJSONValueObjectGetObject(reply, "return");
+
+ if (virJSONValueObjectGetBoolean(caps, "flc", &capability->flc) <
0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing 'flc'
field"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetBoolean(caps, "sgx1", &capability->sgx1)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing 'sgx1'
field"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetBoolean(caps, "sgx2", &capability->sgx2)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing 'sgx2'
field"));
+ return -1;
+ }
+
+ if ((sgxSections = virJSONValueObjectGetArray(caps, "sections"))) {
+ unsigned long long size;
+
+ /* Got the section, the QEMU version is above 7.0.0 */
+ capability->nSgxSections = virJSONValueArraySize(sgxSections);
+ capability->sgxSections = g_new0(virSGXSection, capability->nSgxSections);
+
+ for (i = 0; i < capability->nSgxSections; i++) {
+ virJSONValue *elem = virJSONValueArrayGet(sgxSections, i);
+
+ if (virJSONValueObjectGetNumberUlong(elem, "size", &size) <
0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing
'size' field"));
+ return -1;
+ }
+ capability->sgxSections[i].size = size / 1024;
+
+ if (virJSONValueObjectGetNumberUint(elem, "node",
+ &capability->sgxSections[i].node)
< 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing
'node' field"));
+ return -1;
+ }
+ }
+ } else {
+ return 0;
+ }
+
+ *capabilities = g_steal_pointer(&capability);
+ return 1;
+}
+
+
static virJSONValue *
qemuMonitorJSONBuildInetSocketAddress(const char *host,
const char *port)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 5154c195c9..2b4fe6e064 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -161,6 +161,10 @@ int
qemuMonitorJSONGetGICCapabilities(qemuMonitor *mon,
virGICCapability **capabilities);
+int
+qemuMonitorJSONGetSGXCapabilities(qemuMonitor *mon,
+ virSGXCapability **capabilities);
+
int
qemuMonitorJSONGetSEVCapabilities(qemuMonitor *mon,
virSEVCapability **capabilities);
--
2.25.1