[PATCH 0/6] Introduce virtio-pmem <memory/> model

Technically, this is v3 of: https://www.redhat.com/archives/libvir-list/2020-December/msg00199.html But I've split the big series (so no longer mixing virtio-mem and virtio-pmem). The virtio-pmem-pci is very similar to NVDIM so the implementation is fairly straightforward. Michal Prívozník (6): qemu_capabilities: Introduce QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI conf: Introduce virtio-pmem <memory/> model security: Relabel virtio-pmem qemu: Allow virtio-pmem in CGroups qemu: Create virtio-pmem in namespace qemu: Build command line for virtio-pmem docs/formatdomain.rst | 29 ++++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 41 ++++++++- src/conf/domain_conf.h | 3 +- src/conf/domain_validate.c | 40 ++++++++- src/qemu/qemu_alias.c | 58 ++++++++---- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_cgroup.c | 6 +- src/qemu/qemu_command.c | 73 ++++++++------- src/qemu/qemu_domain.c | 25 ++++++ src/qemu/qemu_domain_address.c | 88 +++++++++++++++---- src/qemu/qemu_domain_address.h | 3 +- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_namespace.c | 3 +- src/qemu/qemu_validate.c | 8 ++ src/security/security_apparmor.c | 1 + src/security/security_dac.c | 2 + src/security/security_selinux.c | 2 + .../caps_4.1.0.x86_64.xml | 1 + .../caps_4.2.0.x86_64.xml | 1 + .../caps_5.0.0.x86_64.xml | 1 + .../caps_5.1.0.x86_64.xml | 1 + .../caps_5.2.0.x86_64.xml | 1 + ...ory-hotplug-virtio-pmem.x86_64-latest.args | 45 ++++++++++ .../memory-hotplug-virtio-pmem.xml | 53 +++++++++++ tests/qemuxml2argvtest.c | 1 + ...mory-hotplug-virtio-pmem.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 29 files changed, 414 insertions(+), 80 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml create mode 120000 tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml -- 2.26.2

In this commit a new capability is introduced that reflect device support by given qemu: QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI, /* -device virtio-pmem-pci */ The virtio-pmem-pci device was introduced in QEMU 4.1. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 1 + 7 files changed, 8 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 4d132defbd..d656732c3e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -609,6 +609,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "ncr53c90", "dc390", "am53c974", + "virtio-pmem-pci", ); @@ -1325,6 +1326,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { */ { "dc390", QEMU_CAPS_SCSI_DC390 }, { "am53c974", QEMU_CAPS_SCSI_AM53C974 }, + { "virtio-pmem-pci", QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI }, }; diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 0f90efa459..a14a78f959 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -589,6 +589,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_SCSI_NCR53C90, /* built-in SCSI */ QEMU_CAPS_SCSI_DC390, /* -device dc-390 */ QEMU_CAPS_SCSI_AM53C974, /* -device am53c974 */ + QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI, /* -device virtio-pmem-pci */ QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml index 58774fddcc..28a4b0ede0 100644 --- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml @@ -231,6 +231,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>4001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml index 1ba8c09374..e150741f11 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml @@ -240,6 +240,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>4002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml index 849727eb40..7c56d110f4 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -247,6 +247,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index ff5f42a563..07466093c9 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -249,6 +249,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index cebacc249d..dea2ff4b54 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -250,6 +250,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion> -- 2.26.2

On 1/15/21 11:12 AM, Michal Privoznik wrote:
In this commit a new capability is introduced that reflect device support by given qemu:
This sounds a bit strange to me. What about this: "This commit introduces a new capability that reflects virtio-pmem-pci device support in qemu:"
QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI, /* -device virtio-pmem-pci */
The virtio-pmem-pci device was introduced in QEMU 4.1.
Signed-off-by: Michal Privoznik <mprivozn@redhat.com> ---
Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
src/qemu/qemu_capabilities.c | 2 ++ src/qemu/qemu_capabilities.h | 1 + tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml | 1 + tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml | 1 + 7 files changed, 8 insertions(+)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 4d132defbd..d656732c3e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -609,6 +609,7 @@ VIR_ENUM_IMPL(virQEMUCaps, "ncr53c90", "dc390", "am53c974", + "virtio-pmem-pci", );
@@ -1325,6 +1326,7 @@ struct virQEMUCapsStringFlags virQEMUCapsObjectTypes[] = { */ { "dc390", QEMU_CAPS_SCSI_DC390 }, { "am53c974", QEMU_CAPS_SCSI_AM53C974 }, + { "virtio-pmem-pci", QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI }, };
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 0f90efa459..a14a78f959 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -589,6 +589,7 @@ typedef enum { /* virQEMUCapsFlags grouping marker for syntax-check */ QEMU_CAPS_SCSI_NCR53C90, /* built-in SCSI */ QEMU_CAPS_SCSI_DC390, /* -device dc-390 */ QEMU_CAPS_SCSI_AM53C974, /* -device am53c974 */ + QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI, /* -device virtio-pmem-pci */
QEMU_CAPS_LAST /* this must always be the last item */ } virQEMUCapsFlags; diff --git a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml index 58774fddcc..28a4b0ede0 100644 --- a/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml @@ -231,6 +231,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>4001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml index 1ba8c09374..e150741f11 100644 --- a/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml @@ -240,6 +240,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>4002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml index 849727eb40..7c56d110f4 100644 --- a/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.0.0.x86_64.xml @@ -247,6 +247,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5000000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100241</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml index ff5f42a563..07466093c9 100644 --- a/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.1.0.x86_64.xml @@ -249,6 +249,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5001000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100242</microcodeVersion> diff --git a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml index cebacc249d..dea2ff4b54 100644 --- a/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml +++ b/tests/qemucapabilitiesdata/caps_5.2.0.x86_64.xml @@ -250,6 +250,7 @@ <flag name='fsdev.createmode'/> <flag name='dc390'/> <flag name='am53c974'/> + <flag name='virtio-pmem-pci'/> <version>5002000</version> <kvmVersion>0</kvmVersion> <microcodeVersion>43100243</microcodeVersion>

