[libvirt][PATCH v11 1/4] qemu: provide support to query the SGX capability

Lin Yang lin.a.yang at intel.com
Wed May 11 06:11:09 UTC 2022


From: Haibin Huang <haibin.huang at intel.com>

QEMU version >= 6.2.0 provides support for creating enclave on
SGX x86 platform using Software Guard Extensions (SGX) feature.
This patch adds support to query the SGX capability from the qemu.

Signed-off-by: Haibin Huang <haibin.huang at intel.com>
---
 src/conf/domain_capabilities.c                |  10 ++
 src/conf/domain_capabilities.h                |  13 ++
 src/libvirt_private.syms                      |   1 +
 src/qemu/qemu_capabilities.c                  | 119 ++++++++++++++++++
 src/qemu/qemu_capabilities.h                  |   6 +
 src/qemu/qemu_capspriv.h                      |   4 +
 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 ++
 .../caps_6.2.0.x86_64.replies                 |  22 +++-
 .../caps_6.2.0.x86_64.xml                     |   5 +
 .../caps_7.0.0.x86_64.replies                 |  22 +++-
 .../caps_7.0.0.x86_64.xml                     |   5 +
 14 files changed, 318 insertions(+), 15 deletions(-)

diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 2a888da1a9..d0e863c5cb 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -78,6 +78,16 @@ virSEVCapabilitiesFree(virSEVCapability *cap)
 }
 
 
+void
+virSGXCapabilitiesFree(virSGXCapability *cap)
+{
+    if (!cap)
+        return;
+
+    VIR_FREE(cap);
+}
+
+
 static void
 virDomainCapsDispose(void *obj)
 {
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index f2eed80b15..9be0cff535 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];
@@ -276,3 +284,8 @@ void
 virSEVCapabilitiesFree(virSEVCapability *capabilities);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSEVCapability, virSEVCapabilitiesFree);
+
+void
+virSGXCapabilitiesFree(virSGXCapability *capabilities);
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virSGXCapability, virSGXCapabilitiesFree);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 97bfca906b..0ebd16f585 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -219,6 +219,7 @@ virDomainCapsEnumSet;
 virDomainCapsFormat;
 virDomainCapsNew;
 virSEVCapabilitiesFree;
+virSGXCapabilitiesFree;
 
 
 # conf/domain_conf.h
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 1ed4cda7f0..8fc6dda955 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -672,6 +672,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
               "virtio-iommu-pci", /* QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI */
               "virtio-iommu.boot-bypass", /* QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS */
               "virtio-net.rss", /* QEMU_CAPS_VIRTIO_NET_RSS */
+
+              /* 430 */
+              "sgx-epc", /* QEMU_CAPS_SGX_EPC */
     );
 
 
@@ -753,6 +756,8 @@ struct _virQEMUCaps {
 
     virSEVCapability *sevCapabilities;
 
+    virSGXCapability *sgxCapabilities;
+
     /* Capabilities which may differ depending on the accelerator. */
     virQEMUCapsAccel kvm;
     virQEMUCapsAccel hvf;
@@ -1396,6 +1401,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = {
     { "s390-pv-guest", QEMU_CAPS_S390_PV_GUEST },
     { "virtio-mem-pci", QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI },
     { "virtio-iommu-pci", QEMU_CAPS_DEVICE_VIRTIO_IOMMU_PCI },
+    { "sgx-epc", QEMU_CAPS_SGX_EPC },
 };
 
 
@@ -1971,6 +1977,22 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
 }
 
 
+static int
+virQEMUCapsSGXInfoCopy(virSGXCapabilityPtr *dst,
+                       virSGXCapabilityPtr src)
+{
+    g_autoptr(virSGXCapability) tmp = NULL;
+
+    tmp = g_new0(virSGXCapability, 1);
+
+    tmp->flc = src->flc;
+    tmp->epc_size = src->epc_size;
+
+    *dst = g_steal_pointer(&tmp);
+    return 0;
+}
+
+
 static void
 virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst,
                                  virQEMUCapsAccel *src)
@@ -2052,6 +2074,12 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps)
                                qemuCaps->sevCapabilities) < 0)
         return NULL;
 
+
+    if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC) &&
+        virQEMUCapsSGXInfoCopy(&ret->sgxCapabilities,
+                               qemuCaps->sgxCapabilities) < 0)
+        return NULL;
+
     return g_steal_pointer(&ret);
 }
 
@@ -2615,6 +2643,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps)
 }
 
 
+virSGXCapabilityPtr
+virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
+{
+    return qemuCaps->sgxCapabilities;
+}
+
+
 static int
 virQEMUCapsProbeQMPCommands(virQEMUCaps *qemuCaps,
                             qemuMonitor *mon)
@@ -3441,6 +3476,31 @@ virQEMUCapsProbeQMPSEVCapabilities(virQEMUCaps *qemuCaps,
 }
 
 
