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.
© 2016 - 2026 Red Hat, Inc.