[libvirt][PATCH RESEND v12 0/6] Support query and use SGX

This patch series provides support for enabling Intel's Software Guard Extensions (SGX) feature in guest VM. Giving the SGX support in QEMU had been merged. Intel SGX is a set of instructions that increases the security of application code and data, giving them more protection from disclosure or modification. Developers can partition sensitive information into enclaves, which are areas of execution in memory with more security protection. The typical flow looks below at very high level: 1. Calls virConnectGetDomainCapabilities API to domain capabilities that includes the following SGX information. <feature> ... <sgx supported='yes'> <epc_size unit='KiB'>N</epc_size> </sgx> ... </feature> 2. User requests to start a guest calling virCreateXML() with SGX requirement. It does not support NUMA yet, since latest QEMU 6.2 release does not support NUMA. It should contain <devices> ... <memory model='sgx-epc'> <target> <size unit='KiB'>N</size> </target> </memory> ... </devices> Please note that SGX NUMA support will be implemented in future patches. Haibin Huang (4): Define SGX capabilities structs Get SGX capabilities form QMP Convert QMP capabilities to domain capabilities conf: expose SGX feature in domain capabilities Lin Yang (2): conf: Introduce SGX EPC element into device memory xml qemu: Add command-line to generate SGX EPC memory backend docs/formatdomain.rst | 9 +- docs/formatdomaincaps.rst | 26 ++++ src/conf/domain_capabilities.c | 33 ++++ src/conf/domain_capabilities.h | 13 ++ src/conf/domain_conf.c | 6 + src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 16 ++ src/conf/schemas/domaincaps.rng | 22 ++- src/conf/schemas/domaincommon.rng | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_alias.c | 6 +- src/qemu/qemu_capabilities.c | 145 ++++++++++++++++++ src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_capspriv.h | 4 + src/qemu/qemu_command.c | 54 ++++++- src/qemu/qemu_domain.c | 38 +++-- src/qemu/qemu_domain_address.c | 6 + src/qemu/qemu_driver.c | 1 + 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 ++ src/qemu/qemu_process.c | 2 + src/qemu/qemu_validate.c | 8 + src/security/security_apparmor.c | 1 + src/security/security_dac.c | 2 + src/security/security_selinux.c | 2 + tests/domaincapsdata/bhyve_basic.x86_64.xml | 1 + tests/domaincapsdata/bhyve_fbuf.x86_64.xml | 1 + tests/domaincapsdata/bhyve_uefi.x86_64.xml | 1 + tests/domaincapsdata/empty.xml | 1 + tests/domaincapsdata/libxl-xenfv.xml | 1 + tests/domaincapsdata/libxl-xenpv.xml | 1 + .../domaincapsdata/qemu_2.11.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.11.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.11.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.11.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 1 + .../qemu_2.12.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_3.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 1 + .../qemu_4.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 + .../qemu_4.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + .../qemu_5.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0.sparc.xml | 1 + tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 1 + .../qemu_5.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 1 + .../qemu_6.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 4 + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 4 + .../qemu_6.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 4 + .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 4 + .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 4 + .../qemu_7.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 4 + .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 1 + .../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 ++- .../sgx-epc.x86_64-6.2.0.args | 37 +++++ tests/qemuxml2argvdata/sgx-epc.xml | 36 +++++ tests/qemuxml2argvtest.c | 2 + .../sgx-epc.x86_64-6.2.0.xml | 52 +++++++ tests/qemuxml2xmltest.c | 2 + 121 files changed, 793 insertions(+), 40 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args create mode 100644 tests/qemuxml2argvdata/sgx-epc.xml create mode 100644 tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml -- 2.17.1

Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/conf/domain_capabilities.c | 10 ++++++++++ src/conf/domain_capabilities.h | 13 +++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 24 insertions(+) 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 d95c181793..8ac528f677 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -219,6 +219,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virSGXCapabilitiesFree; # conf/domain_conf.h -- 2.17.1

On 5/18/22 09:59, Haibin Huang wrote:
Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/conf/domain_capabilities.c | 10 ++++++++++ src/conf/domain_capabilities.h | 13 +++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 24 insertions(+)
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;
So QEMU declares this as uint64. I'm not sure that uint is long enough to hold all values. But what bothers me more is QAPI declaration (qapi/misc-target.json): ## # @SGXInfo: # # Information about intel Safe Guard eXtension (SGX) support # # Features: # @deprecated: Member @section-size is deprecated. Use @sections instead. And looking into commit message that introduce this change: https://gitlab.com/qemu-project/qemu/-/commit/a66bd91f030827742778a9e0da19fe... The "@section-size" will be deprecated in 7.2 version. Shouldn't we be parsing sections then? I'd rather see us requiring newer QEMU (7.0 in which @sections member was introduced) than having to rewrite this again. Then we'll get into tougher situation where we'll have to support both old and new QEMUs. Now, looking ad the new @sections member, it captures per-NUMA node sizes of SGX enclaves. Shouldn't we pass that information to users? Michal

On 5/18/22 09:59, Haibin Huang wrote:
Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/conf/domain_capabilities.c | 10 ++++++++++ src/conf/domain_capabilities.h | 13 +++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 24 insertions(+)
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);
We try to avoid VIR_FREE() in new code. Either use plain g_free() or if you also need to clear the pointer then: g_clear_pointer(&cap, g_free); but since only first order pointer is passed then clearing the variable has no visible effect outside of the function => plain g_free() is sufficient.
+} + +
Michal

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@intel.com> --- 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 +++ 4 files changed, 119 insertions(+), 7 deletions(-) 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.17.1

On 5/18/22 09:59, Haibin Huang wrote:
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@intel.com> --- 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 +++ 4 files changed, 119 insertions(+), 7 deletions(-)
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; }
This hunk ^^ ...
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; + }
.. and this hunk ^^ don't belong into this patch. They belong to the very last patch where libvirt is able to start a guest with sgx-epc memdev. In other words: these two hunks are conceptually different to the rest of the patch. It just so happens that they live in the same file. Since we've been struggling with proper split of the code into patches I worry that maybe I'm not expressing my thoughts comprehensibly. Or maybe it's lost in translation. I don't know. I've tried to fix your patches and they're available here: https://gitlab.com/MichalPrivoznik/libvirt/-/commits/sgx_fixups Pleaso do take a look, ideally rather sooner than later - I was pinged by a colleague of yours couple of months after I've done this the first time - by that time I was tired of rebasing that branch constantly and just deleted it. This branch is not going to stay there forever either.
} 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); +
This is probably a leftover from bad conflict resolution. You are not introducing either of qemuMonitorJSONMigrate() qemuMonitorJSONGetSpiceMigrationStatus() and they are already declared. No need to declare them again. Michal

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@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