+static int
+virQEMUCapsProbeQMPSGXCapabilities(virQEMUCaps *qemuCaps,
+                                   qemuMonitor *mon)
+{
+    int rc = -1;
+    virSGXCapability *caps = NULL;
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC))
+        return 0;
+
+    if ((rc = qemuMonitorGetSGXCapabilities(mon, &caps)) < 0)
+        return -1;
+
+    /* SGX isn't actually supported */
+    if (rc == 0) {
+        virQEMUCapsClear(qemuCaps, QEMU_CAPS_SGX_EPC);
+        return 0;
+    }
+
+    virSGXCapabilitiesFree(qemuCaps->sgxCapabilities);
+    qemuCaps->sgxCapabilities = caps;
+    return 0;
+}
+
+
 /*
  * Filter for features which should never be passed to QEMU. Either because
  * QEMU never supported them or they were dropped as they never did anything
@@ -4219,6 +4279,42 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
 }
 
 
+static int
+virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps,
+                        xmlXPathContextPtr ctxt)
+{
+    g_autoptr(virSGXCapability) sgx = NULL;
+    g_autofree char *flc = NULL;
+
+    if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC))
+        return 0;
+
+    if (virXPathBoolean("boolean(./sgx)", ctxt) == 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing SGX platform data in QEMU capabilities cache"));
+        return -1;
+    }
+
+    sgx = g_new0(virSGXCapability, 1);
+
+    if ((!(flc = virXPathString("string(./sgx/flc)", ctxt))) ||
+        virStringParseYesNo(flc, &sgx->flc) < 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing or invalid SGX platform flc in QEMU capabilities cache"));
+        return -1;
+    }
+
+    if (virXPathUInt("string(./sgx/epc_size)", ctxt, &sgx->epc_size) < 0) {
+        virReportError(VIR_ERR_XML_ERROR, "%s",
+                       _("missing or malformed SGX platform epc_size in QEMU capabilities cache"));
+        return -1;
+    }
+
+    qemuCaps->sgxCapabilities = g_steal_pointer(&sgx);
+    return 0;
+}
+
+
 static int
 virQEMUCapsParseFlags(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
 {
@@ -4521,6 +4617,9 @@ virQEMUCapsLoadCache(virArch hostArch,
     if (virQEMUCapsParseSEVInfo(qemuCaps, ctxt) < 0)
         return -1;
 
+    if (virQEMUCapsParseSGXInfo(qemuCaps, ctxt) < 0)
+        return -1;
+
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_KVM))
         virQEMUCapsInitHostCPUModel(qemuCaps, hostArch, VIR_DOMAIN_VIRT_KVM);
     if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_HVF))
@@ -4706,6 +4805,21 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virBuffer *buf)
 }
 
 
+static void
+virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps,
+                         virBuffer *buf)
+{
+    virSGXCapabilityPtr sgx = virQEMUCapsGetSGXCapabilities(qemuCaps);
+
+    virBufferAddLit(buf, "<sgx>\n");
+    virBufferAdjustIndent(buf, 2);
+    virBufferAsprintf(buf, "<flc>%s</flc>\n", sgx->flc ? "yes" : "no");
+    virBufferAsprintf(buf, "<epc_size>%u</epc_size>\n", sgx->epc_size);
+    virBufferAdjustIndent(buf, -2);
+    virBufferAddLit(buf, "</sgx>\n");
+}
+
+
 char *
 virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
 {
@@ -4787,6 +4901,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
     if (qemuCaps->sevCapabilities)
         virQEMUCapsFormatSEVInfo(qemuCaps, &buf);
 
+    if (qemuCaps->sgxCapabilities)
+        virQEMUCapsFormatSGXInfo(qemuCaps, &buf);
+
     if (qemuCaps->kvmSupportsNesting)
         virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");
 
@@ -5454,6 +5571,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps,
         return -1;
     if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0)
         return -1;
+    if (virQEMUCapsProbeQMPSGXCapabilities(qemuCaps, mon) < 0)
+        return -1;
 
     virQEMUCapsInitProcessCaps(qemuCaps);
 
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 9b240e47fb..0d420527b0 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -648,6 +648,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
     QEMU_CAPS_VIRTIO_IOMMU_BOOT_BYPASS, /* virtio-iommu.boot-bypass */
     QEMU_CAPS_VIRTIO_NET_RSS, /* virtio-net rss feature */
 
+    /* 430 */
+    QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */
+
     QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
 