The virtio-pmem is a virtio variant of NVDIMM and just like NVDIMM virtio-pmem also allows accessing host pages bypassing guest page cache. The difference is that if a regular file is used to back guest's NVDIMM (model='nvdimm') the persistence of guest writes might not be guaranteed while with virtio-pmem it is. To express this new model at domain XML level, I've chosen the following: <memory model='virtio-pmem' access='shared'> <source> <path>/tmp/virtio_pmem</path> </source> <target> <size unit='KiB'>524288</size> </target> <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> </memory> Another difference between NVDIMM and virtio-pmem is that while the former supports NUMA node locality the latter doesn't. And also, the latter goes onto PCI bus and not into a DIMM module. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- docs/formatdomain.rst | 29 ++++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 41 ++++++++- src/conf/domain_conf.h | 3 +- src/conf/domain_validate.c | 40 ++++++++- src/qemu/qemu_command.c | 1 + src/qemu/qemu_domain.c | 25 ++++++ src/qemu/qemu_domain_address.c | 88 +++++++++++++++---- src/qemu/qemu_domain_address.h | 3 +- src/qemu/qemu_hotplug.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 + .../memory-hotplug-virtio-pmem.xml | 53 +++++++++++ ...mory-hotplug-virtio-pmem.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 17 files changed, 274 insertions(+), 27 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml create mode 120000 tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 6100b88e99..dd197d8f6a 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -7257,20 +7257,30 @@ Example: usage of the memory devices </label> </target> </memory> + <memory model='virtio-pmem' access='shared'> + <source> + <path>/tmp/virtio_pmem</path> + </source> + <target> + <size unit='KiB'>524288</size> + </target> + </memory> </devices> ... ``model`` Provide ``dimm`` to add a virtual DIMM module to the guest. :since:`Since - 1.2.14` Provide ``nvdimm`` model adds a Non-Volatile DIMM module. - :since:`Since 3.2.0` + 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` ``access`` An optional attribute ``access`` ( :since:`since 3.2.0` ) that provides capability to fine tune mapping of the memory on per module basis. Values are the same as `Memory Backing <#elementsMemoryBacking>`__: ``shared`` and ``private``. For ``nvdimm`` model, if using real NVDIMM DAX device as - backend, ``shared`` is required. + backend, ``shared`` is required. For ``virtio-pmem`` model ``shared`` is + required. ``discard`` An optional attribute ``discard`` ( :since:`since 4.4.0` ) that provides @@ -7299,9 +7309,9 @@ Example: usage of the memory devices This element can be used to override the default set of NUMA nodes where the memory would be allocated. - For model ``nvdimm`` this element is mandatory. The mandatory child element - ``path`` represents a path in the host that backs the nvdimm module in the - guest. The following optional elements may be used: + For model ``nvdimm`` the ``source`` element is mandatory. The mandatory + child element ``path`` represents a path in the host that backs the nvdimm + module in the guest. The following optional elements may be used: ``alignsize`` The ``alignsize`` element defines the page size alignment used to mmap the @@ -7315,6 +7325,13 @@ Example: usage of the memory devices to guarantee the persistence of writes to the vNVDIMM backend, then use the ``pmem`` element in order to utilize the feature. :since:`Since 5.0.0` + For model ``virtio-pmem`` the ``source`` element is mandatory. The following + optional elements may be used: + + ``path`` + Represents a path in the host that backs the virtio memory module in the + guest. It is mandatory. + ``target`` The mandatory ``target`` element configures the placement and sizing of the added memory from the perspective of the guest. diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 7dc419bcc3..a4bddcf132 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -6019,6 +6019,7 @@ <choice> <value>dimm</value> <value>nvdimm</value> + <value>virtio-pmem</value> </choice> </attribute> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 01b7187637..ff3b7cbfc8 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1309,6 +1309,7 @@ VIR_ENUM_IMPL(virDomainMemoryModel, "", "dimm", "nvdimm", + "virtio-pmem", ); VIR_ENUM_IMPL(virDomainShmemModel, @@ -5331,6 +5332,28 @@ virDomainVsockDefPostParse(virDomainVsockDefPtr vsock) } +static int +virDomainMemoryDefPostParse(virDomainMemoryDefPtr mem) +{ + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + /* Virtio-pmem mandates shared access so that guest writes get + * reflected in the underlying file. */ + if (mem->access == VIR_DOMAIN_MEMORY_ACCESS_DEFAULT) + mem->access = VIR_DOMAIN_MEMORY_ACCESS_SHARED; + break; + + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } + + return 0; +} + + static int virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, const virDomainDef *def, @@ -5376,6 +5399,10 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, ret = 0; break; + case VIR_DOMAIN_DEVICE_MEMORY: + ret = virDomainMemoryDefPostParse(dev->data.memory); + break; + case VIR_DOMAIN_DEVICE_LEASE: case VIR_DOMAIN_DEVICE_FS: case VIR_DOMAIN_DEVICE_INPUT: @@ -5390,7 +5417,6 @@ virDomainDeviceDefPostParseCommon(virDomainDeviceDefPtr dev, case VIR_DOMAIN_DEVICE_SHMEM: case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: - case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_IOMMU: case VIR_DOMAIN_DEVICE_AUDIO: ret = 0; @@ -15310,6 +15336,10 @@ virDomainMemorySourceDefParseXML(xmlNodePtr node, break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + def->nvdimmPath = virXPathString("string(./path)", ctxt); + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -17194,6 +17224,11 @@ virDomainMemoryFindByDefInternal(virDomainDefPtr def, continue; break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + if (STRNEQ(tmp->nvdimmPath, mem->nvdimmPath)) + continue; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; @@ -26486,6 +26521,10 @@ virDomainMemorySourceDefFormat(virBufferPtr buf, virBufferAddLit(&childBuf, "<pmem/>\n"); break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + virBufferEscapeString(&childBuf, "<path>%s</path>\n", def->nvdimmPath); + 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 ec43bbe186..f59d972c85 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2307,6 +2307,7 @@ typedef enum { VIR_DOMAIN_MEMORY_MODEL_NONE, VIR_DOMAIN_MEMORY_MODEL_DIMM, /* dimm hotpluggable memory device */ VIR_DOMAIN_MEMORY_MODEL_NVDIMM, /* nvdimm memory device */ + VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM, /* virtio-pmem memory device */ VIR_DOMAIN_MEMORY_MODEL_LAST } virDomainMemoryModel; @@ -2318,7 +2319,7 @@ struct _virDomainMemoryDef { /* source */ virBitmapPtr sourceNodes; unsigned long long pagesize; /* kibibytes */ - char *nvdimmPath; + char *nvdimmPath; /* valid for NVDIMM an VIRTIO_PMEM */ unsigned long long alignsize; /* kibibytes; valid only for NVDIMM */ bool nvdimmPmem; /* valid only for NVDIMM */ diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 988aff8dd7..ecef22c31c 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1389,7 +1389,8 @@ static int virDomainMemoryDefValidate(const virDomainMemoryDef *mem, const virDomainDef *def) { - if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) { + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: if (!mem->nvdimmPath) { virReportError(VIR_ERR_XML_DETAIL, "%s", _("path is required for model 'nvdimm'")); @@ -1407,6 +1408,43 @@ virDomainMemoryDefValidate(const virDomainMemoryDef *mem, _("label size is required for NVDIMM device")); return -1; } + break; + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + if (!mem->nvdimmPath) { + virReportError(VIR_ERR_XML_DETAIL, + _("path is required for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + + if (mem->discard == VIR_TRISTATE_BOOL_YES) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("discard is not supported for model '%s'"), + virDomainMemoryModelTypeToString(mem->model)); + return -1; + } + + if (mem->access != VIR_DOMAIN_MEMORY_ACCESS_SHARED) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("shared access mode required for virtio-pmem device")); + return -1; + } + + if (mem->targetNode != -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio-pmem does not support NUMA nodes")); + return -1; + } + + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + break; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainMemoryModel, mem->model); + return -1; } return 0; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6f970a3128..6a4ad6c412 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3325,6 +3325,7 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def, return NULL; break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: break; diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 0765dc72d2..dd79cfd9d9 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -8605,6 +8605,8 @@ static int qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, const virDomainDef *def) { + bool needsNuma = true; + switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: @@ -8640,11 +8642,34 @@ qemuDomainDefValidateMemoryHotplugDevice(const virDomainMemoryDef *mem, } break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + if (mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI && + mem->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("only 'pci' addresses are supported for the " + "virtio-pmem device")); + return -1; + } + + /* virtio-pmem doesn't have .node attribute. */ + needsNuma = false; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: return -1; } + if (needsNuma && + virDomainNumaGetNodeCount(def->numa) != 0) { + if (mem->targetNode == -1) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("target NUMA node needs to be specified for " + "memory device")); + return -1; + } + } + return 0; } diff --git a/src/qemu/qemu_domain_address.c b/src/qemu/qemu_domain_address.c index f0ba318cc8..d40edadb4d 100644 --- a/src/qemu/qemu_domain_address.c +++ b/src/qemu/qemu_domain_address.c @@ -313,11 +313,11 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, virDomainDeviceAddressType type) { /* - declare address-less virtio devices to be of address type 'type' - disks, networks, videos, consoles, controllers, memballoon and rng - in this order - if type is ccw filesystem and vsock devices are declared to be of - address type ccw + Declare address-less virtio devices to be of address type 'type' + disks, networks, videos, consoles, controllers, hostdevs, memballoon, + rngs and memories in this order. + If type is ccw filesystem and vsock devices are declared to be of + address type ccw. */ size_t i; @@ -379,6 +379,12 @@ qemuDomainPrimeVirtioDeviceAddresses(virDomainDefPtr def, def->rngs[i]->info.type = type; } + for (i = 0; i < def->nmems; i++) { + if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM && + def->mems[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) + def->mems[i]->info.type = type; + } + if (type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCW) { for (i = 0; i < def->nfss; i++) { if (def->fss[i]->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) @@ -1005,11 +1011,23 @@ qemuDomainDeviceCalculatePCIConnectFlags(virDomainDeviceDefPtr dev, } break; + case VIR_DOMAIN_DEVICE_MEMORY: + switch (dev->data.memory->model) { + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + return virtioFlags; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + return 0; + } + break; + /* These devices don't ever connect with PCI */ case VIR_DOMAIN_DEVICE_NVRAM: case VIR_DOMAIN_DEVICE_TPM: case VIR_DOMAIN_DEVICE_PANIC: - case VIR_DOMAIN_DEVICE_MEMORY: case VIR_DOMAIN_DEVICE_HUB: case VIR_DOMAIN_DEVICE_REDIRDEV: case VIR_DOMAIN_DEVICE_SMARTCARD: @@ -2420,6 +2438,17 @@ qemuDomainAssignDevicePCISlots(virDomainDefPtr def, return -1; } + for (i = 0; i < def->nmems; i++) { + virDomainMemoryDefPtr mem = def->mems[i]; + + if (mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM || + !virDeviceInfoPCIAddressIsWanted(&mem->info)) + continue; + + if (qemuDomainPCIAddressReserveNextAddr(addrs, &mem->info) < 0) + return -1; + } + return 0; } @@ -3067,19 +3096,32 @@ qemuAssignMemoryDeviceSlot(virDomainMemoryDefPtr mem, int -qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def, +qemuDomainAssignMemoryDeviceSlot(virQEMUDriverPtr driver, + virDomainObjPtr vm, virDomainMemoryDefPtr mem) { - virBitmapPtr slotmap = NULL; - int ret; + g_autoptr(virBitmap) slotmap = NULL; + virDomainDeviceDef dev = {.type = VIR_DOMAIN_DEVICE_MEMORY, .data.memory = mem}; - if (!(slotmap = qemuDomainGetMemorySlotMap(def))) - return -1; + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + if (!(slotmap = qemuDomainGetMemorySlotMap(vm->def))) + return -1; - ret = qemuAssignMemoryDeviceSlot(mem, slotmap); + return qemuAssignMemoryDeviceSlot(mem, slotmap); + break; - virBitmapFree(slotmap); - return ret; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + return qemuDomainEnsurePCIAddress(vm, &dev, driver); + break; + + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } + + return 0; } @@ -3097,8 +3139,22 @@ qemuDomainAssignMemorySlots(virDomainDefPtr def) return -1; for (i = 0; i < def->nmems; i++) { - if (qemuAssignMemoryDeviceSlot(def->mems[i], slotmap) < 0) - goto cleanup; + virDomainMemoryDefPtr mem = def->mems[i]; + + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + if (qemuAssignMemoryDeviceSlot(def->mems[i], slotmap) < 0) + goto cleanup; + break; + + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + /* handled in qemuDomainAssignPCIAddresses() */ + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + break; + } } ret = 0; diff --git a/src/qemu/qemu_domain_address.h b/src/qemu/qemu_domain_address.h index 7ef3308246..20a46160d5 100644 --- a/src/qemu/qemu_domain_address.h +++ b/src/qemu/qemu_domain_address.h @@ -56,7 +56,8 @@ void qemuDomainFillDeviceIsolationGroup(virDomainDefPtr def, void qemuDomainReleaseDeviceAddress(virDomainObjPtr vm, virDomainDeviceInfoPtr info); -int qemuDomainAssignMemoryDeviceSlot(virDomainDefPtr def, +int qemuDomainAssignMemoryDeviceSlot(virQEMUDriverPtr driver, + virDomainObjPtr vm, virDomainMemoryDefPtr mem); int qemuDomainEnsureVirtioAddress(bool *releaseAddr, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f336a90c8e..0096e8bf64 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2412,7 +2412,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, if (qemuDomainDefValidateMemoryHotplug(vm->def, mem) < 0) goto cleanup; - if (qemuDomainAssignMemoryDeviceSlot(vm->def, mem) < 0) + if (qemuDomainAssignMemoryDeviceSlot(driver, vm, mem) < 0) goto cleanup; /* in cases where we are using a VM with aliases generated according to the diff --git a/src/qemu/qemu_validate.c b/src/qemu/qemu_validate.c index eadf3af8b3..a060bd98ba 100644 --- a/src/qemu/qemu_validate.c +++ b/src/qemu/qemu_validate.c @@ -4624,6 +4624,14 @@ qemuValidateDomainDeviceDefMemory(virDomainMemoryDefPtr mem, } break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("virtio-pmem 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 1b035cce2f..1d828ce0d8 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -690,6 +690,7 @@ AppArmorSetMemoryLabel(virSecurityManagerPtr mgr, return -1; } return reload_profile(mgr, def, mem->nvdimmPath, true); + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 4f4a0a069e..0acdc2a52d 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1892,6 +1892,7 @@ virSecurityDACRestoreMemoryLabel(virSecurityManagerPtr mgr, ret = virSecurityDACRestoreFileLabel(mgr, mem->nvdimmPath); break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: @@ -2074,6 +2075,7 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr, user, group, true); break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index 2fc6ef2616..bbffbccb17 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1581,6 +1581,7 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManagerPtr mgr, return -1; break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: @@ -1608,6 +1609,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManagerPtr mgr, ret = virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath, true); break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml new file mode 100644 index 0000000000..23729ed799 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml @@ -0,0 +1,53 @@ +<domain type='kvm'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <maxMemory slots='16' unit='KiB'>1099511627776</maxMemory> + <memory unit='KiB'>2095104</memory> + <currentMemory unit='KiB'>2095104</currentMemory> + <vcpu placement='static' cpuset='0-1'>2</vcpu> + <os> + <type arch='x86_64' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <cpu mode='custom' match='exact' check='none'> + <model fallback='forbid'>qemu64</model> + <topology sockets='2' dies='1' cores='1' threads='1'/> + <numa> + <cell id='0' cpus='0-1' memory='2095104' unit='KiB'/> + </numa> + </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-i386</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='usb' index='0' model='piix3-uhci'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + <memory model='virtio-pmem' access='shared'> + <source> + <path>/tmp/virtio_pmem</path> + </source> + <target> + <size unit='KiB'>524288</size> + </target> + <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/> + </memory> + </devices> +</domain> diff --git a/tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml new file mode 120000 index 0000000000..904425abe4 --- /dev/null +++ b/tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml @@ -0,0 +1 @@ +../qemuxml2argvdata/memory-hotplug-virtio-pmem.xml \ No newline at end of file diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index ed8e22bdb1..9553a8a4f8 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -1261,6 +1261,7 @@ mymain(void) QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_DEVICE_NVDIMM, QEMU_CAPS_LAST); + DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem"); DO_TEST("net-udp", NONE); -- 2.26.2

Just like with NVDIMM model, we have to relabel the path to virtio-pmem so that QEMU can access it. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 4 ++-- src/security/security_selinux.c | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 1d828ce0d8..29f0956d22 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -683,6 +683,7 @@ AppArmorSetMemoryLabel(virSecurityManagerPtr mgr, { switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: if (!virFileExists(mem->nvdimmPath)) { virReportError(VIR_ERR_INTERNAL_ERROR, _("%s: \'%s\' does not exist"), @@ -690,7 +691,6 @@ AppArmorSetMemoryLabel(virSecurityManagerPtr mgr, return -1; } return reload_profile(mgr, def, mem->nvdimmPath, true); - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 0acdc2a52d..71d58758c4 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1889,10 +1889,10 @@ virSecurityDACRestoreMemoryLabel(virSecurityManagerPtr mgr, switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: ret = virSecurityDACRestoreFileLabel(mgr, mem->nvdimmPath); break; - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: @@ -2063,6 +2063,7 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr, switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME); if (seclabel && !seclabel->relabel) return 0; @@ -2075,7 +2076,6 @@ virSecurityDACSetMemoryLabel(virSecurityManagerPtr mgr, user, group, true); break; - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: case VIR_DOMAIN_MEMORY_MODEL_NONE: diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index bbffbccb17..3563dbfb86 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -1572,6 +1572,7 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManagerPtr mgr, switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); if (!seclabel || !seclabel->relabel) return 0; @@ -1581,7 +1582,6 @@ virSecuritySELinuxSetMemoryLabel(virSecurityManagerPtr mgr, return -1; break; - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_LAST: @@ -1602,6 +1602,7 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManagerPtr mgr, switch (mem->model) { case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: seclabel = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME); if (!seclabel || !seclabel->relabel) return 0; @@ -1609,7 +1610,6 @@ virSecuritySELinuxRestoreMemoryLabel(virSecurityManagerPtr mgr, ret = virSecuritySELinuxRestoreFileLabel(mgr, mem->nvdimmPath, true); break; - case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: -- 2.26.2

Some users might want to have virtio-pmem backed by a block device in which case we have to allow the device in CGroups. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_cgroup.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index f7146a71c9..cb8112ea90 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -502,7 +502,8 @@ qemuSetupMemoryDevicesCgroup(virDomainObjPtr vm, qemuDomainObjPrivatePtr priv = vm->privateData; int rv; - if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM) + if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) return 0; if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) @@ -525,7 +526,8 @@ qemuTeardownMemoryDevicesCgroup(virDomainObjPtr vm, qemuDomainObjPrivatePtr priv = vm->privateData; int rv; - if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM) + if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) return 0; if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) -- 2.26.2

Some users might want to have virtio-pmem backed by a block device in which case we have to create the device in the domain private namespace. Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_namespace.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c index 1002455ddf..35fe177bef 100644 --- a/src/qemu/qemu_namespace.c +++ b/src/qemu/qemu_namespace.c @@ -351,7 +351,8 @@ static int qemuDomainSetupMemory(virDomainMemoryDefPtr mem, char ***paths) { - if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM) + if (mem->model != VIR_DOMAIN_MEMORY_MODEL_NVDIMM && + mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) return 0; return virStringListAdd(paths, mem->nvdimmPath); -- 2.26.2

Now we have everything prepared for generating the command line. The device alias prefix was chosen to be 'virtiopmem'. Since virtio-pmem-pci device goes onto PCI bus generating device alias must have been changed slightly because qemuAssignDeviceMemoryAlias() might have used DIMM slot number to generate the alias. This obviously won't work and thus the "old" way (which includes qemuDomainDeviceAliasIndex()) must be used. Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1735375 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_alias.c | 58 ++++++++++----- src/qemu/qemu_command.c | 72 ++++++++++--------- ...ory-hotplug-virtio-pmem.x86_64-latest.args | 45 ++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 126 insertions(+), 50 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index dcb6c7156d..b3492d6e85 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -466,6 +466,29 @@ qemuAssignDeviceRNGAlias(virDomainDefPtr def, } +static int +qemuDeviceMemoryGetAliasID(virDomainDefPtr def, + virDomainMemoryDefPtr mem, + bool oldAlias, + const char *prefix) +{ + size_t i; + int maxidx = 0; + + /* virtio-pmem goes onto PCI bus and thus DIMM address is not valid */ + if (!oldAlias && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) + return mem->info.addr.dimm.slot; + + for (i = 0; i < def->nmems; i++) { + int idx; + if ((idx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, prefix)) >= maxidx) + maxidx = idx + 1; + } + + return maxidx; +} + + /** * qemuAssignDeviceMemoryAlias: * @def: domain definition. Necessary only if @oldAlias is true. @@ -483,29 +506,32 @@ qemuAssignDeviceMemoryAlias(virDomainDefPtr def, virDomainMemoryDefPtr mem, bool oldAlias) { - size_t i; - int maxidx = 0; - int idx; - const char *prefix; + const char *prefix = NULL; + int idx = 0; if (mem->info.alias) return 0; - if (mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM) + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: prefix = "dimm"; - else + break; + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: prefix = "nvdimm"; - - if (oldAlias) { - for (i = 0; i < def->nmems; i++) { - if ((idx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, prefix)) >= maxidx) - maxidx = idx + 1; - } - } else { - maxidx = mem->info.addr.dimm.slot; + break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + prefix = "virtiopmem"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainMemoryModel, mem->model); + return -1; + break; } - mem->info.alias = g_strdup_printf("%s%d", prefix, maxidx); + idx = qemuDeviceMemoryGetAliasID(def, mem, oldAlias, prefix); + mem->info.alias = g_strdup_printf("%s%d", prefix, idx); return 0; } @@ -680,7 +706,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) return -1; } for (i = 0; i < def->nmems; i++) { - if (qemuAssignDeviceMemoryAlias(NULL, def->mems[i], false) < 0) + if (qemuAssignDeviceMemoryAlias(def, def->mems[i], false) < 0) return -1; } if (def->vsock) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6a4ad6c412..64b189fd11 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3087,8 +3087,9 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, if (mem->nvdimmPath) { memPath = g_strdup(mem->nvdimmPath); /* If the NVDIMM is a real device then there's nothing to prealloc. - * If anything, we would be only wearing off the device. */ - if (!mem->nvdimmPmem) + * If anything, we would be only wearing off the device. + * Simirarly, virtio-pmem-pci doesn't need prealloc either. */ + if (!mem->nvdimmPmem && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) prealloc = true; } else if (useHugepage) { if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, &memPath) < 0) @@ -3282,7 +3283,7 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def, virQEMUCapsPtr qemuCaps) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - const char *device; + const char *device = NULL; if (!mem->info.alias) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3291,47 +3292,50 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def, } switch (mem->model) { - case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: - - if (mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM) - device = "pc-dimm"; - else - device = "nvdimm"; - - virBufferAsprintf(&buf, "%s,", device); - - if (mem->targetNode >= 0) - virBufferAsprintf(&buf, "node=%d,", mem->targetNode); - - if (mem->labelsize) - virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024); - - if (virUUIDIsValid(mem->uuid)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(mem->uuid, uuidstr); - virBufferAsprintf(&buf, "uuid=%s,", uuidstr); - } - - if (mem->readonly) { - virBufferAddLit(&buf, "unarmed=on,"); - } - - virBufferAsprintf(&buf, "memdev=mem%s,id=%s", - mem->info.alias, mem->info.alias); - - if (qemuBuildDeviceAddressStr(&buf, def, &mem->info, qemuCaps) < 0) - return NULL; + device = "pc-dimm"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + device = "nvdimm"; break; case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + device = "virtio-pmem-pci"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainMemoryModel, mem->model); + return NULL; break; + } + + virBufferAsprintf(&buf, "%s,", device); + + if (mem->targetNode >= 0) + virBufferAsprintf(&buf, "node=%d,", mem->targetNode); + + if (mem->labelsize) + virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024); + + if (virUUIDIsValid(mem->uuid)) { + char uuidstr[VIR_UUID_STRING_BUFLEN]; + virUUIDFormat(mem->uuid, uuidstr); + virBufferAsprintf(&buf, "uuid=%s,", uuidstr); } + if (mem->readonly) { + virBufferAddLit(&buf, "unarmed=on,"); + } + + virBufferAsprintf(&buf, "memdev=mem%s,id=%s", + mem->info.alias, mem->info.alias); + + if (qemuBuildDeviceAddressStr(&buf, def, &mem->info, qemuCaps) < 0) + return NULL; + return virBufferContentAndReset(&buf); } diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args new file mode 100644 index 0000000000..e2f5097424 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args @@ -0,0 +1,45 @@ +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 \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,accel=kvm,usb=off,dump-guest-core=off \ +-cpu qemu64 \ +-m size=2095104k,slots=16,maxmem=1099511627776k \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,dies=1,cores=1,threads=1 \ +-object memory-backend-ram,id=ram-node0,size=2145386496 \ +-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \ +-object memory-backend-file,id=memvirtiopmem0,mem-path=/tmp/virtio_pmem,\ +share=yes,size=536870912 \ +-device virtio-pmem-pci,memdev=memvirtiopmem0,id=virtiopmem0,bus=pci.0,\ +addr=0x5 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1",\ +"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\ +"file":"libvirt-1-storage"}' \ +-device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 4a2ab6bec1..cf77224fc3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3053,6 +3053,7 @@ mymain(void) QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_DEVICE_NVDIMM, QEMU_CAPS_LAST); + DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem"); DO_TEST("machine-aeskeywrap-on-caps", QEMU_CAPS_AES_KEY_WRAP, -- 2.26.2

On 1/15/21 11:12 AM, Michal Privoznik wrote:
Now we have everything prepared for generating the command line. The device alias prefix was chosen to be 'virtiopmem'.
Since virtio-pmem-pci device goes onto PCI bus generating device alias must have been changed slightly because qemuAssignDeviceMemoryAlias() might have used DIMM slot number to generate the alias. This obviously won't work and thus the "old" way (which includes qemuDomainDeviceAliasIndex()) must be used.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1735375 Signed-off-by: Michal Privoznik <mprivozn@redhat.com> --- src/qemu/qemu_alias.c | 58 ++++++++++----- src/qemu/qemu_command.c | 72 ++++++++++--------- ...ory-hotplug-virtio-pmem.x86_64-latest.args | 45 ++++++++++++ tests/qemuxml2argvtest.c | 1 + 4 files changed, 126 insertions(+), 50 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args
diff --git a/src/qemu/qemu_alias.c b/src/qemu/qemu_alias.c index dcb6c7156d..b3492d6e85 100644 --- a/src/qemu/qemu_alias.c +++ b/src/qemu/qemu_alias.c @@ -466,6 +466,29 @@ qemuAssignDeviceRNGAlias(virDomainDefPtr def, }
+static int +qemuDeviceMemoryGetAliasID(virDomainDefPtr def, + virDomainMemoryDefPtr mem, + bool oldAlias, + const char *prefix) +{ + size_t i; + int maxidx = 0; + + /* virtio-pmem goes onto PCI bus and thus DIMM address is not valid */ + if (!oldAlias && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) + return mem->info.addr.dimm.slot; + + for (i = 0; i < def->nmems; i++) { + int idx; + if ((idx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, prefix)) >= maxidx) + maxidx = idx + 1; + } + + return maxidx; +} + + /** * qemuAssignDeviceMemoryAlias: * @def: domain definition. Necessary only if @oldAlias is true. @@ -483,29 +506,32 @@ qemuAssignDeviceMemoryAlias(virDomainDefPtr def, virDomainMemoryDefPtr mem, bool oldAlias) { - size_t i; - int maxidx = 0; - int idx; - const char *prefix; + const char *prefix = NULL; + int idx = 0;
if (mem->info.alias) return 0;
- if (mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM) + switch (mem->model) { + case VIR_DOMAIN_MEMORY_MODEL_DIMM: prefix = "dimm"; - else + break; + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: prefix = "nvdimm"; - - if (oldAlias) { - for (i = 0; i < def->nmems; i++) { - if ((idx = qemuDomainDeviceAliasIndex(&def->mems[i]->info, prefix)) >= maxidx) - maxidx = idx + 1; - } - } else { - maxidx = mem->info.addr.dimm.slot; + break; + case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + prefix = "virtiopmem"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: + case VIR_DOMAIN_MEMORY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainMemoryModel, mem->model); + return -1; + break; }
- mem->info.alias = g_strdup_printf("%s%d", prefix, maxidx); + idx = qemuDeviceMemoryGetAliasID(def, mem, oldAlias, prefix); + mem->info.alias = g_strdup_printf("%s%d", prefix, idx);
return 0; } @@ -680,7 +706,7 @@ qemuAssignDeviceAliases(virDomainDefPtr def, virQEMUCapsPtr qemuCaps) return -1; } for (i = 0; i < def->nmems; i++) { - if (qemuAssignDeviceMemoryAlias(NULL, def->mems[i], false) < 0) + if (qemuAssignDeviceMemoryAlias(def, def->mems[i], false) < 0) return -1; } if (def->vsock) { diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 6a4ad6c412..64b189fd11 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3087,8 +3087,9 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, if (mem->nvdimmPath) { memPath = g_strdup(mem->nvdimmPath); /* If the NVDIMM is a real device then there's nothing to prealloc. - * If anything, we would be only wearing off the device. */ - if (!mem->nvdimmPmem) + * If anything, we would be only wearing off the device. + * Simirarly, virtio-pmem-pci doesn't need prealloc either. */
s/Simirarly/Similarly Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
+ if (!mem->nvdimmPmem && mem->model != VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM) prealloc = true; } else if (useHugepage) { if (qemuGetDomainHupageMemPath(priv->driver, def, pagesize, &memPath) < 0) @@ -3282,7 +3283,7 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def, virQEMUCapsPtr qemuCaps) { g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER; - const char *device; + const char *device = NULL;
if (!mem->info.alias) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -3291,47 +3292,50 @@ qemuBuildMemoryDeviceStr(const virDomainDef *def, }
switch (mem->model) { - case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_DIMM: - - if (mem->model == VIR_DOMAIN_MEMORY_MODEL_DIMM) - device = "pc-dimm"; - else - device = "nvdimm"; - - virBufferAsprintf(&buf, "%s,", device); - - if (mem->targetNode >= 0) - virBufferAsprintf(&buf, "node=%d,", mem->targetNode); - - if (mem->labelsize) - virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024); - - if (virUUIDIsValid(mem->uuid)) { - char uuidstr[VIR_UUID_STRING_BUFLEN]; - - virUUIDFormat(mem->uuid, uuidstr); - virBufferAsprintf(&buf, "uuid=%s,", uuidstr); - } - - if (mem->readonly) { - virBufferAddLit(&buf, "unarmed=on,"); - } - - virBufferAsprintf(&buf, "memdev=mem%s,id=%s", - mem->info.alias, mem->info.alias); - - if (qemuBuildDeviceAddressStr(&buf, def, &mem->info, qemuCaps) < 0) - return NULL; + device = "pc-dimm"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: + device = "nvdimm"; break;
case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM: + device = "virtio-pmem-pci"; + break; + case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_LAST: + default: + virReportEnumRangeError(virDomainMemoryModel, mem->model); + return NULL; break; + } + + virBufferAsprintf(&buf, "%s,", device); + + if (mem->targetNode >= 0) + virBufferAsprintf(&buf, "node=%d,", mem->targetNode); + + if (mem->labelsize) + virBufferAsprintf(&buf, "label-size=%llu,", mem->labelsize * 1024); + + if (virUUIDIsValid(mem->uuid)) { + char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(mem->uuid, uuidstr); + virBufferAsprintf(&buf, "uuid=%s,", uuidstr); }
+ if (mem->readonly) { + virBufferAddLit(&buf, "unarmed=on,"); + } + + virBufferAsprintf(&buf, "memdev=mem%s,id=%s", + mem->info.alias, mem->info.alias); + + if (qemuBuildDeviceAddressStr(&buf, def, &mem->info, qemuCaps) < 0) + return NULL; + return virBufferContentAndReset(&buf); }
diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args new file mode 100644 index 0000000000..e2f5097424 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args @@ -0,0 +1,45 @@ +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 \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name guest=QEMUGuest1,debug-threads=on \ +-S \ +-object secret,id=masterKey0,format=raw,\ +file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ +-machine pc,accel=kvm,usb=off,dump-guest-core=off \ +-cpu qemu64 \ +-m size=2095104k,slots=16,maxmem=1099511627776k \ +-overcommit mem-lock=off \ +-smp 2,sockets=2,dies=1,cores=1,threads=1 \ +-object memory-backend-ram,id=ram-node0,size=2145386496 \ +-numa node,nodeid=0,cpus=0-1,memdev=ram-node0 \ +-object memory-backend-file,id=memvirtiopmem0,mem-path=/tmp/virtio_pmem,\ +share=yes,size=536870912 \ +-device virtio-pmem-pci,memdev=memvirtiopmem0,id=virtiopmem0,bus=pci.0,\ +addr=0x5 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,fd=1729,server,nowait \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-boot strict=on \ +-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \ +-blockdev '{"driver":"host_device","filename":"/dev/HostVG/QEMUGuest1",\ +"node-name":"libvirt-1-storage","auto-read-only":true,"discard":"unmap"}' \ +-blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"raw",\ +"file":"libvirt-1-storage"}' \ +-device ide-hd,bus=ide.0,unit=0,drive=libvirt-1-format,id=ide0-0-0,bootindex=1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 \ +-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\ +resourcecontrol=deny \ +-msg timestamp=on diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 4a2ab6bec1..cf77224fc3 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -3053,6 +3053,7 @@ mymain(void) QEMU_CAPS_OBJECT_MEMORY_FILE, QEMU_CAPS_DEVICE_NVDIMM, QEMU_CAPS_LAST); + DO_TEST_CAPS_LATEST("memory-hotplug-virtio-pmem");
DO_TEST("machine-aeskeywrap-on-caps", QEMU_CAPS_AES_KEY_WRAP,

On 1/15/21 11:12 AM, Michal Privoznik wrote:
Technically, this is v3 of:
https://www.redhat.com/archives/libvir-list/2020-December/msg00199.html
But I've split the big series (so no longer mixing virtio-mem and virtio-pmem). The virtio-pmem-pci is very similar to NVDIM so the implementation is fairly straightforward.
Michal Prívozník (6): qemu_capabilities: Introduce QEMU_CAPS_DEVICE_VIRTIO_PMEM_PCI conf: Introduce virtio-pmem <memory/> model security: Relabel virtio-pmem qemu: Allow virtio-pmem in CGroups qemu: Create virtio-pmem in namespace qemu: Build command line for virtio-pmem
Series LGTM. One more stuff to the "features that exists in x86_64 but not on PowerPC for no apparent reason" list :/ Reviewed-by: Daniel Henrique Barboza <danielhb413@gmail.com>
docs/formatdomain.rst | 29 ++++-- docs/schemas/domaincommon.rng | 1 + src/conf/domain_conf.c | 41 ++++++++- src/conf/domain_conf.h | 3 +- src/conf/domain_validate.c | 40 ++++++++- src/qemu/qemu_alias.c | 58 ++++++++---- src/qemu/qemu_capabilities.c | 2 + src/qemu/qemu_capabilities.h | 1 + src/qemu/qemu_cgroup.c | 6 +- src/qemu/qemu_command.c | 73 ++++++++------- src/qemu/qemu_domain.c | 25 ++++++ src/qemu/qemu_domain_address.c | 88 +++++++++++++++---- src/qemu/qemu_domain_address.h | 3 +- src/qemu/qemu_hotplug.c | 2 +- src/qemu/qemu_namespace.c | 3 +- src/qemu/qemu_validate.c | 8 ++ src/security/security_apparmor.c | 1 + src/security/security_dac.c | 2 + src/security/security_selinux.c | 2 + .../caps_4.1.0.x86_64.xml | 1 + .../caps_4.2.0.x86_64.xml | 1 + .../caps_5.0.0.x86_64.xml | 1 + .../caps_5.1.0.x86_64.xml | 1 + .../caps_5.2.0.x86_64.xml | 1 + ...ory-hotplug-virtio-pmem.x86_64-latest.args | 45 ++++++++++ .../memory-hotplug-virtio-pmem.xml | 53 +++++++++++ tests/qemuxml2argvtest.c | 1 + ...mory-hotplug-virtio-pmem.x86_64-latest.xml | 1 + tests/qemuxml2xmltest.c | 1 + 29 files changed, 414 insertions(+), 80 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.x86_64-latest.args create mode 100644 tests/qemuxml2argvdata/memory-hotplug-virtio-pmem.xml create mode 120000 tests/qemuxml2xmloutdata/memory-hotplug-virtio-pmem.x86_64-latest.xml
participants (2)
-
Daniel Henrique Barboza
-
Michal Privoznik