On 5/18/22 09:59, Haibin Huang wrote:
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@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> +
This doesn't belong here. In this commit you are not touching domcaps at all. Here you are just detecting SGX capabilities. Therefore, the commit message should reflect that and this change should go into the commit where domcaps are formatted.
+ <define name='value'>
I'm puzzled by this change. We use double quotes, so please stick with that.
<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); +
This is useless. This function is never introduced and nothing calls it. In fact, virQEMUCapsSetSEVCapabilities() shouldn't be there either.
int virQEMUCapsProbeCPUDefinitionsTest(virQEMUCaps *qemuCaps, qemuMonitor *mon);
Michal

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@intel.com> --- docs/formatdomaincaps.rst | 26 +++++++++++++++++++ src/conf/domain_capabilities.c | 23 ++++++++++++++++ src/qemu/qemu_capabilities.c | 24 +++++++++++++++++ tests/domaincapsdata/bhyve_basic.x86_64.xml | 1 + tests/domaincapsdata/bhyve_fbuf.x86_64.xml | 1 + tests/domaincapsdata/bhyve_uefi.x86_64.xml | 1 + tests/domaincapsdata/empty.xml | 1 + tests/domaincapsdata/libxl-xenfv.xml | 1 + tests/domaincapsdata/libxl-xenpv.xml | 1 + .../domaincapsdata/qemu_2.11.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.11.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_2.11.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.11.0.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_2.12.0-tcg.x86_64.xml | 1 + .../qemu_2.12.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_2.12.0.s390x.xml | 1 + tests/domaincapsdata/qemu_2.12.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.0.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_3.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_3.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_3.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.0.0-tcg.x86_64.xml | 1 + .../qemu_4.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_4.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_4.2.0-tcg.x86_64.xml | 1 + .../qemu_4.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_4.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_4.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.0.0-tcg.x86_64.xml | 1 + .../qemu_5.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_5.1.0.sparc.xml | 1 + tests/domaincapsdata/qemu_5.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_5.2.0-tcg.x86_64.xml | 1 + .../qemu_5.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_5.2.0.s390x.xml | 1 + tests/domaincapsdata/qemu_5.2.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.0.0-tcg.x86_64.xml | 1 + .../qemu_6.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.0.0.s390x.xml | 1 + tests/domaincapsdata/qemu_6.0.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_6.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_6.1.0.x86_64.xml | 1 + .../domaincapsdata/qemu_6.2.0-q35.x86_64.xml | 4 +++ .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 4 +++ .../qemu_6.2.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_6.2.0.x86_64.xml | 4 +++ .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 4 +++ .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 4 +++ .../qemu_7.0.0-virt.aarch64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.aarch64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.ppc64.xml | 1 + tests/domaincapsdata/qemu_7.0.0.x86_64.xml | 4 +++ .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 1 + .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 1 + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 1 + 87 files changed, 175 insertions(+) diff --git a/docs/formatdomaincaps.rst b/docs/formatdomaincaps.rst index 4de96ea83a..964cc26d21 100644 --- a/docs/formatdomaincaps.rst +++ b/docs/formatdomaincaps.rst @@ -519,6 +519,10 @@ capabilities. All features occur as children of the main ``features`` element. <cbitpos>47</cbitpos> <reduced-phys-bits>1</reduced-phys-bits> </sev> + <sgx> + <flc>no</flc> + <epc_size>1</epc_size> + </sgx> </features> </domainCapabilities> @@ -598,3 +602,25 @@ in domain XML <formatdomain.html#launchSecurity>`__ ``maxESGuests`` The maximum number of SEV-ES guests that can be launched on the host. This value may be configurable in the firmware for some hosts. + +SGX capabilities +^^^^^^^^^^^^^^^^ + +Intel Software Guard Extensions (Intel SGX) capabilities are exposed under the +``sgx`` 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. + +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 formatdomain.rst +Memory devices. + + +``flc`` + FLC (Flexible Launch Control), not strictly part of SGX2, but was not part of + original SGX hardware either. + +``epc_size`` + The size of the SGX enclave page cache (called EPC). diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index d0e863c5cb..1ec1eda6c0 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++) @@ -622,6 +623,27 @@ virDomainCapsFeatureSEVFormat(virBuffer *buf, return; } +static void +virDomainCapsFeatureSGXFormat(virBuffer *buf, + const virSGXCapability *sgx) +{ + if (!sgx) { + virBufferAddLit(buf, "<sgx supported='no'/>\n"); + } else { + virBufferAddLit(buf, "<sgx supported='yes'>\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 unit='KiB'>%d</epc_size>\n", sgx->epc_size); + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "</sgx>\n"); + } + + return; +} static void virDomainCapsFormatFeatures(const virDomainCaps *caps, @@ -642,6 +664,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 0d16762a0b..68c48b9fe4 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -6635,6 +6635,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, @@ -6687,6 +6710,7 @@ virQEMUCapsFillDomainCaps(virQEMUCaps *qemuCaps, virQEMUCapsFillDomainFeatureGICCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureSEVCaps(qemuCaps, domCaps); virQEMUCapsFillDomainFeatureS390PVCaps(qemuCaps, domCaps); + virQEMUCapsFillDomainFeatureSGXCaps(qemuCaps, domCaps); return 0; } diff --git a/tests/domaincapsdata/bhyve_basic.x86_64.xml b/tests/domaincapsdata/bhyve_basic.x86_64.xml index 745f325531..dd054577c0 100644 --- a/tests/domaincapsdata/bhyve_basic.x86_64.xml +++ b/tests/domaincapsdata/bhyve_basic.x86_64.xml @@ -33,5 +33,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/bhyve_fbuf.x86_64.xml b/tests/domaincapsdata/bhyve_fbuf.x86_64.xml index bb11c02ae9..0b1d9c17d7 100644 --- a/tests/domaincapsdata/bhyve_fbuf.x86_64.xml +++ b/tests/domaincapsdata/bhyve_fbuf.x86_64.xml @@ -50,5 +50,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/bhyve_uefi.x86_64.xml b/tests/domaincapsdata/bhyve_uefi.x86_64.xml index dfd2360d74..69fff197a7 100644 --- a/tests/domaincapsdata/bhyve_uefi.x86_64.xml +++ b/tests/domaincapsdata/bhyve_uefi.x86_64.xml @@ -42,5 +42,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/empty.xml b/tests/domaincapsdata/empty.xml index d3e2d89b60..97752ca04a 100644 --- a/tests/domaincapsdata/empty.xml +++ b/tests/domaincapsdata/empty.xml @@ -13,5 +13,6 @@ </devices> <features> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/libxl-xenfv.xml b/tests/domaincapsdata/libxl-xenfv.xml index cc5b3847e2..c71d759517 100644 --- a/tests/domaincapsdata/libxl-xenfv.xml +++ b/tests/domaincapsdata/libxl-xenfv.xml @@ -76,5 +76,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/libxl-xenpv.xml b/tests/domaincapsdata/libxl-xenpv.xml index 325f1e50b3..8ae2370b7e 100644 --- a/tests/domaincapsdata/libxl-xenpv.xml +++ b/tests/domaincapsdata/libxl-xenpv.xml @@ -66,5 +66,6 @@ <vmcoreinfo supported='no'/> <genid supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml index ea9737d9ce..665e2b6401 100644 --- a/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0-q35.x86_64.xml @@ -187,5 +187,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml index cccc6830f9..de19ae76e0 100644 --- a/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0-tcg.x86_64.xml @@ -200,5 +200,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0.s390x.xml b/tests/domaincapsdata/qemu_2.11.0.s390x.xml index 804bf8020e..5249aca8c1 100644 --- a/tests/domaincapsdata/qemu_2.11.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.11.0.s390x.xml @@ -215,5 +215,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.11.0.x86_64.xml b/tests/domaincapsdata/qemu_2.11.0.x86_64.xml index 3a8aa2ab71..3186231683 100644 --- a/tests/domaincapsdata/qemu_2.11.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.11.0.x86_64.xml @@ -187,5 +187,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml index 0dc5995c09..7aa4ba7d2c 100644 --- a/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-q35.x86_64.xml @@ -208,5 +208,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml index 575506d852..a08a9b6a8e 100644 --- a/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-tcg.x86_64.xml @@ -218,5 +218,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml index 2074c89875..e4518988c6 100644 --- a/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.12.0-virt.aarch64.xml @@ -168,5 +168,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.aarch64.xml b/tests/domaincapsdata/qemu_2.12.0.aarch64.xml index a93313f980..ff1158d107 100644 --- a/tests/domaincapsdata/qemu_2.12.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.aarch64.xml @@ -162,5 +162,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.ppc64.xml b/tests/domaincapsdata/qemu_2.12.0.ppc64.xml index cb3edcbd56..681b4bc7bd 100644 --- a/tests/domaincapsdata/qemu_2.12.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.ppc64.xml @@ -132,5 +132,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.s390x.xml b/tests/domaincapsdata/qemu_2.12.0.s390x.xml index 5c3d9ce7db..7f7b8a1911 100644 --- a/tests/domaincapsdata/qemu_2.12.0.s390x.xml +++ b/tests/domaincapsdata/qemu_2.12.0.s390x.xml @@ -215,5 +215,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml index c8a5558536..32f1816ad6 100644 --- a/tests/domaincapsdata/qemu_2.12.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_2.12.0.x86_64.xml @@ -208,5 +208,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml index 4f80439eb4..740ff9062d 100644 --- a/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0-q35.x86_64.xml @@ -204,5 +204,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml index 301101095c..09c4c07471 100644 --- a/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0-tcg.x86_64.xml @@ -216,5 +216,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.ppc64.xml b/tests/domaincapsdata/qemu_3.0.0.ppc64.xml index 8605db5cc8..039ee5c99c 100644 --- a/tests/domaincapsdata/qemu_3.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_3.0.0.ppc64.xml @@ -134,5 +134,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.s390x.xml b/tests/domaincapsdata/qemu_3.0.0.s390x.xml index f49b6907ff..63a128fab5 100644 --- a/tests/domaincapsdata/qemu_3.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_3.0.0.s390x.xml @@ -222,5 +222,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.0.0.x86_64.xml b/tests/domaincapsdata/qemu_3.0.0.x86_64.xml index 650728566e..a8cd693bbd 100644 --- a/tests/domaincapsdata/qemu_3.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.0.0.x86_64.xml @@ -204,5 +204,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml index c4277c53a1..381cc9a4ec 100644 --- a/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0-q35.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml index 2a65cb0ad9..28868f1c0b 100644 --- a/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0-tcg.x86_64.xml @@ -226,5 +226,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0.ppc64.xml b/tests/domaincapsdata/qemu_3.1.0.ppc64.xml index 8035f7230a..3176d7044f 100644 --- a/tests/domaincapsdata/qemu_3.1.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_3.1.0.ppc64.xml @@ -134,5 +134,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_3.1.0.x86_64.xml b/tests/domaincapsdata/qemu_3.1.0.x86_64.xml index 6e3ddda356..db9bb1dd9f 100644 --- a/tests/domaincapsdata/qemu_3.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_3.1.0.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml index 8f3911b4b3..b99301af1f 100644 --- a/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-q35.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml index a4dc7bafc9..da58e85b72 100644 --- a/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-tcg.x86_64.xml @@ -226,5 +226,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml index 7108efe3b4..65aa9403c5 100644 --- a/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.0.0-virt.aarch64.xml @@ -175,5 +175,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.aarch64.xml b/tests/domaincapsdata/qemu_4.0.0.aarch64.xml index 1e7db635d0..d3e2ac0621 100644 --- a/tests/domaincapsdata/qemu_4.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.aarch64.xml @@ -169,5 +169,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.ppc64.xml b/tests/domaincapsdata/qemu_4.0.0.ppc64.xml index f109d36266..076820c5bc 100644 --- a/tests/domaincapsdata/qemu_4.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.ppc64.xml @@ -135,5 +135,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.s390x.xml b/tests/domaincapsdata/qemu_4.0.0.s390x.xml index b810ad737a..821d467bd9 100644 --- a/tests/domaincapsdata/qemu_4.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_4.0.0.s390x.xml @@ -232,5 +232,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.0.0.x86_64.xml b/tests/domaincapsdata/qemu_4.0.0.x86_64.xml index 24e732d9c3..3dac8ff1ae 100644 --- a/tests/domaincapsdata/qemu_4.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.0.0.x86_64.xml @@ -207,5 +207,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml index 3ee7feea48..2f9dc00689 100644 --- a/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0-q35.x86_64.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml index b20c02cb68..13540675b6 100644 --- a/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0-tcg.x86_64.xml @@ -229,5 +229,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml index 0f1d398e2c..bb7d6b9219 100644 --- a/tests/domaincapsdata/qemu_4.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.1.0.x86_64.xml @@ -213,5 +213,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml index c8a77cdd41..9fef4ccd37 100644 --- a/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-q35.x86_64.xml @@ -221,5 +221,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml index d0ee3f7b7a..76636c0c37 100644 --- a/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-tcg.x86_64.xml @@ -236,5 +236,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml index 05d606967b..1a87fc417b 100644 --- a/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.2.0-virt.aarch64.xml @@ -177,5 +177,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.aarch64.xml b/tests/domaincapsdata/qemu_4.2.0.aarch64.xml index f19ad5e6db..943c3605d8 100644 --- a/tests/domaincapsdata/qemu_4.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.aarch64.xml @@ -171,5 +171,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.ppc64.xml b/tests/domaincapsdata/qemu_4.2.0.ppc64.xml index 4c3a2c6d98..e0187041db 100644 --- a/tests/domaincapsdata/qemu_4.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.ppc64.xml @@ -141,5 +141,6 @@ <backingStoreInput supported='no'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.s390x.xml b/tests/domaincapsdata/qemu_4.2.0.s390x.xml index fb162ea578..8150e5119a 100644 --- a/tests/domaincapsdata/qemu_4.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_4.2.0.s390x.xml @@ -247,5 +247,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml index 6578fd04b6..8f3edfce70 100644 --- a/tests/domaincapsdata/qemu_4.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_4.2.0.x86_64.xml @@ -221,5 +221,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml index 8a6797c2f1..4c6ea67c99 100644 --- a/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-q35.x86_64.xml @@ -223,5 +223,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml index d277c96426..e0536347e5 100644 --- a/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-tcg.x86_64.xml @@ -238,5 +238,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml index f8cea230d9..3a70b34001 100644 --- a/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.0.0-virt.aarch64.xml @@ -186,5 +186,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml index ab72b7ffeb..6a8c1027c0 100644 --- a/tests/domaincapsdata/qemu_5.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.aarch64.xml @@ -180,5 +180,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml index 5772045e35..0910a0e3bf 100644 --- a/tests/domaincapsdata/qemu_5.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.ppc64.xml @@ -146,5 +146,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml index 51ca1d98e0..74f297c2e7 100644 --- a/tests/domaincapsdata/qemu_5.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.0.0.x86_64.xml @@ -223,5 +223,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml index 3468fb2e72..ceafdd35e7 100644 --- a/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0-q35.x86_64.xml @@ -224,5 +224,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml index 4f1ffbb2ba..ae9754a14c 100644 --- a/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0-tcg.x86_64.xml @@ -238,5 +238,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0.sparc.xml b/tests/domaincapsdata/qemu_5.1.0.sparc.xml index 5c1c0c4680..ae8474a696 100644 --- a/tests/domaincapsdata/qemu_5.1.0.sparc.xml +++ b/tests/domaincapsdata/qemu_5.1.0.sparc.xml @@ -113,5 +113,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml index 8ff49c7899..37d053c086 100644 --- a/tests/domaincapsdata/qemu_5.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.1.0.x86_64.xml @@ -224,5 +224,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml index 2301a475eb..4e68dc46f4 100644 --- a/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-q35.x86_64.xml @@ -224,5 +224,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml index 6cff0f815e..a8914a90b2 100644 --- a/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-tcg.x86_64.xml @@ -238,5 +238,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml index a863a6052d..41bb7ecb45 100644 --- a/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.2.0-virt.aarch64.xml @@ -186,5 +186,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml index ab72b7ffeb..6a8c1027c0 100644 --- a/tests/domaincapsdata/qemu_5.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.aarch64.xml @@ -180,5 +180,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml index 051b7d43a8..17f6f71bf9 100644 --- a/tests/domaincapsdata/qemu_5.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.ppc64.xml @@ -146,5 +146,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.s390x.xml b/tests/domaincapsdata/qemu_5.2.0.s390x.xml index 2a2ca8abcf..496c08dd34 100644 --- a/tests/domaincapsdata/qemu_5.2.0.s390x.xml +++ b/tests/domaincapsdata/qemu_5.2.0.s390x.xml @@ -249,5 +249,6 @@ <backup supported='no'/> <s390-pv supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml index 41a54985d7..df653b95e3 100644 --- a/tests/domaincapsdata/qemu_5.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_5.2.0.x86_64.xml @@ -224,5 +224,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml index 4595e70f61..95627a1f9c 100644 --- a/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0-q35.x86_64.xml @@ -230,5 +230,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml index 65f4459bcb..4ac6365cad 100644 --- a/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0-tcg.x86_64.xml @@ -244,5 +244,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml index 61eab9de0e..bda348ac18 100644 --- a/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_6.0.0-virt.aarch64.xml @@ -187,5 +187,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0.aarch64.xml b/tests/domaincapsdata/qemu_6.0.0.aarch64.xml index fa722b5fd3..d1478dedde 100644 --- a/tests/domaincapsdata/qemu_6.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_6.0.0.aarch64.xml @@ -181,5 +181,6 @@ <backingStoreInput supported='yes'/> <backup supported='no'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0.s390x.xml b/tests/domaincapsdata/qemu_6.0.0.s390x.xml index 13fa3a637e..ccb6536dfc 100644 --- a/tests/domaincapsdata/qemu_6.0.0.s390x.xml +++ b/tests/domaincapsdata/qemu_6.0.0.s390x.xml @@ -250,5 +250,6 @@ <backup supported='no'/> <s390-pv supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml index a6fa374211..621cf5032c 100644 --- a/tests/domaincapsdata/qemu_6.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.0.0.x86_64.xml @@ -230,5 +230,6 @@ <maxGuests>59</maxGuests> <maxESGuests>450</maxESGuests> </sev> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml index f4d0fcf673..93194d4f99 100644 --- a/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0-q35.x86_64.xml @@ -226,5 +226,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml index 40bc875e3c..9828fb4192 100644 --- a/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0-tcg.x86_64.xml @@ -239,5 +239,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml index 67fc449f5d..0948e9cf14 100644 --- a/tests/domaincapsdata/qemu_6.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.1.0.x86_64.xml @@ -226,5 +226,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml index 9d68c0a404..5ef1006b81 100644 --- a/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0-q35.x86_64.xml @@ -226,5 +226,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml index a439dda190..5731369514 100644 --- a/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0-tcg.x86_64.xml @@ -240,5 +240,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml index f6045623f5..7494df031f 100644 --- a/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_6.2.0-virt.aarch64.xml @@ -189,5 +189,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0.aarch64.xml b/tests/domaincapsdata/qemu_6.2.0.aarch64.xml index 35e18adcd5..2946a36b04 100644 --- a/tests/domaincapsdata/qemu_6.2.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_6.2.0.aarch64.xml @@ -183,5 +183,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml index 8fed9d30b7..4213cc2988 100644 --- a/tests/domaincapsdata/qemu_6.2.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_6.2.0.ppc64.xml @@ -144,5 +144,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml index 0f89790b60..0dc51619f8 100644 --- a/tests/domaincapsdata/qemu_6.2.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_6.2.0.x86_64.xml @@ -226,5 +226,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml index 1f56616587..3f1ce8028c 100644 --- a/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0-q35.x86_64.xml @@ -227,5 +227,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml index 9ed9123f7d..c113c98360 100644 --- a/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0-tcg.x86_64.xml @@ -241,5 +241,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml b/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml index 7a8cb9f113..514f673e4c 100644 --- a/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml +++ b/tests/domaincapsdata/qemu_7.0.0-virt.aarch64.xml @@ -189,5 +189,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0.aarch64.xml b/tests/domaincapsdata/qemu_7.0.0.aarch64.xml index d48c87dc3a..797affc12f 100644 --- a/tests/domaincapsdata/qemu_7.0.0.aarch64.xml +++ b/tests/domaincapsdata/qemu_7.0.0.aarch64.xml @@ -183,5 +183,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml index 942c721afd..68d51bf4b1 100644 --- a/tests/domaincapsdata/qemu_7.0.0.ppc64.xml +++ b/tests/domaincapsdata/qemu_7.0.0.ppc64.xml @@ -146,5 +146,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml index 71532ad0ed..c02afe0f40 100644 --- a/tests/domaincapsdata/qemu_7.0.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.0.0.x86_64.xml @@ -227,5 +227,9 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='yes'> + <flc>no</flc> + <epc_size unit='KiB'>1</epc_size> + </sgx> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml index b6bb9e3ffe..ee82ea900b 100644 --- a/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0-q35.x86_64.xml @@ -227,5 +227,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml index cd14a10f05..f0c1621f6c 100644 --- a/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0-tcg.x86_64.xml @@ -241,5 +241,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> diff --git a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml index 58bce4251e..409fcc96b2 100644 --- a/tests/domaincapsdata/qemu_7.1.0.x86_64.xml +++ b/tests/domaincapsdata/qemu_7.1.0.x86_64.xml @@ -227,5 +227,6 @@ <backingStoreInput supported='yes'/> <backup supported='yes'/> <sev supported='no'/> + <sgx supported='no'/> </features> </domainCapabilities> -- 2.17.1