@@ -840,6 +843,9 @@ virQEMUCapsCPUFeatureFromQEMU(virQEMUCaps *qemuCaps,
 virSEVCapability *
 virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
 
+virSGXCapabilityPtr
+virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
+
 bool
 virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_GNUC_NO_INLINE;
 
diff --git a/src/qemu/qemu_capspriv.h b/src/qemu/qemu_capspriv.h
index f4f4a99d32..c632647a74 100644
--- a/src/qemu/qemu_capspriv.h
+++ b/src/qemu/qemu_capspriv.h
@@ -101,6 +101,10 @@ void
 virQEMUCapsSetSEVCapabilities(virQEMUCaps *qemuCaps,
                               virSEVCapability *capabilities);
 
+void
+virQEMUCapsSetSGXCapabilities(virQEMUCaps *qemuCaps,
+                              virSGXCapability *capabilities);
+
 int
 virQEMUCapsProbeCPUDefinitionsTest(virQEMUCaps *qemuCaps,
                                    qemuMonitor *mon);
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 316cff5b9b..e3425b1db7 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3690,6 +3690,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 5c2a749282..f7b0582f68 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 9e611e93e8..5c6c6f293a 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -6469,6 +6469,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", &section_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)
@@ -7478,13 +7541,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);
@@ -7528,6 +7603,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 982fbad44e..2e445cda91 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -256,6 +256,15 @@ qemuMonitorJSONAddFileHandleToSet(qemuMonitor *mon,
                                   const char *opaque,
                                   qemuMonitorAddFdInfo *info);
 
+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);
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies
index e235532d62..04b3a06f4a 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies
@@ -32707,6 +32707,20 @@
   }
 }
 
+{
+  "execute": "query-sgx-capabilities",
+  "id": "libvirt-51"
+}
+
+{
+  "return": {
+    "sgx": true,
+    "section-size": 1024,
+    "flc": false
+  },
+  "id": "libvirt-51"
+}
+
 {
   "execute": "query-cpu-model-expansion",
   "arguments": {
@@ -32715,7 +32729,7 @@
       "name": "host"
     }
   },
-  "id": "libvirt-51"
+  "id": "libvirt-52"
 }
 
 {
@@ -33048,7 +33062,7 @@
       }
     }
   },
-  "id": "libvirt-51"
+  "id": "libvirt-52"
 }
 
 {
@@ -33062,7 +33076,7 @@
       }
     }
   },
-  "id": "libvirt-52"
+  "id": "libvirt-53"
 }
 
 {
@@ -33395,7 +33409,7 @@
       }
     }
   },
-  "id": "libvirt-52"
+  "id": "libvirt-53"
 }
 
 {
diff --git a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml
index dba5ecaf87..0b0563752f 100644
--- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.xml
@@ -238,6 +238,7 @@
   <flag name='memory-backend-file.prealloc-threads'/>
   <flag name='virtio-iommu-pci'/>
   <flag name='virtio-net.rss'/>
+  <flag name='sgx-epc'/>
   <version>6002000</version>
   <kvmVersion>0</kvmVersion>
   <microcodeVersion>43100244</microcodeVersion>
@@ -3706,4 +3707,8 @@
   <machine type='tcg' name='pc-q35-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
   <machine type='tcg' name='pc-i440fx-3.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
   <machine type='tcg' name='pc-q35-2.11' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
+  <sgx>
+    <flc>no</flc>
+    <epc_size>1</epc_size>
+  </sgx>
 </qemuCaps>
diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies
index 620442704a..6e85a96ffb 100644
--- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies
@@ -33317,6 +33317,20 @@
   }
 }
 
+{
+  "execute": "query-sgx-capabilities",
+  "id": "libvirt-51"
+}
+
+{
+  "return": {
+    "sgx": true,
+    "section-size": 1024,
+    "flc": false
+  },
+  "id": "libvirt-51"
+}
+
 {
   "execute": "query-cpu-model-expansion",
   "arguments": {
@@ -33325,7 +33339,7 @@
       "name": "host"
     }
   },
-  "id": "libvirt-51"
+  "id": "libvirt-52"
 }
 
 {
@@ -33662,7 +33676,7 @@
       }
     }
   },
-  "id": "libvirt-51"
+  "id": "libvirt-52"
 }
 
 {
@@ -33676,7 +33690,7 @@
       }
     }
   },
-  "id": "libvirt-52"
+  "id": "libvirt-53"
 }
 
 {
@@ -34013,7 +34027,7 @@
       }
     }
   },
-  "id": "libvirt-52"
+  "id": "libvirt-53"
 }
 
 {
diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml
index 8074c97ecd..65d0d71cee 100644
--- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml
@@ -242,6 +242,7 @@
   <flag name='virtio-iommu-pci'/>
   <flag name='virtio-iommu.boot-bypass'/>
   <flag name='virtio-net.rss'/>
+  <flag name='sgx-epc'/>
   <version>7000000</version>
   <kvmVersion>0</kvmVersion>
   <microcodeVersion>43100243</microcodeVersion>
@@ -3770,4 +3771,8 @@
   <machine type='tcg' name='pc-q35-2.5' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
   <machine type='tcg' name='pc-i440fx-3.0' hotplugCpus='yes' maxCpus='255' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
   <machine type='tcg' name='pc-q35-2.11' hotplugCpus='yes' maxCpus='288' defaultCPU='qemu64-x86_64-cpu' numaMemSupported='yes' defaultRAMid='pc.ram'/>
+  <sgx>
+    <flc>no</flc>
+    <epc_size>1</epc_size>
+  </sgx>
 </qemuCaps>
-- 
2.25.1



More information about the libvir-list mailing list