[libvirt][PATCH RESEND v10 2/5] conf: expose SGX feature in domain capabilities

Haibin Huang haibin.huang at intel.com
Tue Feb 8 05:21:17 UTC 2022


Extend hypervisor capabilities to include sgx feature. When available,
the hypervisor supports launching an VM with SGX on Intel platfrom.
The SGX feature tag privides additional details like section size and
sgx1 or sgx2.

Signed-off-by: Haibin Huang <haibin.huang at intel.com>
---
 docs/formatdomaincaps.html.in  | 26 ++++++++++++++++++++++++++
 docs/schemas/domaincaps.rng    | 22 +++++++++++++++++++++-
 src/conf/domain_capabilities.c | 21 +++++++++++++++++++++
 src/qemu/qemu_capabilities.c   | 24 ++++++++++++++++++++++++
 4 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 35b8bf3def..d932e6df80 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -598,6 +598,10 @@
       <cbitpos>47</cbitpos>
       <reduced-phys-bits>1</reduced-phys-bits>
     </sev>
+    <sgx>
+      <flc>no</flc>
+      <epc_size>1</epc_size>
+    </sgx>
   </features>
 </domainCapabilities>
 </pre>
@@ -689,5 +693,27 @@
       This value may be configurable in the firmware for some hosts.</dd>
     </dl>
 
+    <h4><a id="elementsSGX">SGX capabilities</a></h4>
+
+    <p>Intel Software Guard Extensions (Intel SGX) capabilities are exposed under
+    the <code>sgx</code> element.
+    Intel SGX helps protect data in use via unique application isolation technology.
+    Protect selected code and data from modification using hardened enclaves with
+    Intel SGX.</p>
+
+    <p>
+      For more details on the SGX feature, please follow resources in the
+      SGX developer's document store. In order to use SGX with libvirt have
+      a look at <a href="formatdomain.html#memory-devices">SGX in domain XML</a>
+    </p>
+
+    <dl>
+      <dt><code>flc</code></dt>
+      <dd>FLC (Flexible Launch Control), not strictly part of SGX2, but was not part
+      of original SGX hardware either.</dd>
+      <dt><code>epc_size</code></dt>
+      <dd>The size of the SGX enclave page cache (called EPC).</dd>
+    </dl>
+
   </body>
 </html>
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 9cbc2467ab..5ace30ae0d 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -270,6 +270,9 @@
       <optional>
         <ref name="sev"/>
       </optional>
+      <optional>
+        <ref name='sgx'/>
+      </optional>
     </element>
   </define>
 
@@ -330,7 +333,24 @@
     </element>
   </define>
 
-  <define name="value">
+  <define name='sgx'>
+    <element name='sgx'>
+      <ref name='supported'/>
+      <optional>
+        <element name='flc'>
+          <data type='string'/>
+        </element>
+        <element name='epc_size'>
+          <attribute name="unit">
+            <value>KiB</value>
+          </attribute>
+          <data type='unsignedInt'/>
+        </element>
+      </optional>
+    </element>
+  </define>
+
+  <define name='value'>
     <zeroOrMore>
       <element name="value">
         <text/>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 1170fd26df..2e9f0ec225 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -100,6 +100,7 @@ virDomainCapsDispose(void *obj)
     virObjectUnref(caps->cpu.custom);
     virCPUDefFree(caps->cpu.hostModel);
     virSEVCapabilitiesFree(caps->sev);
+    virSGXCapabilitiesFree(caps->sgx);
 
     values = &caps->os.loader.values;
     for (i = 0; i < values->nvalues; i++)
@@ -618,6 +619,25 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf,
     return;
 }
 
+static void
+virDomainCapsFeatureSGXFormat(virBuffer *buf,
+                              const virSGXCapability *sgx)
+{
+    if (!sgx) {
+        return; // will delete in test patch
+        virBufferAddLit(buf, "<sgx supported='no'/>\n");
+    } else {
+        return; // will delete in test patch
+        virBufferAddLit(buf, "<sgx supported='yes'>\n");
+        virBufferAdjustIndent(buf, 2);
+        virBufferAsprintf(buf, "<flc>%s</flc>\n", sgx->flc ? "yes" : "no");
+        virBufferAsprintf(buf, "<epc_size unit='KiB'>%d</epc_size>\n", sgx->epc_size);
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</sgx>\n");
+    }
+
+    return;
+}
 
 static void
 virDomainCapsFormatFeatures(const virDomainCaps *caps,
@@ -638,6 +658,7 @@ virDomainCapsFormatFeatures(const virDomainCaps *caps,
     }
 
     virDomainCapsFeatureSEVFormat(&childBuf, caps->sev);
+    virDomainCapsFeatureSGXFormat(&childBuf, caps->sgx);
 
     virXMLFormatElement(buf, "features", NULL, &childBuf);
 }
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 0e43dd2466..745d203241 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -6632,6 +6632,29 @@ virQEMUCapsFillDomainFeatureS390PVCaps(virQEMUCaps *qemuCaps,
     }
 }
 
+/**
+ * virQEMUCapsFillDomainFeatureiSGXCaps:
+ * @qemuCaps: QEMU capabilities
+ * @domCaps: domain capabilities
+ *
+ * Take the information about SGX capabilities that has been obtained
+ * using the 'query-sgx-capabilities' QMP command and stored in @qemuCaps
+ * and convert it to a form suitable for @domCaps.
+ */
+static void
+virQEMUCapsFillDomainFeatureSGXCaps(virQEMUCaps *qemuCaps,
+                                    virDomainCaps *domCaps)
+{
+    virSGXCapability *cap = qemuCaps->sgxCapabilities;
+
+    if (!cap)
+        return;
+
+    domCaps->sgx = g_new0(virSGXCapability, 1);
+
+    domCaps->sgx->flc = cap->flc;
+    domCaps->sgx->epc_size = cap->epc_size;
+}
 
 int
 virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps,
@@ -6684,6 +6707,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps,
     virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps);
     virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps);
     virQEMUCapsFillDomainFeatureS390PVCaps(qemuCaps, domCaps);
+    virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps);
 
     return 0;
 }
-- 
2.17.1




More information about the libvir-list mailing list