diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 49f7d27aa3..fc778901d1 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -3692,10 +3692,14 @@ qemuBuildMemoryGetPagesize(virQEMUDriverConfig *cfg, prealloc = true; } - *pagesizeRet = pagesize; - *needHugepageRet = needHugepage; - *useHugepageRet = useHugepage; - *preallocRet = prealloc; + if (pagesizeRet) + *pagesizeRet = pagesize; + if (needHugepageRet) + *needHugepageRet = needHugepage; + if (useHugepageRet) + *useHugepageRet = useHugepage; + if (preallocRet) + *preallocRet = prealloc; return 0; } @@ -3871,14 +3875,18 @@ qemuBuildMemoryBackendProps(virJSONValue **backendProps, return -1; if (mem->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM) { - /* Explicitly disable prealloc for virtio-mem as it's not supported - * currently. Warn users if their config would result in prealloc. */ - if (priv->memPrealloc || prealloc) { - VIR_WARN("Memory preallocation is unsupported for virtio-mem memory devices"); + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC)) { + /* Explicitly disable prealloc for virtio-mem if it isn't supported. + * Warn users if their config would result in prealloc. */ + if (priv->memPrealloc || prealloc) { + VIR_WARN("Memory preallocation is unsupported for virtio-mem memory devices"); + } + + if (priv->memPrealloc && + virJSONValueObjectAppendBoolean(props, "prealloc", 0) < 0) + return -1; } - if (priv->memPrealloc && - virJSONValueObjectAppendBoolean(props, "prealloc", 0) < 0) - return -1; + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MEMORY_BACKEND_RESERVE) && virJSONValueObjectAppendBoolean(props, "reserve", 0) < 0) return -1; @@ -4031,7 +4039,9 @@ qemuBuildMemoryDimmBackendStr(virCommand *cmd, virJSONValue * -qemuBuildMemoryDeviceProps(const virDomainDef *def, +qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + qemuDomainObjPrivate *priv, + const virDomainDef *def, const virDomainMemoryDef *mem) { g_autoptr(virJSONValue) props = NULL; @@ -4039,6 +4049,7 @@ qemuBuildMemoryDeviceProps(const virDomainDef *def, g_autofree char *uuidstr = NULL; virTristateBool unarmed = VIR_TRISTATE_BOOL_ABSENT; g_autofree char *memdev = NULL; + bool prealloc = false; if (!mem->info.alias) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -4062,6 +4073,10 @@ qemuBuildMemoryDeviceProps(const virDomainDef *def, case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM: device = "virtio-mem-pci"; + + if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_VIRTIO_MEM_PCI_PREALLOC) && + qemuBuildMemoryGetPagesize(cfg, def, mem, NULL, NULL, NULL, &prealloc) < 0) + return NULL; break; case VIR_DOMAIN_MEMORY_MODEL_NONE: @@ -4089,6 +4104,7 @@ qemuBuildMemoryDeviceProps(const virDomainDef *def, "S:uuid", uuidstr, "T:unarmed", unarmed, "s:memdev", memdev, + "B:prealloc", prealloc, "s:id", mem->info.alias, NULL) < 0) return NULL; @@ -7792,7 +7808,7 @@ qemuBuildMemoryDeviceCommandLine(virCommand *cmd, if (qemuBuildMemoryDimmBackendStr(cmd, def->mems[i], def, cfg, priv) < 0) return -1; - if (!(props = qemuBuildMemoryDeviceProps(def, def->mems[i]))) + if (!(props = qemuBuildMemoryDeviceProps(cfg, priv, def, def->mems[i]))) return -1; if (qemuBuildDeviceCommandlineFromJSON(cmd, props, priv->qemuCaps) < 0) diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index dd981e333f..ba175aff9c 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -153,7 +153,9 @@ int qemuBuildMemoryBackendProps(virJSONValue **backendProps, bool systemMemory); virJSONValue * -qemuBuildMemoryDeviceProps(const virDomainDef *def, +qemuBuildMemoryDeviceProps(virQEMUDriverConfig *cfg, + qemuDomainObjPrivate *priv, + const virDomainDef *def, const virDomainMemoryDef *mem); /* Current, best practice */ diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index f36de2385a..6e3a60b225 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2400,7 +2400,7 @@ qemuDomainAttachMemory(virQEMUDriver *driver, objalias = g_strdup_printf("mem%s", mem->info.alias); - if (!(devprops = qemuBuildMemoryDeviceProps(vm->def, mem))) + if (!(devprops = qemuBuildMemoryDeviceProps(cfg, priv, vm->def, mem))) goto cleanup; if (qemuBuildMemoryBackendProps(&props, objalias, cfg, diff --git a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args index 1d83ec88a8..77dbc0c89c 100644 --- a/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args +++ b/tests/qemuxml2argvdata/memory-hotplug-virtio-mem.x86_64-latest.args @@ -21,7 +21,7 @@ XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ -object '{"qom-type":"memory-backend-ram","id":"memvirtiomem0","reserve":false,"size":1073741824}' \ -device '{"driver":"virtio-mem-pci","node":0,"block-size":2097152,"requested-size":536870912,"memdev":"memvirtiomem0","id":"virtiomem0","bus":"pci.0","addr":"0x2"}' \ -object '{"qom-type":"memory-backend-file","id":"memvirtiomem1","mem-path":"/dev/hugepages2M/libvirt/qemu/-1-QEMUGuest1","reserve":false,"size":2147483648,"host-nodes":[1,2,3],"policy":"bind"}' \ --device '{"driver":"virtio-mem-pci","node":0,"block-size":2097152,"requested-size":1073741824,"memdev":"memvirtiomem1","id":"virtiomem1","bus":"pci.0","addr":"0x3"}' \ +-device '{"driver":"virtio-mem-pci","node":0,"block-size":2097152,"requested-size":1073741824,"memdev":"memvirtiomem1","prealloc":true,"id":"virtiomem1","bus":"pci.0","addr":"0x3"}' \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ -display none \ -no-user-config \