From: Lin Yang <lin.a.yang@intel.com> <devices> ... <memory model='sgx-epc'> <target> <size unit='KiB'>512</size> </target> </memory> ... </devices> Signed-off-by: Lin Yang <lin.a.yang@intel.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- docs/formatdomain.rst | 9 +++- src/conf/domain_conf.c | 6 +++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 16 ++++++ src/conf/schemas/domaincommon.rng | 1 + src/qemu/qemu_alias.c | 3 ++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 38 +++++++++----- src/qemu/qemu_domain_address.c | 6 +++ src/qemu/qemu_driver.c | 1 + src/qemu/qemu_process.c | 2 + src/qemu/qemu_validate.c | 8 +++ src/security/security_apparmor.c | 1 + src/security/security_dac.c | 2 + src/security/security_selinux.c | 2 + tests/qemuxml2argvdata/sgx-epc.xml | 36 +++++++++++++ .../sgx-epc.x86_64-6.2.0.xml | 52 +++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 18 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.xml create mode 100644 tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c1e99951a6..20aee6c639 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7859,6 +7859,11 @@ Example: usage of the memory devices <current unit='KiB'>524288</current> </target> </memory> + <memory model='sgx-epc'> + <target> + <size unit='KiB'>16384</size> + </target> + </memory> </devices> ... @@ -7867,7 +7872,9 @@ Example: usage of the memory devices 1.2.14` Provide ``nvdimm`` model that adds a Non-Volatile DIMM module. :since:`Since 3.2.0` Provide ``virtio-pmem`` model to add a paravirtualized persistent memory device. :since:`Since 7.1.0` Provide ``virtio-mem`` model - to add paravirtualized memory device. :since:`Since 7.9.0` + to add paravirtualized memory device. :since:`Since 7.9.0` Provide + ``sgx-epc`` model to add a SGX enclave page cache (EPC) memory to the guest. + :since:`Since 8.4.0 and QEMU 6.2.0` ``access`` An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 70562cc993..ebd919083d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1430,6 +1430,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel, "nvdimm", "virtio-pmem", "virtio-mem", + "sgx-epc", ); VIR_ENUM_IMPL(virDomainShmemModel, @@ -5641,6 +5642,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDef *mem, case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -14596,6 +14598,7 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, def->nvdimmPath = virXPathString("string(./path)", ctxt); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -14664,6 +14667,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } @@ -16460,6 +16464,7 @@ virDomainMemoryFindByDefInternal(virDomainDef *def, continue; break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -25935,6 +25940,7 @@ virDomainMemorySourceDefFormat(virBuffer *buf, virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->nvdimmPath); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2e2da0c69c..8bbaacde38 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2540,6 +2540,7 @@ typedef enum { VIR_DOMAIN_MEMORY_MODEL_NVDIMM, /* nvdimm memory device */ VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */ VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM, /* virtio-mem memory device */ + VIR_DOMAIN_MEMORY_MODEL_SGX_EPC, /* SGX enclave page cache */ VIR_DOMAIN_MEMORY_MODEL_LAST } virDomainMemoryModel; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 18eb8d697d..e25d5b663c 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -2159,6 +2159,22 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem, case VIR_DOMAIN_MEMORY_MODEL_DIMM: break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("memory device address is not supported for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + + if (mem->targetNode != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("NUMA nodes is not supported for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 2544864eb4..f00d3692f7 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6718,6 +6718,7 @@ <value>nvdimm</value> <value>virtio-pmem</value> <value>virtio-mem</value> + <value>sgx-epc</value> </choice> </attribute> <optional> diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 8c2f055604..e5a946cbed 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -516,6 +516,9 @@ qemuAssignDeviceMemoryAlias(virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: prefix = "virtiomem"; break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + prefix = "epc"; + break; case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a52ba70066..4807b137b6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4041,6 +4041,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, return NULL; break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4305d5db06..2adf346caa 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8438,6 +8438,7 @@ qemuDomainUpdateMemoryDeviceInfo(virQEMUDriver *driver, break; case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -9119,6 +9120,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, } break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hotplug are not supported for the %s device"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: return -1; @@ -9154,7 +9161,7 @@ int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, const virDomainMemoryDef *mem) { - unsigned int nmems = def->nmems; + unsigned int hotplugNum = 0; unsigned long long hotplugSpace; unsigned long long hotplugMemory = 0; size_t i; @@ -9162,15 +9169,27 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, hotplugSpace = def->mem.max_memory - virDomainDefGetMemoryInitial(def); if (mem) { - nmems++; + hotplugNum++; hotplugMemory = mem->size; if (qemuDomainDefValidateMemoryHotplugDevice(mem, def) < 0) return -1; } + for (i = 0; i < def->nmems; i++) { + /* sgx epc memory does not support hotplug */ + if (def->mems[i]->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) { + hotplugMemory += def->mems[i]->size; + hotplugNum++; + /* already existing devices don't need to be checked on hotplug */ + if (!mem && + qemuDomainDefValidateMemoryHotplugDevice(def->mems[i], def) < 0) + return -1; + } + } + if (!virDomainDefHasMemoryHotplug(def)) { - if (nmems) { + if (hotplugNum) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("cannot use/hotplug a memory device when domain " "'maxMemory' is not defined")); @@ -9193,22 +9212,13 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, } } - if (nmems > def->mem.memory_slots) { + if (hotplugNum > def->mem.memory_slots) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("memory device count '%u' exceeds slots count '%u'"), - nmems, def->mem.memory_slots); + hotplugNum, def->mem.memory_slots); return -1; } - for (i = 0; i < def->nmems; i++) { - hotplugMemory += def->mems[i]->size; - - /* already existing devices don't need to be checked on hotplug */ - if (!mem && - qemuDomainDefValidateMemoryHotplugDevice(def->mems[i], def) < 0) - return -1; - } - if (hotplugMemory > hotplugSpace) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("memory device total size exceeds hotplug space")); diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index 753733d1b9..a111ae4d0c 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -389,6 +389,7 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } @@ -1039,6 +1040,7 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDef *dev, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: return 0; } @@ -2421,6 +2423,7 @@ qemuDomainAssignDevicePCISlots(virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } @@ -3081,6 +3084,7 @@ qemuDomainAssignMemoryDeviceSlot(virDomainObj *vm, return qemuDomainEnsurePCIAddress(vm, &dev); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -3107,6 +3111,7 @@ qemuDomainReleaseMemoryDeviceSlot(virDomainObj *vm, qemuDomainReleaseDeviceAddress(vm, &mem->info); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -3140,6 +3145,7 @@ qemuDomainAssignMemorySlots(virDomainDef *def) case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: /* handled in qemuDomainAssignPCIAddresses() */ break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 702fd0239c..39b2b25a48 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7022,6 +7022,7 @@ qemuDomainChangeMemoryLiveValidateChange(const virDomainMemoryDef *oldDef, case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: virReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("cannot modify memory of model '%s'"), diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 07e467d01e..0aa8ff05b5 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3831,6 +3831,7 @@ qemuProcessDomainMemoryDefNeedHugepagesPath(const virDomainMemoryDef *mem, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: /* None of these can be backed by hugepages. */ return false; @@ -3905,6 +3906,7 @@ qemuProcessNeedMemoryBackingPath(virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: /* Backed by user provided path. Not stored in memory * backing dir anyway. */ diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index 6ff61d91fa..f2c7a496a6 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5080,6 +5080,14 @@ qemuValidateDomainDeviceDefMemory(virDomainMemoryDef *mem, } break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("sgx epc isn't supported by this QEMU binary")); + return -1; + } + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 55c0193940..e44f58f7ab 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -687,6 +687,7 @@ AppArmorSetMemoryLabel(virSecurityManager *mgr, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 5b840f4225..d7252f8953 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1852,6 +1852,7 @@ virSecurityDACRestoreMemoryLabel(virSecurityManager *mgr, case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: ret = 0; @@ -2037,6 +2038,7 @@ virSecurityDACSetMemoryLabel(virSecurityManager *mgr, case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: ret = 0; diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 6f02baf2ce..b95fb14c32 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1582,6 +1582,7 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManager *mgr, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } @@ -1610,6 +1611,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManager *mgr, case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: ret = 0; diff --git a/tests/qemuxml2argvdata/sgx-epc.xml b/tests/qemuxml2argvdata/sgx-epc.xml new file mode 100644 index 0000000000..65ae8ae296 --- /dev/null +++ b/tests/qemuxml2argvdata/sgx-epc.xml @@ -0,0 +1,36 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='q35'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memory model='sgx-epc'> + <target> + <size unit='MiB'>64</size> + </target> + </memory> + <memory model='sgx-epc'> + <target> + <size unit='MiB'>16</size> + </target> + </memory> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml b/tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml new file mode 100644 index 0000000000..06cc3e7a44 --- /dev/null +++ b/tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml @@ -0,0 +1,52 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory unit='KiB'>219100</memory> + <currentMemory unit='KiB'>219100</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='x86_64' machine='pc-q35-6.2'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + </cpu> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-x86_64</emulator> + <controller type='pci' index='0' model='pcie-root'/> + <controller type='usb' index='0' model='none'/> + <controller type='sata' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x1f' function='0x2'/> + </controller> + <controller type='pci' index='1' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='1' port='0x8'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x0' multifunction='on'/> + </controller> + <controller type='pci' index='2' model='pcie-root-port'> + <model name='pcie-root-port'/> + <target chassis='2' port='0x9'/> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x01' slot='0x00' function='0x0'/> + </memballoon> + <memory model='sgx-epc'> + <target> + <size unit='KiB'>65536</size> + </target> + </memory> + <memory model='sgx-epc'> + <target> + <size unit='KiB'>16384</size> + </target> + </memory> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index a8e1cb2400..1ef919036a 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1487,6 +1487,8 @@ mymain(void) DO_TEST_CAPS_LATEST("channel-qemu-vdagent"); DO_TEST_CAPS_LATEST("channel-qemu-vdagent-features"); + DO_TEST_CAPS_VER("sgx-epc", "6.2.0"); + cleanup: if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.17.1

On 5/18/22 09:59, Haibin Huang wrote:
From: Lin Yang <lin.a.yang@intel.com>
<devices> ... <memory model='sgx-epc'> <target> <size unit='KiB'>512</size> </target> </memory> ... </devices>
Signed-off-by: Lin Yang <lin.a.yang@intel.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- docs/formatdomain.rst | 9 +++- src/conf/domain_conf.c | 6 +++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 16 ++++++ src/conf/schemas/domaincommon.rng | 1 + src/qemu/qemu_alias.c | 3 ++ src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 38 +++++++++----- src/qemu/qemu_domain_address.c | 6 +++ src/qemu/qemu_driver.c | 1 + src/qemu/qemu_process.c | 2 + src/qemu/qemu_validate.c | 8 +++ src/security/security_apparmor.c | 1 + src/security/security_dac.c | 2 + src/security/security_selinux.c | 2 + tests/qemuxml2argvdata/sgx-epc.xml | 36 +++++++++++++ .../sgx-epc.x86_64-6.2.0.xml | 52 +++++++++++++++++++ tests/qemuxml2xmltest.c | 2 + 18 files changed, 172 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.xml create mode 100644 tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml
diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index c1e99951a6..20aee6c639 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7859,6 +7859,11 @@ Example: usage of the memory devices <current unit='KiB'>524288</current> </target> </memory> + <memory model='sgx-epc'> + <target> + <size unit='KiB'>16384</size> + </target> + </memory> </devices> ...
@@ -7867,7 +7872,9 @@ Example: usage of the memory devices 1.2.14` Provide ``nvdimm`` model that adds a Non-Volatile DIMM module. :since:`Since 3.2.0` Provide ``virtio-pmem`` model to add a paravirtualized persistent memory device. :since:`Since 7.1.0` Provide ``virtio-mem`` model - to add paravirtualized memory device. :since:`Since 7.9.0` + to add paravirtualized memory device. :since:`Since 7.9.0` Provide + ``sgx-epc`` model to add a SGX enclave page cache (EPC) memory to the guest. + :since:`Since 8.4.0 and QEMU 6.2.0`
``access`` An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 70562cc993..ebd919083d 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1430,6 +1430,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel, "nvdimm", "virtio-pmem", "virtio-mem", + "sgx-epc", );
VIR_ENUM_IMPL(virDomainShmemModel, @@ -5641,6 +5642,7 @@ virDomainMemoryDefPostParse(virDomainMemoryDef *mem,
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -14596,6 +14598,7 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, def->nvdimmPath = virXPathString("string(./path)", ctxt); break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -14664,6 +14667,7 @@ virDomainMemoryTargetDefParseXML(xmlNodePtr node, case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; } @@ -16460,6 +16464,7 @@ virDomainMemoryFindByDefInternal(virDomainDef *def, continue; break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -25935,6 +25940,7 @@ virDomainMemorySourceDefFormat(virBuffer *buf, virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->nvdimmPath); break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 2e2da0c69c..8bbaacde38 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2540,6 +2540,7 @@ typedef enum { VIR_DOMAIN_MEMORY_MODEL_NVDIMM, /* nvdimm memory device */ VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */ VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM, /* virtio-mem memory device */ + VIR_DOMAIN_MEMORY_MODEL_SGX_EPC, /* SGX enclave page cache */
VIR_DOMAIN_MEMORY_MODEL_LAST } virDomainMemoryModel; diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 18eb8d697d..e25d5b663c 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -2159,6 +2159,22 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem, case VIR_DOMAIN_MEMORY_MODEL_DIMM: break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("memory device address is not supported for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + + if (mem->targetNode != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("NUMA nodes is not supported for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincommon.rng index 2544864eb4..f00d3692f7 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6718,6 +6718,7 @@ <value>nvdimm</value> <value>virtio-pmem</value> <value>virtio-mem</value> + <value>sgx-epc</value> </choice> </attribute> <optional> diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 8c2f055604..e5a946cbed 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -516,6 +516,9 @@ qemuAssignDeviceMemoryAlias(virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: prefix = "virtiomem"; break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + prefix = "epc"; + break; case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index a52ba70066..4807b137b6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4041,6 +4041,7 @@ qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, return NULL; break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: default: diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4305d5db06..2adf346caa 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8438,6 +8438,7 @@ qemuDomainUpdateMemoryDeviceInfo(virQEMUDriver *driver, break;
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -9119,6 +9120,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, } break;
+ case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hotplug are not supported for the %s device"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: return -1; @@ -9154,7 +9161,7 @@ int qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, const virDomainMemoryDef *mem) { - unsigned int nmems = def->nmems; + unsigned int hotplugNum = 0; unsigned long long hotplugSpace; unsigned long long hotplugMemory = 0; size_t i; @@ -9162,15 +9169,27 @@ qemuDomainDefValidateMemoryHotplug(const virDomainDef *def, hotplugSpace = def->mem.max_memory - virDomainDefGetMemoryInitial(def);
if (mem) { - nmems++; + hotplugNum++; hotplugMemory = mem->size;
if (qemuDomainDefValidateMemoryHotplugDevice(mem, def) < 0) return -1; }
+ for (i = 0; i < def->nmems; i++) { + /* sgx epc memory does not support hotplug */ + if (def->mems[i]->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) {
This is very, very easy to overlook. I mean the condition. Also, notice how when you added new memory type compiler identified all the places you need to adjust? That's because I've rewrote the code to use switch() everywhere. And this new code goes against that direction.
+ hotplugMemory += def->mems[i]->size; + hotplugNum++; + /* already existing devices don't need to be checked on hotplug */ + if (!mem && + qemuDomainDefValidateMemoryHotplugDevice(def->mems[i], def) < 0) + return -1; + } + }
Michal

On 5/30/22, 6:10 AM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
+ for (i = 0; i < def->nmems; i++) { + /* sgx epc memory does not support hotplug */ + if (def->mems[i]->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) {
This is very, very easy to overlook. I mean the condition. Also, notice how when you added new memory type compiler identified all the places you need to adjust? That's because I've rewrote the code to use switch() everywhere. And this new code goes against that direction.
Thanks for pointing this out. I will update it to use switch() style instead of if condition. Thanks, Lin.

From: Lin Yang <lin.a.yang@intel.com> According to the result parsing from xml, add the argument of SGX EPC memory backend into QEMU command line: #qemu-system-x86_64 \ ...... \ -object memory-backend-epc,id=memepc0,size=64M,prealloc=on \ -object memory-backend-epc,id=memepc1,size=28M \ -machine sgx-epc.0.memdev=memepc0,sgx-epc.1.memdev=memepc1 Signed-off-by: Lin Yang <lin.a.yang@intel.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/qemu/qemu_alias.c | 3 +- src/qemu/qemu_command.c | 53 +++++++++++++++++-- .../sgx-epc.x86_64-6.2.0.args | 37 +++++++++++++ tests/qemuxml2argvtest.c | 2 + 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index e5a946cbed..03c79bcf0e 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -467,7 +467,8 @@ qemuDeviceMemoryGetAliasID(virDomainDef *def, * valid */ if (!oldAlias && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM && - mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM) + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) return mem->info.addr.dimm.slot; for (i = 0; i < def->nmems; i++) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4807b137b6..9c83f0e168 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3774,6 +3774,10 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, if (systemMemory) disableCanonicalPath = true; + } else if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) { + backendType = "memory-backend-epc"; + if (!priv->memPrealloc) + prealloc = true; } else if (useHugepage || mem->nvdimmPath || memAccess || def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { @@ -3934,6 +3938,11 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, _("this qemu doesn't support the " "memory-backend-memfd object")); return -1; + } else if (STREQ(backendType, "memory-backend-epc") && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SGX_EPC)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the memory-backend-epc object")); + return -1; } rc = 0; @@ -6979,6 +6988,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, virCPUDef *cpu = def->cpu; g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; size_t i; + int epcNum = 0; virCommandAddArg(cmd, "-machine"); virBufferAdd(&buf, def->os.machine, -1); @@ -7199,6 +7209,25 @@ qemuBuildMachineCommandLine(virCommand *cmd, virBufferAddLit(&buf, ",graphics=off"); } + /* add sgx epc memory to -machine parameter */ + for (i = 0; i < def->nmems; i++) { + switch ((virDomainMemoryModel) def->mems[i]->model) { + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virBufferAsprintf(&buf, ",sgx-epc.%d.memdev=mem%s", epcNum++, + def->mems[i]->info.alias); + + break; + + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } + } + virCommandAddArgBuffer(cmd, &buf); return 0; @@ -7779,11 +7808,27 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd, if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv) < 0) return -1; - if (!(props = qemuBuildMemoryDeviceProps(cfg, priv, def, def->mems[i]))) - return -1; + switch ((virDomainMemoryModel) def->mems[i]->model) { + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + if (!(props = qemuBuildMemoryDeviceProps(cfg, priv, def, def->mems[i]))) + return -1; - if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, priv->qemuCaps) < 0) - return -1; + if (qemuBuildDeviceCommandlineFromJSON(cmd, props, def, priv->qemuCaps) < 0) + return -1; + + break; + + /* sgx epc memory will be added to -machine parameter, so skip here */ + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + break; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } } return 0; diff --git a/tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args b/tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args new file mode 100644 index 0000000000..56c476b777 --- /dev/null +++ b/tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args @@ -0,0 +1,37 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +/usr/bin/qemu-system-x86_64 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object '{"qom-type":"secret","id":"masterKey0","format":"raw","file":"/tmp/lib/domain--1-QEMUGuest1/master-key.aes"}' \ +-machine pc-q35-6.2,usb=off,dump-guest-core=off,memory-backend=pc.ram,sgx-epc.0.memdev=memepc0,sgx-epc.1.memdev=memepc1 \ +-accel tcg \ +-cpu qemu64 \ +-m 134 \ +-object '{"qom-type":"memory-backend-ram","id":"pc.ram","size":140509184}' \ +-overcommit mem-lock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device pcie-root-port,port=8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,addr=0x1 \ +-device pcie-root-port,port=9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \ +-object '{"qom-type":"memory-backend-epc","id":"memepc0","prealloc":true,"size":67108864}' \ +-object '{"qom-type":"memory-backend-epc","id":"memepc1","prealloc":true,"size":16777216}' \ +-audiodev '{"id":"audio1","driver":"none"}' \ +-device virtio-balloon-pci,id=balloon0,bus=pci.1,addr=0x0 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 7708e3ba3e..b32803474e 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3433,6 +3433,8 @@ mymain(void) /* HVF guests should not work on Linux with KVM */ DO_TEST_CAPS_LATEST_PARSE_ERROR("hvf-x86_64-q35-headless"); + DO_TEST_CAPS_VER("sgx-epc", "6.2.0"); + if (getenv("LIBVIRT_SKIP_CLEANUP") == NULL) virFileDeleteTree(fakerootdir); -- 2.17.1

On 5/18/22 09:59, Haibin Huang wrote:
From: Lin Yang <lin.a.yang@intel.com>
According to the result parsing from xml, add the argument of SGX EPC memory backend into QEMU command line:
#qemu-system-x86_64 \ ...... \ -object memory-backend-epc,id=memepc0,size=64M,prealloc=on \ -object memory-backend-epc,id=memepc1,size=28M \ -machine sgx-epc.0.memdev=memepc0,sgx-epc.1.memdev=memepc1
Signed-off-by: Lin Yang <lin.a.yang@intel.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/qemu/qemu_alias.c | 3 +- src/qemu/qemu_command.c | 53 +++++++++++++++++-- .../sgx-epc.x86_64-6.2.0.args | 37 +++++++++++++ tests/qemuxml2argvtest.c | 2 + 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index e5a946cbed..03c79bcf0e 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -467,7 +467,8 @@ qemuDeviceMemoryGetAliasID(virDomainDef *def, * valid */ if (!oldAlias && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM && - mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM) + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) return mem->info.addr.dimm.slot;
for (i = 0; i < def->nmems; i++) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4807b137b6..9c83f0e168 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3774,6 +3774,10 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, if (systemMemory) disableCanonicalPath = true;
+ } else if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) { + backendType = "memory-backend-epc"; + if (!priv->memPrealloc) + prealloc = true; } else if (useHugepage || mem->nvdimmPath || memAccess || def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
@@ -3934,6 +3938,11 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, _("this qemu doesn't support the " "memory-backend-memfd object")); return -1; + } else if (STREQ(backendType, "memory-backend-epc") && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SGX_EPC)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the memory-backend-epc object")); + return -1; }
rc = 0; @@ -6979,6 +6988,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, virCPUDef *cpu = def->cpu; g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; size_t i; + int epcNum = 0;
virCommandAddArg(cmd, "-machine"); virBufferAdd(&buf, def->os.machine, -1); @@ -7199,6 +7209,25 @@ qemuBuildMachineCommandLine(virCommand *cmd, virBufferAddLit(&buf, ",graphics=off"); }
+ /* add sgx epc memory to -machine parameter */ + for (i = 0; i < def->nmems; i++) { + switch ((virDomainMemoryModel) def->mems[i]->model) { + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virBufferAsprintf(&buf, ",sgx-epc.%d.memdev=mem%s", epcNum++, + def->mems[i]->info.alias);
So there really isn't any better way to specify sgx-epc than through -M? This way libvirt loses capability to set th device @id attribute which means we have to jump through hoops (like in your patch 2/6) when the @id value is expected. I vaguely pointing this out earlier (but maybe I just thought about pointing it out and never did - it's been a while since I've reviewed these patches), but I don't know what the consensus was. Michal

On 5/30/22, 6:09 AM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
On 5/18/22 09:59, Haibin Huang wrote:
From: Lin Yang <lin.a.yang@intel.com>
According to the result parsing from xml, add the argument of SGX EPC memory backend into QEMU command line:
#qemu-system-x86_64 \ ...... \ -object memory-backend-epc,id=memepc0,size=64M,prealloc=on \ -object memory-backend-epc,id=memepc1,size=28M \ -machine sgx-epc.0.memdev=memepc0,sgx-epc.1.memdev=memepc1
Signed-off-by: Lin Yang <lin.a.yang@intel.com> Signed-off-by: Haibin Huang <haibin.huang@intel.com> --- src/qemu/qemu_alias.c | 3 +- src/qemu/qemu_command.c | 53 +++++++++++++++++-- .../sgx-epc.x86_64-6.2.0.args | 37 +++++++++++++ tests/qemuxml2argvtest.c | 2 + 4 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc.x86_64-6.2.0.args
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index e5a946cbed..03c79bcf0e 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -467,7 +467,8 @@ qemuDeviceMemoryGetAliasID(virDomainDef *def, * valid */ if (!oldAlias && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM && - mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM) + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) return mem->info.addr.dimm.slot;
for (i = 0; i < def->nmems; i++) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4807b137b6..9c83f0e168 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3774,6 +3774,10 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, if (systemMemory) disableCanonicalPath = true;
+ } else if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) { + backendType = "memory-backend-epc"; + if (!priv->memPrealloc) + prealloc = true; } else if (useHugepage || mem->nvdimmPath || memAccess || def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) {
@@ -3934,6 +3938,11 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, _("this qemu doesn't support the " "memory-backend-memfd object")); return -1; + } else if (STREQ(backendType, "memory-backend-epc") && + !virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_SGX_EPC)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("this qemu doesn't support the memory-backend-epc object")); + return -1; }
rc = 0; @@ -6979,6 +6988,7 @@ qemuBuildMachineCommandLine(virCommand *cmd, virCPUDef *cpu = def->cpu; g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; size_t i; + int epcNum = 0;
virCommandAddArg(cmd, "-machine"); virBufferAdd(&buf, def->os.machine, -1); @@ -7199,6 +7209,25 @@ qemuBuildMachineCommandLine(virCommand *cmd, virBufferAddLit(&buf, ",graphics=off"); }
+ /* add sgx epc memory to -machine parameter */ + for (i = 0; i < def->nmems; i++) { + switch ((virDomainMemoryModel) def->mems[i]->model) { + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virBufferAsprintf(&buf, ",sgx-epc.%d.memdev=mem%s", epcNum++, + def->mems[i]->info.alias);
So there really isn't any better way to specify sgx-epc than through -M? This way libvirt loses capability to set th device @id attribute which means we have to jump through hoops (like in your patch 2/6) when the @id value is expected.
I vaguely pointing this out earlier (but maybe I just thought about pointing it out and never did - it's been a while since I've reviewed these patches), but I don't know what the consensus was.
I was not involved in the QEMU SGX patches review process and don’t know the reason why it use -machine instead of -device. The initial patch introduce separate QEMU argument -sgx-epc, but finally was updated to -machine according to the comments. https://lists.nongnu.org/archive/html/qemu-devel/2021-05/msg00644.html Thanks, Lin.

On 5/18/22 09:59, Haibin Huang wrote:
Overall, these patches work. I've raised couple of points and for your convenience you can find reworked patches here: https://gitlab.com/MichalPrivoznik/libvirt/-/commits/sgx_fixups/ Please see individual patches for comments. Michal

On 5/30/22 15:09, Michal Prívozník wrote:
On 5/18/22 09:59, Haibin Huang wrote:
Overall, these patches work. I've raised couple of points and for your convenience you can find reworked patches here:
https://gitlab.com/MichalPrivoznik/libvirt/-/commits/sgx_fixups/
Please see individual patches for comments.
So, now that I've cleaned up the code I can start to test it, but unfortunately, I don't have good news. It's not working. I've put the following into my domain XML: <memory model='sgx-epc'> <target> <size unit='KiB'>16384</size> </target> </memory> and this is the generated cmd line: -machine pc-i440fx-6.2,usb=off,dump-guest-core=off,sgx-epc.0.memdev=memepc0 \ -object '{"qom-type":"memory-backend-memfd","id":"memepc0","hugetlb":true,"hugetlbsize":2097152,"share":true,"prealloc":true,"prealloc-threads":16,"size":16777216,"host-nodes":[0],"policy":"bind"}' \ but if fails with: 2022-05-31T14:05:22.988793Z qemu-system-x86_64: Parameter 'sgx-epc.0.node' is missing Now, there are two problems here: 1) obviously, wrong backend was picked. But this is easy to solve - just move the if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) case in qemuBuildMemoryBackendProps() from the last patch before the memfd case. 2) apparently, .node attribute is required? Now, it's true that initially my guest has 2 NUMA nodes defined, but even after I remove those I still see the error. I believe I've raised this issue in one of earlier reviews: https://listman.redhat.com/archives/libvir-list/2022-February/228835.html Please make sure that in v13 this is addressed (even at expense of not working with QEMU-6.2.0 and requiring newer QEMU, if that's needed). Wasting precious reviewer bandwidth does not help anybody. Michal

On 5/31/22, 7:29 AM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
So, now that I've cleaned up the code I can start to test it, but unfortunately, I don't have good news. It's not working. I've put the following into my domain XML:
<memory model='sgx-epc'> <target> <size unit='KiB'>16384</size> </target> </memory>
and this is the generated cmd line:
-machine pc-i440fx-6.2,usb=off,dump-guest-core=off,sgx-epc.0.memdev=memepc0 \
-object '{"qom-type":"memory-backend-memfd","id":"memepc0","hugetlb":true,"hugetlbsize":2097152,"share":true,"prealloc":true,> "prealloc-threads":16,"size":16777216,"host-nodes":[0],"policy":"bind"}' \
but if fails with:
2022-05-31T14:05:22.988793Z qemu-system-x86_64: Parameter 'sgx-epc.0.node' is missing
Now, there are two problems here:
1) obviously, wrong backend was picked. But this is easy to solve - just move the if (mem->model == VIR_DOMAIN_MEMORY_MODEL_SGX_EPC) case in qemuBuildMemoryBackendProps() from the last patch before the memfd case.
Thank you so much for resolving this issue.
2) apparently, .node attribute is required? Now, it's true that initially my guest has 2 NUMA nodes defined, but even after I remove those I still see the error. I believe I've raised this issue in one of earlier reviews:
https://listman.redhat.com/archives/libvir-list/2022-February/228835.html
Please make sure that in v13 this is addressed (even at expense of not working with QEMU-6.2.0 and requiring newer QEMU, if that's needed). Wasting precious reviewer bandwidth does not help anybody.
The .node attribute is required for qemu 7.0.0, but qemu 6.2.0 doesn’t need It. Missing .node will fail with qemu 7.0.0, even only define one NUMA node. Giving it’s probably impossible to detect whether .node is needed or not, our proposal here is this patch only works with qemu 6.2.0, then support qemu 7.0.0 in another patch. It might give user a chance to choose different libvirt version, or pick up some commits to work with different qemu version. If it’s unnecessary, we can definitely only support 7.0.0 as you suggested. Thanks, Lin.

On 6/2/22 02:52, Yang, Lin A wrote:
On 5/31/22, 7:29 AM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
2) apparently, .node attribute is required? Now, it's true that
initially my guest has 2 NUMA nodes defined, but even after I remove
those I still see the error. I believe I've raised this issue in one of
earlier reviews:
https://listman.redhat.com/archives/libvir-list/2022-February/228835.html
Please make sure that in v13 this is addressed (even at expense of not
working with QEMU-6.2.0 and requiring newer QEMU, if that's needed).
Wasting precious reviewer bandwidth does not help anybody.
The .node attribute is required for qemu 7.0.0, but qemu 6.2.0 doesn’t need
It. Missing .node will fail with qemu 7.0.0, even only define one NUMA node.
Giving it’s probably impossible to detect whether .node is needed or not, our
proposal here is this patch only works with qemu 6.2.0, then support qemu 7.0.0
in another patch. It might give user a chance to choose different libvirt version,
or pick up some commits to work with different qemu version.
If it’s unnecessary, we can definitely only support 7.0.0 as you suggested.
Worst case scenario we can do a version check. It's very suboptimal because if somebody backports your patches in QEMU, libvirt will stop working despite having the version check. Therefore, I'm more inclined to just use the newest API and well, 6.2 won't work. In the long run - it's just one release that has the feature but libvirt can't use it versus plenty of releases (that come after 7.0) which have the feature and libvirt can use it. If we go this way then we'll still need version check, but the other way round: if (qemuCaps->version < 7000000) virQEMUCapsClear(qemuCaps, QEMU_CAPS_SGX_EPC); Or just exit early and don't even bother detecting SGX when version is not 7.0.0: if (qemuCaps->version < 7000000) return 0; This has the downside that when somebody backports QEMU patches to 6.2 to match the QAPI of 7.0 libvirt would still refuse to use the feature. But one can argue that at that point the maintainer should also patch libvirt (very trivial patch to remove these two lines of condition). This is the reason we like QEMU to make features introspectable - we could avoid all of this if we were able to detect .node attribute :-( Now that I look at the output of query-qmp-schema command I see that 6.2 returns: { "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int" } ], "meta-type": "object" }, while 7.0 returns: { "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int", "features": [ "deprecated" ] }, { "name": "sections", "type": "[454]" } ], "meta-type": "object" } So maybe in the end libvirt CAN know the difference without having to do any version check. We have a "dialect" of XPATH that we use to traverse the QMP schema: look at the comment above virQEMUQAPISchemaPathGet(). Michal

On 6/1/22, 11:37 PM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
Worst case scenario we can do a version check. It's very suboptimal because if somebody backports your patches in QEMU, libvirt will stop working despite having the version check.
Therefore, I'm more inclined to just use the newest API and well, 6.2 won't work. In the long run - it's just one release that has the feature but libvirt can't use it versus plenty of releases (that come after 7.0) which have the feature and libvirt can use it. If we go this way then we'll still need version check, but the other way round:
if (qemuCaps->version < 7000000) virQEMUCapsClear(qemuCaps, QEMU_CAPS_SGX_EPC);
Or just exit early and don't even bother detecting SGX when version is not 7.0.0:
if (qemuCaps->version < 7000000) return 0;
This has the downside that when somebody backports QEMU patches to 6.2 to match the QAPI of 7.0 libvirt would still refuse to use the feature. But one can argue that at that point the maintainer should also patch libvirt (very trivial patch to remove these two lines of condition).
This is the reason we like QEMU to make features introspectable - we could avoid all of this if we were able to detect .node attribute :-(
Now that I look at the output of query-qmp-schema command I see that 6.2 returns:
{ "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int" } ], "meta-type": "object" },
while 7.0 returns:
{ "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int", "features": [ "deprecated" ] }, { "name": "sections", "type": "[454]" } ], "meta-type": "object" }
So maybe in the end libvirt CAN know the difference without having to do any version check. We have a "dialect" of XPATH that we use to traverse the QMP schema: look at the comment above virQEMUQAPISchemaPathGet().
This is awesome! Thank you so much for this very informative explanation. QEMU 7.0.0 provides more NUMA info in SGX part, so if we see "sections" in QAPI schema, we can assume .node attribute is required. Let me try this solution at first. We can support both QEMU 6.2.0 and 7.0.0 in V13 patches if it is doable. Thanks, Lin.

