From mprivozn at redhat.com Fri Jul 1 07:43:16 2022 From: mprivozn at redhat.com (Michal Privoznik) Date: Fri, 1 Jul 2022 09:43:16 +0200 Subject: [PATCH for 8.5.0] qemu_hotplug: Don't skip cleanup in qemuDomainAttachNetDevice() Message-ID: <50e87a993457e5717baedd6b504fa153c82536c8.1656661372.git.mprivozn@redhat.com> Introduced in v8.4.0-rc1~183 but the first real problem introduced in v8.4.0-rc1~170, there's a qemuBuildInterfaceConnect() call inside of qemuDomainAttachNetDevice(). If the former fails, then the function is immediately returned from instead of jumping onto the cleanup label. This is crucial, because at this point the domain definition contains 'borrowed' net definition, which is then freed, since an error was met. The domain definition is then left with a dangling pointer which leads to all sorts of different crashes. Fixes: 29d022b1eb7b2330ed224a08509e6d3a5eeecc53 Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2102009 Signed-off-by: Michal Privoznik --- src/qemu/qemu_hotplug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index ee44649d48..27e68370cf 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1265,7 +1265,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net); if (qemuBuildInterfaceConnect(vm, net, VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0) - return -1; + goto cleanup; iface_connected = true; -- 2.35.1 From jdenemar at redhat.com Fri Jul 1 08:43:16 2022 From: jdenemar at redhat.com (Jiri Denemark) Date: Fri, 1 Jul 2022 10:43:16 +0200 Subject: [PATCH for 8.5.0] qemu_hotplug: Don't skip cleanup in qemuDomainAttachNetDevice() In-Reply-To: <50e87a993457e5717baedd6b504fa153c82536c8.1656661372.git.mprivozn@redhat.com> References: <50e87a993457e5717baedd6b504fa153c82536c8.1656661372.git.mprivozn@redhat.com> Message-ID: On Fri, Jul 01, 2022 at 09:43:16 +0200, Michal Privoznik wrote: > Introduced in v8.4.0-rc1~183 but the first real problem > introduced in v8.4.0-rc1~170, there's a > qemuBuildInterfaceConnect() call inside of > qemuDomainAttachNetDevice(). If the former fails, then the > function is immediately returned from instead of jumping onto the > cleanup label. This is crucial, because at this point the domain > definition contains 'borrowed' net definition, which is then > freed, since an error was met. The domain definition is then left > with a dangling pointer which leads to all sorts of different > crashes. > > Fixes: 29d022b1eb7b2330ed224a08509e6d3a5eeecc53 > Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2102009 > Signed-off-by: Michal Privoznik > --- > src/qemu/qemu_hotplug.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c > index ee44649d48..27e68370cf 100644 > --- a/src/qemu/qemu_hotplug.c > +++ b/src/qemu/qemu_hotplug.c > @@ -1265,7 +1265,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, > VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net); > > if (qemuBuildInterfaceConnect(vm, net, VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0) > - return -1; > + goto cleanup; > > iface_connected = true; > Reviewed-by: Jiri Denemark From mprivozn at redhat.com Fri Jul 1 08:50:01 2022 From: mprivozn at redhat.com (=?UTF-8?B?TWljaGFsIFByw612b3puw61r?=) Date: Fri, 1 Jul 2022 10:50:01 +0200 Subject: [PATCH for 8.5.0] qemu_hotplug: Don't skip cleanup in qemuDomainAttachNetDevice() In-Reply-To: References: <50e87a993457e5717baedd6b504fa153c82536c8.1656661372.git.mprivozn@redhat.com> Message-ID: <4f686403-fd31-dbb3-4ed5-c7b18bd3c8ef@redhat.com> On 7/1/22 10:43, Jiri Denemark wrote: > On Fri, Jul 01, 2022 at 09:43:16 +0200, Michal Privoznik wrote: >> Introduced in v8.4.0-rc1~183 but the first real problem >> introduced in v8.4.0-rc1~170, there's a >> qemuBuildInterfaceConnect() call inside of >> qemuDomainAttachNetDevice(). If the former fails, then the >> function is immediately returned from instead of jumping onto the >> cleanup label. This is crucial, because at this point the domain >> definition contains 'borrowed' net definition, which is then >> freed, since an error was met. The domain definition is then left >> with a dangling pointer which leads to all sorts of different >> crashes. >> >> Fixes: 29d022b1eb7b2330ed224a08509e6d3a5eeecc53 >> Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2102009 >> Signed-off-by: Michal Privoznik >> --- >> src/qemu/qemu_hotplug.c | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c >> index ee44649d48..27e68370cf 100644 >> --- a/src/qemu/qemu_hotplug.c >> +++ b/src/qemu/qemu_hotplug.c >> @@ -1265,7 +1265,7 @@ qemuDomainAttachNetDevice(virQEMUDriver *driver, >> VIR_APPEND_ELEMENT_COPY(vm->def->nets, vm->def->nnets, net); >> >> if (qemuBuildInterfaceConnect(vm, net, VIR_NETDEV_VPORT_PROFILE_OP_CREATE) < 0) >> - return -1; >> + goto cleanup; >> >> iface_connected = true; >> > > Reviewed-by: Jiri Denemark > Merged, thanks. Michal From jdenemar at redhat.com Fri Jul 1 09:31:13 2022 From: jdenemar at redhat.com (Jiri Denemark) Date: Fri, 1 Jul 2022 11:31:13 +0200 (CEST) Subject: Release of libvirt-8.5.0 Message-ID: <20220701093113.48900180138@rein.int.mamuti.net> The 8.5.0 release of both libvirt and libvirt-python is tagged and signed tarballs and source RPMs are available at https://libvirt.org/sources/ https://libvirt.org/sources/python/ Thanks everybody who helped with this release by sending patches, reviewing, testing, or providing feedback. Your work is greatly appreciated. * New features * qemu: Introduce support for network backed NVRAM Users can now use remote store NVRAM image by specifying newly introduced attribute `type='network'` with `` element. * qemu: Add support for post-copy migration recovery A new ``VIR_MIGRATE_POSTCOPY_RESUME`` flag (``virsh migrate --postcopy-resume``) was introduced for recovering from a failed post-copy migration. * Introduce thread_pool_min and thread_pool_max attributes to IOThread New attributes ``thread_pool_min`` and ``thread_pool_max`` were introduced to ```` as well as new ```` element with the same attributes. This way it's possible to instruct QEMU to spawn enough worker threads for an IOThread upfront, resulting in predictable time needed to process an I/O request. * Improvements * Define a TFTP server without a DHCP server in network configuration It's now possible to define a network with no DHCP server but with a TFTP server. This may be useful when DHCP service is provided by other entity on the network than libvirt spawned dnsmasq. * Bug fixes * qemu: Restore label to temp file in qemuDomainScreenshot() When virDomainScreenshot() is called, libvirt instructs QEMU to save the screenshot into a temporary file. This file needs to be labelled correctly, so that QEMU can access it. And since the file is temporary (it's deleted after the screenshot was taken) the corresponding label restore was missing. This proven to be problematic for profile based models, like AppArmor, where the temporary files were added into the profile but never removed, which resulted in longer profile recalculation times. * qemuBuildInterfaceConnect: Initialize @tapfd array Due to an uninitialized array, unsuccessful attempt to start a guest with an ```` might have resulted in closing of a random FD and thus sudden disconnect of a client or other random failures. * qemu: Fix hotplug of network interfaces A logic bug introduced in a recent refactor was fixed. The bug caused a problem when hot-adding a network interface, which failed with the following error:: error: internal error: unable to execute QEMU command 'netdev_add': File descriptor named '(null)' has not been found * Fix ``startupPolicy`` validation for ``block`` disks Setting of ``startupPolicy`` for a block disk would result in an error due to a logic bug in a recent refactor. * qemu: Fix crash when overriding device properties via ```` element Adding an override for a device property would result in a crash of the qemu driver. Enjoy. Jirka From mprivozn at redhat.com Fri Jul 1 12:54:04 2022 From: mprivozn at redhat.com (=?UTF-8?B?TWljaGFsIFByw612b3puw61r?=) Date: Fri, 1 Jul 2022 14:54:04 +0200 Subject: [PATCH] security_selinux.c: Relabel existing mode="bind" UNIX sockets In-Reply-To: <871qv9ezmi.fsf@bigbadwolfsecurity.com> References: <871qv9ezmi.fsf@bigbadwolfsecurity.com> Message-ID: On 6/28/22 14:33, David Michael wrote: > This supports sockets created by libvirt and passed by FD using the > same method as in security_dac.c. > > Signed-off-by: David Michael > --- > > Hi, > > Custom SELinux labels are not applied to sockets when they have > mode="bind", but other security models (DAC) allow changing these > sockets. Can the same method be used to support SELinux? > > Thanks. > > David > > src/security/security_selinux.c | 6 ++++-- > tests/securityselinuxlabeldata/chardev.txt | 2 +- > 2 files changed, 5 insertions(+), 3 deletions(-) > > diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c > index e2f34a27dc..8b258c9e36 100644 > --- a/src/security/security_selinux.c > +++ b/src/security/security_selinux.c > @@ -2541,7 +2541,9 @@ virSecuritySELinuxSetChardevLabel(virSecurityManager *mgr, > break; > > case VIR_DOMAIN_CHR_TYPE_UNIX: > - if (!dev_source->data.nix.listen) { > + if (!dev_source->data.nix.listen || > + (dev_source->data.nix.path && > + virFileExists(dev_source->data.nix.path))) { I've copied the comment from corresponding _dac.c function, so that it's obvious why we are relabelling in this case too. > if (virSecuritySELinuxSetFilecon(mgr, > dev_source->data.nix.path, > imagelabel, > @@ -2618,7 +2620,7 @@ virSecuritySELinuxRestoreChardevLabel(virSecurityManager *mgr, > case VIR_DOMAIN_CHR_TYPE_UNIX: > if (!dev_source->data.nix.listen) { > if (virSecuritySELinuxRestoreFileLabel(mgr, > - dev_source->data.file.path, > + dev_source->data.nix.path, > true) < 0) > goto done; > } > diff --git a/tests/securityselinuxlabeldata/chardev.txt b/tests/securityselinuxlabeldata/chardev.txt > index 3f4b6302b9..bdb367f7a5 100644 > --- a/tests/securityselinuxlabeldata/chardev.txt > +++ b/tests/securityselinuxlabeldata/chardev.txt > @@ -2,6 +2,6 @@ > /plain.dev;system_u:object_r:svirt_image_t:s0:c41,c264 > /plain.fifo;system_u:object_r:svirt_image_t:s0:c41,c264 > /nolabel.sock; > -/plain.sock; > +/plain.sock;system_u:object_r:svirt_image_t:s0:c41,c264 > /yeslabel.sock;system_u:object_r:svirt_image_t:s0:c41,c264 > /altlabel.sock;system_u:object_r:svirt_image_custom_t:s0:c41,c264 Reviewed-by: Michal Privoznik and pushed. Congratulations on your first libvirt contribution! Michal From mprivozn at redhat.com Fri Jul 1 13:01:19 2022 From: mprivozn at redhat.com (=?UTF-8?B?TWljaGFsIFByw612b3puw61r?=) Date: Fri, 1 Jul 2022 15:01:19 +0200 Subject: [libvirt PATCH v2] tools: add virt-qmp-proxy for proxying QMP clients to libvirt QEMU guests In-Reply-To: <20220620171950.1416742-1-berrange@redhat.com> References: <20220620171950.1416742-1-berrange@redhat.com> Message-ID: <9cd7eb31-cb62-c06d-edcf-04ed81d7c33b@redhat.com> On 6/20/22 19:19, Daniel P. Berrang? wrote: > Libvirt provides QMP passthrough APIs for the QEMU driver and these are > exposed in virsh. It is not especially pleasant, however, using the raw > QMP JSON syntax. QEMU has a tool 'qmp-shell' which can speak QMP and > exposes a human friendly interactive shell. It is not possible to use > this with libvirt managed guest, however, since only one client can > attach to he QMP socket at any point in time. > > The virt-qmp-proxy tool aims to solve this problem. It opens a UNIX > socket and listens for incoming client connections, speaking QMP on > the connected socket. It will forward any QMP commands received onto > the running libvirt QEMU guest, and forward any replies back to the > QMP client. > > $ virsh start demo > $ virt-qmp-proxy demo demo.qmp & > $ qmp-shell demo.qmp > Welcome to the QMP low-level shell! > Connected to QEMU 6.2.0 > > (QEMU) query-kvm > { > "return": { > "enabled": true, > "present": true > } > } > > Note this tool of course has the same risks as the raw libvirt > QMP passthrough. It is safe to run query commands to fetch information > but commands which change the QEMU state risk disrupting libvirt's > management of QEMU, potentially resulting in data loss/corruption in > the worst case. > > Signed-off-by: Daniel P. Berrang? > --- > > Changed in v2: > > - Rewrote to not be such a gross hack, specifically > - Wired up usage of libvirt event loop for sock I/O > - Register with libvirt for QMP events > - Incrementally read from socket & try json parsing > until we get a full command, instead of assuming > a full command in one read > - Forwarding of passed FDs in both directions > (libvirt -> client untested, since AFAIK, no > QMP cmd returns FDs currently) > > > Other thought.... > > This patch is against libvirt.git but has a dependancy on the > libvirt-python.git APIs. If we put this in libvirt-client RPM > then we get a new dep on python. > > Perhaps better to have this live in libvirt-python.git/examples, > though I would like it present as a standard tool ? Another > option is to bundle with virt-install which is a python app > commonly present on virt hosts ? Or, we could have it in a separate RPM which would require libvirt-client and libvirt-python. > > docs/manpages/meson.build | 1 + > docs/manpages/virt-qmp-proxy.rst | 120 +++++++++++ > tools/meson.build | 5 + > tools/virt-qmp-proxy | 360 +++++++++++++++++++++++++++++++ > 4 files changed, 486 insertions(+) > create mode 100644 docs/manpages/virt-qmp-proxy.rst > create mode 100755 tools/virt-qmp-proxy Reviewed-by: Michal Privoznik Michal From pkrempa at redhat.com Fri Jul 1 13:46:36 2022 From: pkrempa at redhat.com (Peter Krempa) Date: Fri, 1 Jul 2022 15:46:36 +0200 Subject: [PATCHv2] storage: pool: Allow more intricate nfs protocol versions Message-ID: Treat the 'protocolVer' field as a string so that e.g. '4.1' can be used. Forbid only ',' in the string as it's a separator of arguments for mount options. Signed-off-by: Peter Krempa --- v2: - forbid ',' in the version string. docs/formatstorage.rst | 2 +- src/conf/schemas/storagepool.rng | 4 +--- src/conf/storage_conf.c | 17 ++++++++--------- src/conf/storage_conf.h | 2 +- src/storage/storage_util.c | 4 ++-- .../pool-netfs-protocol-ver-linux.argv | 2 +- .../pool-netfs-protocol-ver.xml | 2 +- .../pool-netfs-protocol-ver.xml | 2 +- 8 files changed, 16 insertions(+), 19 deletions(-) diff --git a/docs/formatstorage.rst b/docs/formatstorage.rst index ef15c0ac5c..83d7d141ac 100644 --- a/docs/formatstorage.rst +++ b/docs/formatstorage.rst @@ -350,7 +350,7 @@ following child elements: ``protocol`` For a ``netfs`` Storage Pool provide a mechanism to define which NFS protocol version number will be used to contact the server's NFS service. The - attribute ``ver`` accepts an unsigned integer as the version number to use. + attribute ``ver`` accepts the version number to use. :since:`Since 5.1.0` ``vendor`` Provides optional information about the vendor of the storage device. This diff --git a/src/conf/schemas/storagepool.rng b/src/conf/schemas/storagepool.rng index bd24b8b8d0..d81ead532a 100644 --- a/src/conf/schemas/storagepool.rng +++ b/src/conf/schemas/storagepool.rng @@ -577,9 +577,7 @@ - - - + diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c index 5da0bf20dd..79f16aadf3 100644 --- a/src/conf/storage_conf.c +++ b/src/conf/storage_conf.c @@ -483,6 +483,7 @@ virStoragePoolSourceClear(virStoragePoolSource *source) virStorageAuthDefFree(source->auth); VIR_FREE(source->vendor); VIR_FREE(source->product); + VIR_FREE(source->protocolVer); } @@ -526,7 +527,6 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolOptions *options; int n; g_autoptr(virStorageAuthDef) authdef = NULL; - g_autofree char *ver = NULL; g_autofree xmlNodePtr *nodeset = NULL; g_autofree char *sourcedir = NULL; VIR_XPATH_NODE_AUTORESTORE(ctxt) @@ -634,7 +634,7 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, } /* Option protocol version string (NFSvN) */ - if ((ver = virXPathString("string(./protocol/@ver)", ctxt))) { + if ((source->protocolVer = virXPathString("string(./protocol/@ver)", ctxt))) { if ((source->format != VIR_STORAGE_POOL_NETFS_NFS) && (source->format != VIR_STORAGE_POOL_NETFS_AUTO)) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, @@ -643,10 +643,11 @@ virStoragePoolDefParseSource(xmlXPathContextPtr ctxt, virStoragePoolFormatFileSystemNetTypeToString(source->format)); return -1; } - if (virStrToLong_uip(ver, NULL, 0, &source->protocolVer) < 0) { - virReportError(VIR_ERR_XML_ERROR, - _("storage pool protocol ver '%s' is malformed"), - ver); + + if (strchr(source->protocolVer, ',')) { + virReportError(VIR_ERR_XML_DETAIL, + _("storage pool protocol ver '%s' must not contain ','"), + source->protocolVer); return -1; } } @@ -1099,9 +1100,7 @@ virStoragePoolSourceFormat(virBuffer *buf, if (src->auth) virStorageAuthDefFormat(buf, src->auth); - if (src->protocolVer) - virBufferAsprintf(buf, "\n", src->protocolVer); - + virBufferEscapeString(buf, "\n", src->protocolVer); virBufferEscapeString(buf, "\n", src->vendor); virBufferEscapeString(buf, "\n", src->product); diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h index de39c3f294..a1bf243935 100644 --- a/src/conf/storage_conf.h +++ b/src/conf/storage_conf.h @@ -213,7 +213,7 @@ struct _virStoragePoolSource { int format; /* Protocol version value for netfs */ - unsigned int protocolVer; + char *protocolVer; }; typedef struct _virStoragePoolTarget virStoragePoolTarget; diff --git a/src/storage/storage_util.c b/src/storage/storage_util.c index 6ed2078b65..3871718b09 100644 --- a/src/storage/storage_util.c +++ b/src/storage/storage_util.c @@ -4201,8 +4201,8 @@ virStorageBackendFileSystemMountCmd(const char *cmdstr, virCommand *cmd = NULL; g_autofree char *nfsVers = NULL; - if (def->type == VIR_STORAGE_POOL_NETFS && def->source.protocolVer > 0) - nfsVers = g_strdup_printf("nfsvers=%u", def->source.protocolVer); + if (def->type == VIR_STORAGE_POOL_NETFS && def->source.protocolVer) + nfsVers = g_strdup_printf("nfsvers=%s", def->source.protocolVer); cmd = virCommandNew(cmdstr); if (netauto) diff --git a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-linux.argv b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-linux.argv index dac46a074f..da3e0c5927 100644 --- a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-linux.argv +++ b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-linux.argv @@ -1,5 +1,5 @@ mount \ --o nodev,nosuid,noexec,nfsvers=3 \ +-o nodev,nosuid,noexec,nfsvers=4.1 \ -t nfs \ localhost:/var/lib/libvirt/images \ /mnt diff --git a/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml index 40f3f94e41..f35992e3c8 100644 --- a/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml +++ b/tests/storagepoolxml2xmlin/pool-netfs-protocol-ver.xml @@ -8,7 +8,7 @@ - + /mnt diff --git a/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml index 5fcad1305b..74c2f5edfe 100644 --- a/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml +++ b/tests/storagepoolxml2xmlout/pool-netfs-protocol-ver.xml @@ -8,7 +8,7 @@ - + /mnt -- 2.36.1 From jtomko at redhat.com Fri Jul 1 13:50:35 2022 From: jtomko at redhat.com (=?iso-8859-1?B?SuFu?= Tomko) Date: Fri, 1 Jul 2022 15:50:35 +0200 Subject: [PATCHv2] storage: pool: Allow more intricate nfs protocol versions In-Reply-To: References: Message-ID: On a Friday in 2022, Peter Krempa wrote: >Treat the 'protocolVer' field as a string so that e.g. '4.1' can be >used. Forbid only ',' in the string as it's a separator of arguments for >mount options. > >Signed-off-by: Peter Krempa >--- > >v2: > - forbid ',' in the version string. > > docs/formatstorage.rst | 2 +- > src/conf/schemas/storagepool.rng | 4 +--- > src/conf/storage_conf.c | 17 ++++++++--------- > src/conf/storage_conf.h | 2 +- > src/storage/storage_util.c | 4 ++-- > .../pool-netfs-protocol-ver-linux.argv | 2 +- > .../pool-netfs-protocol-ver.xml | 2 +- > .../pool-netfs-protocol-ver.xml | 2 +- > 8 files changed, 16 insertions(+), 19 deletions(-) > Reviewed-by: J?n Tomko Jano -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 488 bytes Desc: not available URL: From pkrempa at redhat.com Fri Jul 1 14:56:13 2022 From: pkrempa at redhat.com (Peter Krempa) Date: Fri, 1 Jul 2022 16:56:13 +0200 Subject: [PATCH] storagepoolxml2argvtest: Fix output data for 'pool-netfs-protocol-ver' Message-ID: The storage pool tests have host-specific versions which I neglected to update in commit c44930d932203b4a58dccbbeaa814fff6cea8216 thus breaking the test-suite on non-linux OSes. Fixes: c44930d932203b4a58dccbbeaa814fff6cea8216 Signed-off-by: Peter Krempa --- Pushed as a build-fix. .../pool-netfs-protocol-ver-freebsd.argv | 2 +- tests/storagepoolxml2argvdata/pool-netfs-protocol-ver.argv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-freebsd.argv b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-freebsd.argv index 32cdaebcff..20954ef50c 100644 --- a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-freebsd.argv +++ b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver-freebsd.argv @@ -1,5 +1,5 @@ mount \ --o nosuid,noexec,nfsvers=3 \ +-o nosuid,noexec,nfsvers=4.1 \ -t nfs \ localhost:/var/lib/libvirt/images \ /mnt diff --git a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver.argv b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver.argv index ed157883c0..9afc6090b8 100644 --- a/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver.argv +++ b/tests/storagepoolxml2argvdata/pool-netfs-protocol-ver.argv @@ -1,5 +1,5 @@ mount \ --o nfsvers=3 \ +-o nfsvers=4.1 \ -t nfs \ localhost:/var/lib/libvirt/images \ /mnt -- 2.36.1 From jtomko at redhat.com Fri Jul 1 15:12:03 2022 From: jtomko at redhat.com (=?UTF-8?q?J=C3=A1n=20Tomko?=) Date: Fri, 1 Jul 2022 17:12:03 +0200 Subject: [libvirt PATCH] conf: fix error message for wrong thread_pool_size Message-ID: <17f8e36e224e200833b68c99308787f3c5d71d23.1656688316.git.jtomko@redhat.com> Fix the copy-and-paste error by referring to the correct variable. Fixes: 0df2e7df80452f81edbfeb0ee355235b533346a9 https://bugzilla.redhat.com/show_bug.cgi?id=2103132 Signed-off-by: J?n Tomko --- Pushed as trivial. src/conf/domain_conf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index fb8bf4cfec..2c2f23242e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -9949,7 +9949,7 @@ virDomainFSDefParseXML(virDomainXMLOption *xmlopt, virStrToLong_i(thread_pool_size, NULL, 10, &def->thread_pool_size) < 0) { virReportError(VIR_ERR_XML_ERROR, _("cannot parse thread pool size '%s' for virtiofs"), - queue_size); + thread_pool_size); goto error; } -- 2.35.3 From lin.a.yang at intel.com Fri Jul 1 19:14:41 2022 From: lin.a.yang at intel.com (Lin Yang) Date: Fri, 1 Jul 2022 12:14:41 -0700 Subject: [libvirt][PATCH v13 1/6] Define SGX capabilities structs In-Reply-To: <20220701191446.727066-1-lin.a.yang@intel.com> References: <20220701191446.727066-1-lin.a.yang@intel.com> Message-ID: <20220701191446.727066-2-lin.a.yang@intel.com> From: Haibin Huang Signed-off-by: Michal Privoznik Signed-off-by: Haibin Huang --- src/conf/domain_capabilities.c | 10 ++++++++++ src/conf/domain_capabilities.h | 24 ++++++++++++++++++++++++ src/libvirt_private.syms | 1 + 3 files changed, 35 insertions(+) diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c index 895e8d00e8..27f3fb8d36 100644 --- a/src/conf/domain_capabilities.c +++ b/src/conf/domain_capabilities.c @@ -76,6 +76,16 @@ virSEVCapabilitiesFree(virSEVCapability *cap) } +void +virSGXCapabilitiesFree(virSGXCapability *cap) +{ + if (!cap) + return; + + g_free(cap); +} + + static void virDomainCapsDispose(void *obj) { diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h index f2eed80b15..dac1098e98 100644 --- a/src/conf/domain_capabilities.h +++ b/src/conf/domain_capabilities.h @@ -192,6 +192,24 @@ struct _virSEVCapability { unsigned int max_es_guests; }; +typedef struct _virSection virSection; +typedef virSection *virSectionPtr; +struct _virSection { + unsigned long long size; + unsigned int node; +}; + +typedef struct _virSGXCapability virSGXCapability; +typedef virSGXCapability *virSGXCapabilityPtr; +struct _virSGXCapability { + bool flc; + bool sgx1; + bool sgx2; + unsigned long long section_size; + size_t nSections; + virSectionPtr pSections; +}; + typedef enum { VIR_DOMAIN_CAPS_FEATURE_IOTHREADS = 0, VIR_DOMAIN_CAPS_FEATURE_VMCOREINFO, @@ -228,6 +246,7 @@ struct _virDomainCaps { virDomainCapsFeatureGIC gic; virSEVCapability *sev; + virSGXCapability *sgx; /* add new domain features here */ virTristateBool features[VIR_DOMAIN_CAPS_FEATURE_LAST]; @@ -276,3 +295,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 76bcc64eb0..5d17890746 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -216,6 +216,7 @@ virDomainCapsEnumSet; virDomainCapsFormat; virDomainCapsNew; virSEVCapabilitiesFree; +virSGXCapabilitiesFree; # conf/domain_conf.h -- 2.25.1 From lin.a.yang at intel.com Fri Jul 1 19:14:40 2022 From: lin.a.yang at intel.com (Lin Yang) Date: Fri, 1 Jul 2022 12:14:40 -0700 Subject: [libvirt][PATCH v13 0/6] Support query and use SGX Message-ID: <20220701191446.727066-1-lin.a.yang@intel.com> 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. ... no yes no 2
... 2. User requests to start a guest calling virCreateXML() with SGX requirement. It supports both non-NUMA SGX interface in QEMU 6.2.0 and NUMA SGX interface in QEMU 7.0.0 and later version. Without NUMA info: ... N ... With NUMA info: ... 0-1 16384 0 ... Please note that it assumes EPC target node in guest VM (.node attribute) is not required in SGX related parameter in QEMU command if QEMU didn't provide any SGX NUMA info, like QEMU 6.2.0 version. 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 | 27 +- docs/formatdomaincaps.rst | 40 +++ src/conf/domain_capabilities.c | 58 ++++ src/conf/domain_capabilities.h | 24 ++ src/conf/domain_conf.c | 27 ++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 9 + src/conf/schemas/domaincaps.rng | 42 +++ src/conf/schemas/domaincommon.rng | 1 + src/libvirt_private.syms | 1 + src/qemu/qemu_alias.c | 6 +- src/qemu/qemu_capabilities.c | 258 ++++++++++++++++++ src/qemu/qemu_capabilities.h | 4 + src/qemu/qemu_command.c | 87 +++++- src/qemu/qemu_domain.c | 48 +++- 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 | 154 ++++++++++- src/qemu/qemu_monitor_json.h | 4 + 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 | 6 + .../domaincapsdata/qemu_6.2.0-tcg.x86_64.xml | 6 + .../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 | 6 + .../domaincapsdata/qemu_7.0.0-q35.x86_64.xml | 10 + .../domaincapsdata/qemu_7.0.0-tcg.x86_64.xml | 10 + .../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 | 10 + .../domaincapsdata/qemu_7.1.0-q35.x86_64.xml | 10 + .../domaincapsdata/qemu_7.1.0-tcg.x86_64.xml | 10 + tests/domaincapsdata/qemu_7.1.0.x86_64.xml | 10 + .../caps_6.2.0.x86_64.replies | 30 +- .../caps_6.2.0.x86_64.xml | 7 + .../caps_7.0.0.x86_64.replies | 34 ++- .../caps_7.0.0.x86_64.xml | 11 + .../caps_7.1.0.x86_64.replies | 34 ++- .../caps_7.1.0.x86_64.xml | 11 + .../sgx-epc-numa.x86_64-latest.args | 40 +++ tests/qemuxml2argvdata/sgx-epc-numa.xml | 50 ++++ .../sgx-epc.x86_64-6.2.0.args | 37 +++ tests/qemuxml2argvdata/sgx-epc.xml | 36 +++ tests/qemuxml2argvtest.c | 3 + .../sgx-epc-numa.x86_64-latest.xml | 64 +++++ .../sgx-epc.x86_64-6.2.0.xml | 52 ++++ tests/qemuxml2xmltest.c | 3 + 124 files changed, 1349 insertions(+), 42 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc-numa.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/sgx-epc-numa.xml 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-numa.x86_64-latest.xml create mode 100644 tests/qemuxml2xmloutdata/sgx-epc.x86_64-6.2.0.xml -- 2.25.1 From lin.a.yang at intel.com Fri Jul 1 19:14:43 2022 From: lin.a.yang at intel.com (Lin Yang) Date: Fri, 1 Jul 2022 12:14:43 -0700 Subject: [libvirt][PATCH v13 3/6] Convert QMP capabilities to domain capabilities In-Reply-To: <20220701191446.727066-1-lin.a.yang@intel.com> References: <20220701191446.727066-1-lin.a.yang@intel.com> Message-ID: <20220701191446.727066-4-lin.a.yang@intel.com> From: Haibin Huang the QMP capabilities: {"return": { "sgx": true, "section-size": 1024, "flc": true } } the domain capabilities: yes 1 Signed-off-by: Michal Privoznik Signed-off-by: Haibin Huang --- src/qemu/qemu_capabilities.c | 230 ++++++++++++++++++ src/qemu/qemu_capabilities.h | 4 + .../caps_6.2.0.x86_64.replies | 30 ++- .../caps_6.2.0.x86_64.xml | 7 + .../caps_7.0.0.x86_64.replies | 34 ++- .../caps_7.0.0.x86_64.xml | 11 + .../caps_7.1.0.x86_64.replies | 34 ++- .../caps_7.1.0.x86_64.xml | 11 + 8 files changed, 346 insertions(+), 15 deletions(-) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 2c3be3ecec..57b5acb150 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -671,6 +671,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "chardev.qemu-vdagent", /* QEMU_CAPS_CHARDEV_QEMU_VDAGENT */ "display-dbus", /* QEMU_CAPS_DISPLAY_DBUS */ "iothread.thread-pool-max", /* QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX */ + "sgx-epc", /* QEMU_CAPS_SGX_EPC */ ); @@ -752,6 +753,8 @@ struct _virQEMUCaps { virSEVCapability *sevCapabilities; + virSGXCapability *sgxCapabilities; + /* Capabilities which may differ depending on the accelerator. */ virQEMUCapsAccel kvm; virQEMUCapsAccel hvf; @@ -1394,6 +1397,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 }, }; @@ -1972,6 +1976,32 @@ virQEMUCapsSEVInfoCopy(virSEVCapability **dst, } +static int +virQEMUCapsSGXInfoCopy(virSGXCapability **dst, + virSGXCapability *src) +{ + g_autoptr(virSGXCapability) tmp = NULL; + + tmp = g_new0(virSGXCapability, 1); + + tmp->flc = src->flc; + tmp->sgx1 = src->sgx1; + tmp->sgx2 = src->sgx2; + tmp->section_size = src->section_size; + + if (src->nSections == 0) { + tmp->nSections = 0; + tmp->pSections = NULL; + } else { + tmp->nSections = src->nSections; + tmp->pSections = src->pSections; + } + + *dst = g_steal_pointer(&tmp); + return 0; +} + + static void virQEMUCapsAccelCopyMachineTypes(virQEMUCapsAccel *dst, virQEMUCapsAccel *src) @@ -2053,6 +2083,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); } @@ -2091,6 +2127,7 @@ void virQEMUCapsDispose(void *obj) virCPUDataFree(qemuCaps->cpuData); virSEVCapabilitiesFree(qemuCaps->sevCapabilities); + virSGXCapabilitiesFree(qemuCaps->sgxCapabilities); virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->hvf); @@ -2616,6 +2653,13 @@ virQEMUCapsGetSEVCapabilities(virQEMUCaps *qemuCaps) } +virSGXCapabilityPtr +virQEMUCapsGetSGXCapabilities(virQEMUCaps *qemuCaps) +{ + return qemuCaps->sgxCapabilities; +} + + static int virQEMUCapsProbeQMPCommands(virQEMUCaps *qemuCaps, qemuMonitor *mon) @@ -3442,6 +3486,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 @@ -4220,6 +4289,116 @@ virQEMUCapsParseSEVInfo(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt) } +static int +virQEMUCapsParseSGXInfo(virQEMUCaps *qemuCaps, + xmlXPathContextPtr ctxt) +{ + g_autoptr(virSGXCapability) sgx = NULL; + xmlNodePtr node; + + g_autofree xmlNodePtr *nodes = NULL; + g_autofree xmlNodePtr *sectionNodes = NULL; + g_autofree char *flc = NULL; + g_autofree char *sgx1 = NULL; + g_autofree char *sgx2 = NULL; + + int n = 0; + int nsections = 0; + + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_SGX_EPC)) + return 0; + + if (virXPathBoolean("boolean(./sgx)", ctxt) == 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing SGX platform data in QEMU capabilities cache")); + return -1; + } + + sgx = g_new0(virSGXCapability, 1); + + if ((!(flc = virXPathString("string(./sgx/flc)", ctxt))) || + virStringParseYesNo(flc, &sgx->flc) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or invalid SGX platform flc in QEMU capabilities cache")); + return -1; + } + + if ((!(sgx1 = virXPathString("string(./sgx/sgx1)", ctxt))) || + virStringParseYesNo(sgx1, &sgx->sgx1) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or invalid SGX platform sgx1 in QEMU capabilities cache")); + return -1; + } + + if ((!(sgx2 = virXPathString("string(./sgx/sgx2)", ctxt))) || + virStringParseYesNo(sgx2, &sgx->sgx2) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or invalid SGX platform sgx2 in QEMU capabilities cache")); + return -1; + } + + if (virXPathULongLong("string(./sgx/section_size)", ctxt, &sgx->section_size) < 0) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("missing or malformed SGX platform section_size in QEMU capabilities cache")); + return -1; + } + + if ((n = virXPathNodeSet("./sgx/sections", ctxt, &nodes)) < 0) { + sgx->nSections = 0; + sgx->pSections = NULL; + VIR_INFO("Sections was not obtained, so QEMU version is 6.2.0"); + qemuCaps->sgxCapabilities = g_steal_pointer(&sgx); + return 0; + } + + if (n == 0) { + qemuCaps->sgxCapabilities = g_steal_pointer(&sgx); + return 0; + } + + // Got the section, the QEMU version is above 7.0.0 + node = ctxt->node; + ctxt->node = nodes[0]; + nsections = virXPathNodeSet("./section", ctxt, §ionNodes); + ctxt->node = node; + + if (nsections < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to parse CPU blockers in QEMU capabilities")); + return -1; + } + + if (nsections > 0) { + size_t i; + g_autofree char * strNode = NULL; + g_autofree char * strSize = NULL; + sgx->nSections = nsections; + sgx->pSections = g_new0(virSection, nsections + 1); + + for (i = 0; i < nsections; i++) { + if ((strNode = virXMLPropString(sectionNodes[i], "node")) && + (virStrToLong_ui(strNode, NULL, 10, &(sgx->pSections[i].node)) < 0)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing node name in QEMU " + "capabilities cache")); + return -1; + } + + if ((strSize = virXMLPropString(sectionNodes[i], "size")) && + (virStrToLong_ull(strSize, NULL, 10, &(sgx->pSections[i].size)) < 0)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing size name in QEMU " + "capabilities cache")); + return -1; + } + } + } + + qemuCaps->sgxCapabilities = g_steal_pointer(&sgx); + return 0; +} + + static int virQEMUCapsParseFlags(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt) { @@ -4522,6 +4701,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)) @@ -4707,6 +4889,49 @@ virQEMUCapsFormatSEVInfo(virQEMUCaps *qemuCaps, virBuffer *buf) } +static void +virQEMUCapsFormatSGXInfo(virQEMUCaps *qemuCaps, + virBuffer *buf) +{ + virSGXCapabilityPtr sgx = virQEMUCapsGetSGXCapabilities(qemuCaps); + size_t i; + + virBufferAddLit(buf, "\n"); + virBufferAdjustIndent(buf, 2); + if (sgx->flc) { + virBufferAsprintf(buf, "%s\n", "yes"); + } else { + virBufferAsprintf(buf, "%s\n", "no"); + } + if (sgx->sgx1) { + virBufferAsprintf(buf, "%s\n", "yes"); + } else { + virBufferAsprintf(buf, "%s\n", "no"); + } + if (sgx->sgx2) { + virBufferAsprintf(buf, "%s\n", "yes"); + } else { + virBufferAsprintf(buf, "%s\n", "no"); + } + virBufferAsprintf(buf, "%llu\n", sgx->section_size); + + if (sgx->nSections > 0) { + virBufferAddLit(buf, "\n"); + + for (i = 0; i < sgx->nSections; i++) { + virBufferAdjustIndent(buf, 2); + virBufferAsprintf(buf, "
pSections[i].node); + virBufferAsprintf(buf, "size='%llu'/>\n", sgx->pSections[i].size); + virBufferAdjustIndent(buf, -2); + } + virBufferAddLit(buf, "\n"); + } + + virBufferAdjustIndent(buf, -2); + virBufferAddLit(buf, "\n"); +} + + char * virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) { @@ -4788,6 +5013,9 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) if (qemuCaps->sevCapabilities) virQEMUCapsFormatSEVInfo(qemuCaps, &buf); + if (qemuCaps->sgxCapabilities) + virQEMUCapsFormatSGXInfo(qemuCaps, &buf); + if (qemuCaps->kvmSupportsNesting) virBufferAddLit(&buf, "\n"); @@ -5455,6 +5683,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 6f35ba1485..fc8c0fde1b 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 */ QEMU_CAPS_CHARDEV_QEMU_VDAGENT, /* -chardev qemu-vdagent */ QEMU_CAPS_DISPLAY_DBUS, /* -display dbus */ QEMU_CAPS_IOTHREAD_THREAD_POOL_MAX, /* -object iothread.thread-pool-max */ + 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/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies index e235532d62..0151ab07fa 100644 --- a/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_6.2.0.x86_64.replies @@ -7459,15 +7459,15 @@ "type": "bool" }, { - "name": "sgx1", + "name": "flc", "type": "bool" }, { - "name": "sgx2", + "name": "sgx1", "type": "bool" }, { - "name": "flc", + "name": "sgx2", "type": "bool" }, { @@ -32707,6 +32707,22 @@ } } +{ + "execute": "query-sgx-capabilities", + "id": "libvirt-51" +} + +{ + "return": { + "sgx": true, + "flc": false, + "sgx1": true, + "sgx2": false, + "section-size": 2048 + }, + "id": "libvirt-51" +} + { "execute": "query-cpu-model-expansion", "arguments": { @@ -32715,7 +32731,7 @@ "name": "host" } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -33048,7 +33064,7 @@ } } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -33062,7 +33078,7 @@ } } }, - "id": "libvirt-52" + "id": "libvirt-53" } { @@ -33395,7 +33411,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..e1f177281f 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 @@ + 6002000 0 43100244 @@ -3706,4 +3707,10 @@ + + no + yes + no + 2 + diff --git a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies index 620442704a..9f806412f7 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.replies @@ -33317,6 +33317,32 @@ } } +{ + "execute": "query-sgx-capabilities", + "id": "libvirt-51" +} + +{ + "return": { + "sgx": true, + "flc": false, + "sgx1": true, + "sgx2": false, + "section-size": 2048, + "sections": [ + { + "node": 0, + "size": 1024 + }, + { + "node": 1, + "size": 1024 + } + ] + }, + "id": "libvirt-51" +} + { "execute": "query-cpu-model-expansion", "arguments": { @@ -33325,7 +33351,7 @@ "name": "host" } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -33662,7 +33688,7 @@ } } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -33676,7 +33702,7 @@ } } }, - "id": "libvirt-52" + "id": "libvirt-53" } { @@ -34013,7 +34039,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 05f844fd5b..7cad1fd7d8 100644 --- a/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.0.0.x86_64.xml @@ -243,6 +243,7 @@ + 7000000 0 43100243 @@ -3771,4 +3772,14 @@ + + no + yes + no + 2 + +
+
+ + diff --git a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies index 025d2db895..b9f9201ac7 100644 --- a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies +++ b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.replies @@ -33866,6 +33866,32 @@ } } +{ + "execute": "query-sgx-capabilities", + "id": "libvirt-51" +} + +{ + "return": { + "sgx": true, + "flc": false, + "sgx1": true, + "sgx2": false, + "section-size": 2048, + "sections": [ + { + "node": 0, + "size": 1024 + }, + { + "node": 1, + "size": 1024 + } + ] + }, + "id": "libvirt-51" +} + { "execute": "query-cpu-model-expansion", "arguments": { @@ -33874,7 +33900,7 @@ "name": "host" } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -34212,7 +34238,7 @@ } } }, - "id": "libvirt-51" + "id": "libvirt-52" } { @@ -34226,7 +34252,7 @@ } } }, - "id": "libvirt-52" + "id": "libvirt-53" } { @@ -34564,7 +34590,7 @@ } } }, - "id": "libvirt-52" + "id": "libvirt-53" } { diff --git a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml index 3707d9b7c9..21b5e361b1 100644 --- a/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_7.1.0.x86_64.xml @@ -244,6 +244,7 @@ + 7000050 0 43100244 @@ -3569,4 +3570,14 @@ + + no + yes + no + 2 + +
+
+ + -- 2.25.1 From lin.a.yang at intel.com Fri Jul 1 19:14:45 2022 From: lin.a.yang at intel.com (Lin Yang) Date: Fri, 1 Jul 2022 12:14:45 -0700 Subject: [libvirt][PATCH v13 5/6] conf: Introduce SGX EPC element into device memory xml In-Reply-To: <20220701191446.727066-1-lin.a.yang@intel.com> References: <20220701191446.727066-1-lin.a.yang@intel.com> Message-ID: <20220701191446.727066-6-lin.a.yang@intel.com> With NUMA config: ... 0-1 512 0 ... Without NUMA config: ... 512 ... Signed-off-by: Lin Yang Signed-off-by: Michal Privoznik --- docs/formatdomain.rst | 27 +++++++- src/conf/domain_conf.c | 27 ++++++++ src/conf/domain_conf.h | 1 + src/conf/domain_validate.c | 9 +++ src/conf/schemas/domaincommon.rng | 1 + src/qemu/qemu_alias.c | 3 + src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 48 ++++++++++---- 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-numa.xml | 50 +++++++++++++++ tests/qemuxml2argvdata/sgx-epc.xml | 36 +++++++++++ .../sgx-epc-numa.x86_64-latest.xml | 64 +++++++++++++++++++ .../sgx-epc.x86_64-6.2.0.xml | 52 +++++++++++++++ tests/qemuxml2xmltest.c | 3 + 20 files changed, 329 insertions(+), 15 deletions(-) create mode 100644 tests/qemuxml2argvdata/sgx-epc-numa.xml create mode 100644 tests/qemuxml2argvdata/sgx-epc.xml create mode 100644 tests/qemuxml2xmloutdata/sgx-epc-numa.x86_64-latest.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 62a94890f0..b95c930d73 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7910,6 +7910,20 @@ Example: usage of the memory devices 524288 + + + 0-1 + + + 16384 + 0 + + + + + 16384 + + ... @@ -7918,7 +7932,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.6.0 and QEMU 6.2.0` ``access`` An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides @@ -7978,6 +7994,13 @@ Example: usage of the memory devices Represents a path in the host that backs the virtio memory module in the guest. It is mandatory. + For model ``sgx-epc`` this element is optional. The following optional + elements may be used: + + ``nodemask`` + This element can be used to override the default set of NUMA nodes where + the memory would be allocated. :since:`Since 8.6.0 and QEMU 7.0.0` + ``target`` The mandatory ``target`` element configures the placement and sizing of the added memory from the perspective of the guest. @@ -7988,6 +8011,8 @@ Example: usage of the memory devices The ``node`` subelement configures the guest NUMA node to attach the memory to. The element shall be used only if the guest has NUMA nodes configured. + For model ``sgx-epc`` this element is optional. It will be set to 0 as + default. :since:`Since 8.6.0 and QEMU 7.0.0` The following optional elements may be used: diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 709ca53790..f8b67eb375 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1431,6 +1431,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel, "nvdimm", "virtio-pmem", "virtio-mem", + "sgx-epc", ); VIR_ENUM_IMPL(virDomainShmemModel, @@ -5680,6 +5681,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; @@ -14697,6 +14699,20 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, def->nvdimmPath = virXPathString("string(./path)", ctxt); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + if ((nodemask = virXPathString("string(./nodemask)", ctxt))) { + if (virBitmapParse(nodemask, &def->sourceNodes, + VIR_DOMAIN_CPUMASK_LEN) < 0) + return -1; + + if (virBitmapIsAllClear(def->sourceNodes)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Invalid value of 'nodemask': %s"), nodemask); + return -1; + } + } + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -14765,6 +14781,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; } @@ -16561,6 +16578,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; @@ -26153,6 +26171,15 @@ virDomainMemorySourceDefFormat(virBuffer *buf, virBufferEscapeString(&childBuf, "%s\n", def->nvdimmPath); break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + if (def->sourceNodes) { + if (!(bitmap = virBitmapFormat(def->sourceNodes))) + return -1; + + virBufferAsprintf(&childBuf, "%s\n", bitmap); + } + break; + 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 4c8c42b7eb..a15798463c 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2559,6 +2559,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 28b0481d4e..c8f03cb844 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -2231,6 +2231,15 @@ 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; + } + 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 da2fb0d5cb..c6377b2e90 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6833,6 +6833,7 @@ nvdimm virtio-pmem virtio-mem + sgx-epc diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index 7efd91051e..5ebeb82f92 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -515,6 +515,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 b307d3139c..7ca183ded7 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4010,6 +4010,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 60ed358871..fc64a5ca9c 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8448,6 +8448,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; @@ -9129,6 +9130,12 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, } break; + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("hotplug is 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; @@ -9164,7 +9171,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; @@ -9172,15 +9179,37 @@ 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++) { + switch (def->mems[i]->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: + 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; + break; + + case VIR_DOMAIN_MEMORY_MODEL_SGX_EPC: + /* sgx epc memory does not support hotplug */ + case VIR_DOMAIN_MEMORY_MODEL_LAST: + case VIR_DOMAIN_MEMORY_MODEL_NONE: + break; + } + } + 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")); @@ -9203,22 +9232,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 3b5c3db67c..79a6c420c0 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -7156,6 +7156,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 771a623ef7..b907387f21 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -3935,6 +3935,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; @@ -4009,6 +4010,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 39210ba65b..fbbfedd095 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -5173,6 +5173,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 008384dee8..36e8ce42b5 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 21cebae694..d94995c9cf 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1853,6 +1853,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; @@ -2040,6 +2041,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 e2f34a27dc..6657663483 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1580,6 +1580,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; } @@ -1608,6 +1609,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-numa.xml b/tests/qemuxml2argvdata/sgx-epc-numa.xml new file mode 100644 index 0000000000..f28b06dd79 --- /dev/null +++ b/tests/qemuxml2argvdata/sgx-epc-numa.xml @@ -0,0 +1,50 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 219100 + 219100 + 2 + + + + + + + + hvm + + + + destroy + restart + destroy + + /usr/bin/qemu-system-x86_64 + + + +
+ + + +