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>
---
src/conf/domain_capabilities.h | 8 +++
src/qemu/qemu_monitor.c | 10 ++++
src/qemu/qemu_monitor.h | 3 +
src/qemu/qemu_monitor_json.c | 104 ++++++++++++++++++++++++++++++---
src/qemu/qemu_monitor_json.h | 9 +++
5 files changed, 127 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index f2eed80b15..21736ad1ac 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -192,6 +192,13 @@ struct _virSEVCapability {
unsigned int max_es_guests;
};
+typedef struct _virSGXCapability virSGXCapability;
+typedef virSGXCapability *virSGXCapabilityPtr;
+struct _virSGXCapability {
+ bool flc;
+ unsigned int epc_size;
+};
+
typedef enum {
VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0,
VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO,
@@ -228,6 +235,7 @@ struct _virDomainCaps {
virDomainCapsFeatureGIC gic;
virSEVCapability *sev;
+ virSGXCapability *sgx;
/* add new domain features here */
virTristateBool features[VIR_DOMAIN_CAPS_FEATURE_LAST];
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index d44c7f0c60..6b82e8c853 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3648,6 +3648,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 b1484fdff8..ed87185e5d 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -900,6 +900,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 a092bf420f..38c3d018f3 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6433,6 +6433,69 @@ 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;
+ virJSONValue *caps;
+ bool flc = false;
+ unsigned int section_size = 0;
+ g_autoptr(virSGXCapability) capability = NULL;
+
+ *capabilities = NULL;
+
+ 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", &flc) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing 'flc'
field"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetNumberUint(caps, "section-size",
§ion_size) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-sgx-capabilities reply was missing
'section-size' field"));
+ return -1;
+ }
+
+ capability = g_new0(virSGXCapability, 1);
+ capability->flc = flc;
+ capability->epc_size = section_size/1024;
+
+ *capabilities = g_steal_pointer(&capability);
+ return 1;
+}
+
static virJSONValue *
qemuMonitorJSONBuildInetSocketAddress(const char *host,
const char *port)
@@ -7469,13 +7532,25 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
return -1;
}
- /* While 'id' attribute is marked as optional in QEMU's QAPI
- * specification, Libvirt always sets it. Thus we can fail if not
- * present. */
- if (!(devalias = virJSONValueObjectGetString(dimminfo, "id"))) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("dimm memory info data is missing
'id'"));
- return -1;
+ if (STREQ(type, "dimm") || STREQ(type, "nvdimm") ||
STREQ(type, "virtio-mem")) {
+ /* While 'id' attribute is marked as optional in QEMU's QAPI
+ * specification, Libvirt always sets it. Thus we can fail if not
+ * present. */
+ if (!(devalias = virJSONValueObjectGetString(dimminfo, "id"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("dimm memory info data is missing
'id'"));
+ return -1;
+ }
+ } else if (STREQ(type, "sgx-epc")) {
+ if (!(devalias = virJSONValueObjectGetString(dimminfo, "memdev")))
{
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("sgx-epc memory info data is missing
'memdev'"));
+ return -1;
+ }
+ } else {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("%s memory device info is not handled yet"), type);
+ return -1;
}
meminfo = g_new0(qemuMonitorMemoryDeviceInfo, 1);
@@ -7519,6 +7594,21 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
_("malformed/missing size in virtio memory
info"));
return -1;
}
+ } else if (STREQ(type, "sgx-epc")) {
+ /* sgx-epc memory devices */
+ if (virJSONValueObjectGetNumberUlong(dimminfo, "memaddr",
+ &meminfo->address) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed/missing memaddr in sgx-epc memory
info"));
+ return -1;
+ }
+
+ if (virJSONValueObjectGetNumberUlong(dimminfo, "size",
+ &meminfo->size) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("malformed/missing size in sgx-epc memory
info"));
+ return -1;
+ }
} else {
/* type not handled yet */
continue;
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 3c442d669f..dbe772c3f7 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -255,6 +255,15 @@ qemuMonitorJSONAddFileHandleToSet(qemuMonitor *mon,
int fdset,
const char *opaque);
+int qemuMonitorJSONGetSGXCapabilities(qemuMonitor *mon,
+ virSGXCapability **capabilities);
+
+int qemuMonitorJSONMigrate(qemuMonitor *mon,
+ unsigned int flags,
+ const char *uri);
+int qemuMonitorJSONGetSpiceMigrationStatus(qemuMonitor *mon,
+ bool *spice_migrated);
+
int
qemuMonitorJSONRemoveFdset(qemuMonitor *mon,
unsigned int fdset);
--
2.25.1