On 6/2/22, 11:28 AM, "Yang, Lin A" <lin.a.yang@intel.com> wrote:
On 6/1/22, 11:37 PM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
Worst case scenario we can do a version check. It's very suboptimal because if somebody backports your patches in QEMU, libvirt will stop working despite having the version check.
Therefore, I'm more inclined to just use the newest API and well, 6.2 won't work. In the long run - it's just one release that has the feature but libvirt can't use it versus plenty of releases (that come after 7.0) which have the feature and libvirt can use it. If we go this way then we'll still need version check, but the other way round:
if (qemuCaps->version < 7000000) virQEMUCapsClear(qemuCaps, QEMU_CAPS_SGX_EPC);
Or just exit early and don't even bother detecting SGX when version is not 7.0.0:
if (qemuCaps->version < 7000000) return 0;
This has the downside that when somebody backports QEMU patches to 6.2 to match the QAPI of 7.0 libvirt would still refuse to use the feature. But one can argue that at that point the maintainer should also patch libvirt (very trivial patch to remove these two lines of condition).
This is the reason we like QEMU to make features introspectable - we could avoid all of this if we were able to detect .node attribute :-(
Now that I look at the output of query-qmp-schema command I see that 6.2 returns:
{ "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int" } ], "meta-type": "object" },
while 7.0 returns:
{ "name": "237", "members": [ { "name": "sgx", "type": "bool" }, { "name": "sgx1", "type": "bool" }, { "name": "sgx2", "type": "bool" }, { "name": "flc", "type": "bool" }, { "name": "section-size", "type": "int", "features": [ "deprecated" ] }, { "name": "sections", "type": "[454]" } ], "meta-type": "object" }
So maybe in the end libvirt CAN know the difference without having to do any version check. We have a "dialect" of XPATH that we use to traverse the QMP schema: look at the comment above virQEMUQAPISchemaPathGet().
This is awesome! Thank you so much for this very informative explanation. QEMU 7.0.0 provides more NUMA info in SGX part, so if we see "sections" in QAPI schema, we can assume .node attribute is required.
Let me try this solution at first. We can support both QEMU 6.2.0 and 7.0.0 in V13 patches if it is doable.
Sorry for multiple emails here. Since these patches here have been review several times, and support 7.0.0 will bring some new commits. Each update to new commit will require git rebase and resolve conflict for old commits. Is it possible that we add the feature to compare QAPI schema and detect .node, but only work with 6.2.0 in this patch and return error message for 7.0.0. After finishing this thread, we can start a new thread to support NUMA for qemu 7.0.0. Any preference? Thanks, Lin.

