mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-22 13:45:38 +00:00
Convert QMP capabilities to domain capabilities
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: Michal Privoznik <mprivozn@redhat.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
1a68499c01
commit
6b7c36c8c2
@ -677,6 +677,7 @@ VIR_ENUM_IMPL(virQEMUCaps,
|
||||
/* 435 */
|
||||
"query-stats", /* QEMU_CAPS_QUERY_STATS */
|
||||
"query-stats-schemas", /* QEMU_CAPS_QUERY_STATS_SCHEMAS */
|
||||
"sgx-epc", /* QEMU_CAPS_SGX_EPC */
|
||||
);
|
||||
|
||||
|
||||
@ -758,6 +759,8 @@ struct _virQEMUCaps {
|
||||
|
||||
virSEVCapability *sevCapabilities;
|
||||
|
||||
virSGXCapability *sgxCapabilities;
|
||||
|
||||
/* Capabilities which may differ depending on the accelerator. */
|
||||
virQEMUCapsAccel kvm;
|
||||
virQEMUCapsAccel hvf;
|
||||
@ -1380,6 +1383,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 },
|
||||
};
|
||||
|
||||
|
||||
@ -1891,6 +1895,36 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst,
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virQEMUCapsSGXInfoCopy(virSGXCapability **dst,
|
||||
virSGXCapability *src)
|
||||
{
|
||||
g_autoptr(virSGXCapability) tmp = NULL;
|
||||
|
||||
if (!src) {
|
||||
*dst = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
tmp = g_new0(virSGXCapability, 1);
|
||||
|
||||
tmp->flc = src->flc;
|
||||
tmp->sgx1 = src->sgx1;
|
||||
tmp->sgx2 = src->sgx2;
|
||||
tmp->section_size = src->section_size;
|
||||
|
||||
if (src->nSgxSections > 0) {
|
||||
tmp->sgxSections = g_new0(virSGXSection, src->nSgxSections);
|
||||
memcpy(tmp->sgxSections, src->sgxSections,
|
||||
src->nSgxSections * sizeof(*tmp->sgxSections));
|
||||
tmp->nSgxSections = src->nSgxSections;
|
||||
}
|
||||
|
||||
*dst = g_steal_pointer(&tmp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst,
|
||||
virQEMUCapsAccel *src)
|
||||
@ -1972,6 +2006,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);
|
||||
}
|
||||
|
||||
@ -2010,6 +2050,7 @@ void virQEMUCapsDispose(void *obj)
|
||||
virCPUDataFree(qemuCaps->cpuData);
|
||||
|
||||
virSEVCapabilitiesFree(qemuCaps->sevCapabilities);
|
||||
virSGXCapabilitiesFree(qemuCaps->sgxCapabilities);
|
||||
|
||||
virQEMUCapsAccelClear(&qemuCaps->kvm);
|
||||
virQEMUCapsAccelClear(&qemuCaps->hvf);
|
||||
@ -2541,6 +2582,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps)
|
||||
}
|
||||
|
||||
|
||||
virSGXCapability *
|
||||
virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps)
|
||||
{
|
||||
return qemuCaps->sgxCapabilities;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virQEMUCapsProbeQMPCommands(virQEMUCaps *qemuCaps,
|
||||
qemuMonitor *mon)
|
||||
@ -3373,6 +3421,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
|
||||
@ -4167,6 +4240,97 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps,
|
||||
xmlXPathContextPtr ctxt)
|
||||
{
|
||||
g_autoptr(virSGXCapability) sgx = NULL;
|
||||
xmlNodePtr sgxSections = NULL;
|
||||
g_autofree char *flc = NULL;
|
||||
g_autofree char *sgx1 = NULL;
|
||||
g_autofree char *sgx2 = 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 ((!(sgx1 = virXPathString("string(./sgx/sgx1)", ctxt))) ||
|
||||
virStringParseYesNo(sgx1, &sgx->sgx1) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("missing or invalid SGX platform sgx1 in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((!(sgx2 = virXPathString("string(./sgx/sgx2)", ctxt))) ||
|
||||
virStringParseYesNo(sgx2, &sgx->sgx2) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("missing or invalid SGX platform sgx2 in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virXPathULongLong("string(./sgx/section_size)", ctxt,
|
||||
&sgx->section_size) < 0) {
|
||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||
_("missing or malformed SGX platform section_size in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((sgxSections = virXPathNode("./sgx/sections", ctxt))) {
|
||||
g_autofree xmlNodePtr *sectionNodes = NULL;
|
||||
int nSgxSections = 0;
|
||||
size_t i;
|
||||
VIR_XPATH_NODE_AUTORESTORE(ctxt);
|
||||
|
||||
ctxt->node = sgxSections;
|
||||
nSgxSections = virXPathNodeSet("./section", ctxt, §ionNodes);
|
||||
|
||||
if (nSgxSections < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("failed to parse SGX sections in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
sgx->nSgxSections = nSgxSections;
|
||||
sgx->sgxSections = g_new0(virSGXSection, nSgxSections);
|
||||
|
||||
for (i = 0; i < nSgxSections; i++) {
|
||||
if (virXMLPropUInt(sectionNodes[i], "node", 10,
|
||||
VIR_XML_PROP_REQUIRED,
|
||||
&(sgx->sgxSections[i].node)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing node name in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (virXMLPropULongLong(sectionNodes[i], "size", 10,
|
||||
VIR_XML_PROP_REQUIRED,
|
||||
&(sgx->sgxSections[i].size)) < 0) {
|
||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||
_("missing size name in QEMU capabilities cache"));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
qemuCaps->sgxCapabilities = g_steal_pointer(&sgx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virQEMUCapsParseFlags(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt)
|
||||
{
|
||||
@ -4455,6 +4619,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))
|
||||
@ -4643,6 +4810,38 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virBuffer *buf)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps,
|
||||
virBuffer *buf)
|
||||
{
|
||||
virSGXCapability *sgx = virQEMUCapsGetSGXCapabilities(qemuCaps);
|
||||
|
||||
virBufferAddLit(buf, "<sgx supported='yes'>\n");
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
virBufferAsprintf(buf, "<flc>%s</flc>\n", sgx->flc ? "yes" : "no");
|
||||
virBufferAsprintf(buf, "<sgx1>%s</sgx1>\n", sgx->sgx1 ? "yes" : "no");
|
||||
virBufferAsprintf(buf, "<sgx2>%s</sgx2>\n", sgx->sgx2 ? "yes" : "no");
|
||||
virBufferAsprintf(buf, "<section_size unit='KiB'>%llu</section_size>\n", sgx->section_size);
|
||||
|
||||
if (sgx->nSgxSections > 0) {
|
||||
size_t i;
|
||||
virBufferAddLit(buf, "<sections>\n");
|
||||
|
||||
for (i = 0; i < sgx->nSgxSections; i++) {
|
||||
virBufferAdjustIndent(buf, 2);
|
||||
virBufferAsprintf(buf, "<section node='%u' ", sgx->sgxSections[i].node);
|
||||
virBufferAsprintf(buf, "size='%llu' ", sgx->sgxSections[i].size);
|
||||
virBufferAddLit(buf, "unit='KiB'/>\n");
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
}
|
||||
virBufferAddLit(buf, "</sections>\n");
|
||||
}
|
||||
|
||||
virBufferAdjustIndent(buf, -2);
|
||||
virBufferAddLit(buf, "</sgx>\n");
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
|
||||
{
|
||||
@ -4724,6 +4923,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps)
|
||||
if (qemuCaps->sevCapabilities)
|
||||
virQEMUCapsFormatSEVInfo(qemuCaps, &buf);
|
||||
|
||||
if (qemuCaps->sgxCapabilities)
|
||||
virQEMUCapsFormatSGXInfo(qemuCaps, &buf);
|
||||
|
||||
if (qemuCaps->kvmSupportsNesting)
|
||||
virBufferAddLit(&buf, "<kvmSupportsNesting/>\n");
|
||||
|
||||
@ -5353,6 +5555,8 @@ virQEMUCapsInitQMPMonitor(virQEMUCaps *qemuCaps,
|
||||
return -1;
|
||||
if (virQEMUCapsProbeQMPSEVCapabilities(qemuCaps, mon) < 0)
|
||||
return -1;
|
||||
if (virQEMUCapsProbeQMPSGXCapabilities(qemuCaps, mon) < 0)
|
||||
return -1;
|
||||
|
||||
virQEMUCapsInitProcessCaps(qemuCaps);
|
||||
|
||||
|
@ -656,6 +656,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */
|
||||
/* 435 */
|
||||
QEMU_CAPS_QUERY_STATS, /* accepts query-stats */
|
||||
QEMU_CAPS_QUERY_STATS_SCHEMAS, /* accepts query-stats-schemas */
|
||||
QEMU_CAPS_SGX_EPC, /* -object sgx-epc,... */
|
||||
|
||||
QEMU_CAPS_LAST /* this must always be the last item */
|
||||
} virQEMUCapsFlags;
|
||||
@ -859,6 +860,9 @@ virQEMUCapsCPUFeatureFromQEMUInPlace(virArch arch,
|
||||
virSEVCapability *
|
||||
virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps);
|
||||
|
||||
virSGXCapability *
|
||||
virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps);
|
||||
|
||||
bool
|
||||
virQEMUCapsGetKVMSupportsSecureGuest(virQEMUCaps *qemuCaps) G_NO_INLINE;
|
||||
|
||||
|
@ -32419,6 +32419,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-sgx-capabilities",
|
||||
"id": "libvirt-48"
|
||||
}
|
||||
|
||||
{
|
||||
"id": "libvirt-48",
|
||||
"error": {
|
||||
"class": "GenericError",
|
||||
"desc": "SGX is not enabled in KVM"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-cpu-model-expansion",
|
||||
"arguments": {
|
||||
@ -32427,7 +32440,7 @@
|
||||
"name": "host"
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -32760,7 +32773,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -32774,7 +32787,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
@ -33107,7 +33120,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -33029,6 +33029,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-sgx-capabilities",
|
||||
"id": "libvirt-48"
|
||||
}
|
||||
|
||||
{
|
||||
"return": {
|
||||
"sgx": true,
|
||||
"flc": false,
|
||||
"sgx1": true,
|
||||
"sgx2": false,
|
||||
"section-size": 536870912,
|
||||
"sections": [
|
||||
{
|
||||
"node": 0,
|
||||
"size": 268435456
|
||||
},
|
||||
{
|
||||
"node": 1,
|
||||
"size": 268435456
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-cpu-model-expansion",
|
||||
"arguments": {
|
||||
@ -33037,7 +33063,7 @@
|
||||
"name": "host"
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -33374,7 +33400,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -33388,7 +33414,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
@ -33725,7 +33751,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -195,6 +195,7 @@
|
||||
<flag name='display-dbus'/>
|
||||
<flag name='usb-host.guest-resets-all'/>
|
||||
<flag name='migration.blocked-reasons'/>
|
||||
<flag name='sgx-epc'/>
|
||||
<version>7000000</version>
|
||||
<kvmVersion>0</kvmVersion>
|
||||
<microcodeVersion>43100243</microcodeVersion>
|
||||
@ -3723,4 +3724,14 @@
|
||||
<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 supported='yes'>
|
||||
<flc>no</flc>
|
||||
<sgx1>yes</sgx1>
|
||||
<sgx2>no</sgx2>
|
||||
<section_size unit='KiB'>524288</section_size>
|
||||
<sections>
|
||||
<section node='0' size='262144' unit='KiB'/>
|
||||
<section node='1' size='262144' unit='KiB'/>
|
||||
</sections>
|
||||
</sgx>
|
||||
</qemuCaps>
|
||||
|
@ -33722,6 +33722,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-sgx-capabilities",
|
||||
"id": "libvirt-48"
|
||||
}
|
||||
|
||||
{
|
||||
"id": "libvirt-48",
|
||||
"error": {
|
||||
"class": "GenericError",
|
||||
"desc": "SGX is not enabled in KVM"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-cpu-model-expansion",
|
||||
"arguments": {
|
||||
@ -33730,7 +33743,7 @@
|
||||
"name": "host"
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -34068,7 +34081,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -34082,7 +34095,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
@ -34420,7 +34433,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -34635,6 +34635,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-sgx-capabilities",
|
||||
"id": "libvirt-48"
|
||||
}
|
||||
|
||||
{
|
||||
"id": "libvirt-48",
|
||||
"error": {
|
||||
"class": "GenericError",
|
||||
"desc": "SGX is not enabled in KVM"
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
"execute": "query-cpu-model-expansion",
|
||||
"arguments": {
|
||||
@ -34643,7 +34656,7 @@
|
||||
"name": "host"
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -34981,7 +34994,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-48"
|
||||
"id": "libvirt-49"
|
||||
}
|
||||
|
||||
{
|
||||
@ -34995,7 +35008,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
@ -35333,7 +35346,7 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"id": "libvirt-49"
|
||||
"id": "libvirt-50"
|
||||
}
|
||||
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user