the QMP capabilities:
{"return":
{
"sgx": true,
"section-size": 1024,
"flc": true
}
}
the domain capabilities:
<sgx>
<flc>yes</flc>
<epc_size>1</epc_size>
</sgx>
Signed-off-by: Haibin Huang <haibin.huang(a)intel.com>
---
src/conf/schemas/domaincaps.rng | 22 +++-
src/qemu/qemu_capabilities.c | 121 ++++++++++++++++++
src/qemu/qemu_capabilities.h | 4 +
src/qemu/qemu_capspriv.h | 4 +
.../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 +
.../caps_7.1.0.x86_64.replies | 21 ++-
9 files changed, 213 insertions(+), 13 deletions(-)
diff --git a/src/conf/schemas/domaincaps.rng b/src/conf/schemas/domaincaps.rng
index 9cbc2467ab..5ace30ae0d 100644
--- a/src/conf/schemas/domaincaps.rng
+++ b/src/conf/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/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index a59d839d85..0d16762a0b 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -675,6 +675,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
/* 430 */
"chardev.qemu-vdagent", /* QEMU_CAPS_CHARDEV_QEMU_VDAGENT */
+ "sgx-epc", /* QEMU_CAPS_SGX_EPC */
);
@@ -756,6 +757,8 @@ struct _virQEMUCaps {
virSEVCapability *sevCapabilities;
+ virSGXCapability *sgxCapabilities;
+
/* Capabilities which may differ depending on the accelerator. */
virQEMUCapsAccel kvm;
virQEMUCapsAccel hvf;
@@ -1398,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 },
};
@@ -1974,6 +1978,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)
@@ -2055,6 +2075,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);
}
@@ -2618,6 +2644,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps)
}
+virSGXCapabilityPtr
+virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
+{
+ return qemuCaps->sgxCapabilities;
+}
+
+
static int
virQEMUCapsProbeQMPCommands(virQEMUCaps *qemuCaps,
qemuMonitor *mon)
@@ -3444,6 +3477,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
@@ -4222,6 +4280,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)
{
@@ -4524,6 +4618,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))
@@ -4709,6 +4806,25 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virBuffer *buf)
}
+static void
+virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps,
+ virBuffer *buf)
+{
+ virSGXCapabilityPtr sgx = virQEMUCapsGetSGXCapabilities(qemuCaps);
+
+ virBufferAddLit(buf, "<sgx>\n");
+ virBufferAdjustIndent(buf, 2);
+ if (sgx->flc) {
+ virBufferAsprintf(buf, "<flc>%s</flc>\n",
"yes");
+ } else {
+ virBufferAsprintf(buf, "<flc>%s</flc>\n", "no");
+ }
+ virBufferAsprintf(buf, "<epc_size>%u</epc_size>\n",
sgx->epc_size);
+ virBufferAdjustIndent(buf, -2);
+ virBufferAddLit(buf, "</sgx>\n");
+}
+
+
char *
virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
{
@@ -4790,6 +4906,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
if (qemuCaps->sevCapabilities)
virQEMUCapsFormatSEVInfo(qemuCaps, &buf);
+ if (qemuCaps->sgxCapabilities)
+ virQEMUCapsFormatSGXInfo(qemuCaps, &buf);
+
if (qemuCaps->kvmSupportsNesting)
virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");
@@ -5457,6 +5576,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 59c09903f3..38ec3222dd 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -650,6 +650,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check
*/
/* 430 */
QEMU_CAPS_CHARDEV_QEMU_VDAGENT, /* -chardev qemu-vdagent */
+ QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */
QEMU_CAPS_LAST /* this must always be the last item */
} virQEMUCapsFlags;
@@ -843,6 +844,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/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 19605d93ae..bc7c16c0f9 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='virtio-iommu-pci'/>
<flag name='virtio-net.rss'/>
<flag name='chardev.qemu-vdagent'/>
+ <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 7523b92e6b..54720d9ee9 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.boot-bypass'/>
<flag name='virtio-net.rss'/>
<flag name='chardev.qemu-vdagent'/>
+ <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>
diff --git a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies
b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies
index 8444825cb7..c52b7917e2 100644
--- a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies
@@ -33484,6 +33484,19 @@
}
}
+{
+ "execute": "query-sgx-capabilities",
+ "id": "libvirt-51"
+}
+
+{
+ "id": "libvirt-51",
+ "error": {
+ "class": "GenericError",
+ "desc": "SGX is not enabled in KVM"
+ }
+}
+
{
"execute": "query-cpu-model-expansion",
"arguments": {
@@ -33492,7 +33505,7 @@
"name": "host"
}
},
- "id": "libvirt-51"
+ "id": "libvirt-52"
}
{
@@ -33829,7 +33842,7 @@
}
}
},
- "id": "libvirt-51"
+ "id": "libvirt-52"
}
{
@@ -33843,7 +33856,7 @@
}
}
},
- "id": "libvirt-52"
+ "id": "libvirt-53"
}
{
@@ -34180,7 +34193,7 @@
}
}
},
- "id": "libvirt-52"
+ "id": "libvirt-53"
}
{
--
2.17.1