On Thu, Jun 02, 2022 at 22:49:15 +0000, Yang, Lin A wrote:
On 6/2/22, 11:28 AM, "Yang, Lin A" <lin.a.yang@intel.com> wrote:
On 6/1/22, 11:37 PM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
[...]
So maybe in the end libvirt CAN know the difference without having to do any version check. We have a "dialect" of XPATH that we use to traverse the QMP schema: look at the comment above virQEMUQAPISchemaPathGet().
This is awesome! Thank you so much for this very informative explanation. QEMU 7.0.0 provides more NUMA info in SGX part, so if we see "sections" in QAPI schema, we can assume .node attribute is required.
Let me try this solution at first. We can support both QEMU 6.2.0 and 7.0.0 in V13 patches if it is doable.
Sorry for multiple emails here.
Since these patches here have been review several times, and support 7.0.0 will bring some new commits. Each update to new commit will require git rebase and resolve conflict for old commits. Is it possible that we add the feature to compare QAPI schema and detect .node, but only work with 6.2.0 in this patch and return error message for 7.0.0. After finishing this thread, we can start a new thread to support NUMA for qemu 7.0.0. Any preference?
Usually we prefer if everything is done in one series, but obviously that is not always possible. In case you want to commit partially-incomplete patches you need to ensure that they behave sanely for anyone attempting to use it. This means mostly that if e.g. your code would work with qemu-6.2 and would then break with qemu-7.0 it _must_ be kept disabled. I didn't go through the conversation here, but from the above it seems that you are discussing that there are two distinct ways how to detect the presence of the feature in qemu between qemu-6.2 and qemu-7.0. If that is true then I'd simply say it's strongly preferrable to just drop the code for qemu-6.2 and just do the necessary steps to make it work with qemu-7.0. Adding another bit of code just to make it work with one extra version doesn't seem to be worth it unless you have a very good justification, because it's more code that we'll have to maintain in the end.

On 6/3/22 09:36, Peter Krempa wrote:
On Thu, Jun 02, 2022 at 22:49:15 +0000, Yang, Lin A wrote:
On 6/2/22, 11:28 AM, "Yang, Lin A" <lin.a.yang@intel.com> wrote:
On 6/1/22, 11:37 PM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
[...]
So maybe in the end libvirt CAN know the difference without having to do any version check. We have a "dialect" of XPATH that we use to traverse the QMP schema: look at the comment above virQEMUQAPISchemaPathGet().
This is awesome! Thank you so much for this very informative explanation. QEMU 7.0.0 provides more NUMA info in SGX part, so if we see "sections" in QAPI schema, we can assume .node attribute is required.
Let me try this solution at first. We can support both QEMU 6.2.0 and 7.0.0 in V13 patches if it is doable.
Sorry for multiple emails here.
Since these patches here have been review several times, and support 7.0.0 will bring some new commits. Each update to new commit will require git rebase and resolve conflict for old commits. Is it possible that we add the feature to compare QAPI schema and detect .node, but only work with 6.2.0 in this patch and return error message for 7.0.0. After finishing this thread, we can start a new thread to support NUMA for qemu 7.0.0. Any preference?
Usually we prefer if everything is done in one series, but obviously that is not always possible.
In case you want to commit partially-incomplete patches you need to ensure that they behave sanely for anyone attempting to use it.
This means mostly that if e.g. your code would work with qemu-6.2 and would then break with qemu-7.0 it _must_ be kept disabled.
I didn't go through the conversation here, but from the above it seems that you are discussing that there are two distinct ways how to detect the presence of the feature in qemu between qemu-6.2 and qemu-7.0.
More or less, yes. The feature works differently in 6.2. And the same cmd line doesn't work in 7.0.
If that is true then I'd simply say it's strongly preferrable to just drop the code for qemu-6.2 and just do the necessary steps to make it work with qemu-7.0. Adding another bit of code just to make it work with one extra version doesn't seem to be worth it unless you have a very good justification, because it's more code that we'll have to maintain in the end.
Exactly. This is what I was also suggesting, to just not bother with 6.2 at all and aim at 7.0. But it looks like Yang is aiming on supporting 6.2 too. This is going to create complicated implementation for a little benefit IMO. But I'm not the one writing patches :-) Michal

On Fri, Jun 03, 2022 at 16:43:30 +0200, Michal Prívozník wrote:
On 6/3/22 09:36, Peter Krempa wrote:
On Thu, Jun 02, 2022 at 22:49:15 +0000, Yang, Lin A wrote:
On 6/2/22, 11:28 AM, "Yang, Lin A" <lin.a.yang@intel.com> wrote:
On 6/1/22, 11:37 PM, "Michal Prívozník" <mprivozn@redhat.com> wrote:
[...]
Exactly. This is what I was also suggesting, to just not bother with 6.2 at all and aim at 7.0. But it looks like Yang is aiming on supporting 6.2 too. This is going to create complicated implementation for a little benefit IMO. But I'm not the one writing patches :-)
One thing to also consider is that we'll be the ones stuck with maintaining them once they are upstream. So I strongly suggest that only the new approach is implemented unless there are good reasons do support 6.2 too which should be properly justified or with a commitment to more upstream contributions to offset it.
participants (4)
-
Haibin Huang
-
Michal Prívozník
-
Peter Krempa
-
Yang, Lin A