diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index f0333d4f1a..6b6e0bfc34 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2975,7 +2975,8 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, qemuDomainObjPrivatePtr priv, const virDomainDef *def, const virDomainMemoryDef *mem, - bool force) + bool force, + bool systemMemory) { const char *backendType = "memory-backend-file"; virDomainNumatuneMemMode mode; @@ -2992,6 +2993,10 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, bool needHugepage = !!pagesize; bool useHugepage = !!pagesize; int discard = mem->discard; + bool disableCanonicalPath = false; + + /* Disabling canonical path is required for migration compatibility of + * system memory objects, see below */ /* The difference between @needHugepage and @useHugepage is that the latter * is true whenever huge page is defined for the current memory cell. @@ -3106,6 +3111,9 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, if (qemuBuildMemoryBackendPropsShare(props, memAccess) < 0) return -1; + if (systemMemory) + disableCanonicalPath = true; + } else if (useHugepage || mem->nvdimmPath || memAccess || def->mem.source == VIR_DOMAIN_MEMORY_SOURCE_FILE) { @@ -3148,10 +3156,29 @@ qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, if (qemuBuildMemoryBackendPropsShare(props, memAccess) < 0) return -1; + + if (systemMemory) + disableCanonicalPath = true; + } else { backendType = "memory-backend-ram"; } + /* This is a terrible hack, but unfortunately there is no better way. + * The replacement for '-m X' argument is not simple '-machine + * memory-backend' and '-object memory-backend-*,size=X' (which was the + * idea). This is because of create_default_memdev() in QEMU sets + * 'x-use-canonical-path-for-ramblock-id' attribute to false and is + * documented in QEMU in qemu-options.hx under 'memory-backend'. Note + * that QEMU consideres 'x-use-canonical-path-for-ramblock-id' stable + * and supported despite the 'x-' prefix. + * See QEMU commit 8db0b20415c129cf5e577a593a4a0372d90b7cc9. + */ + if (disableCanonicalPath && + virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_X_USE_CANONICAL_PATH_FOR_RAMBLOCK_ID) && + virJSONValueObjectAdd(props, "b:x-use-canonical-path-for-ramblock-id", false, NULL) < 0) + return -1; + if (!priv->memPrealloc && virJSONValueObjectAdd(props, "B:prealloc", prealloc, NULL) < 0) return -1; @@ -3263,7 +3290,7 @@ qemuBuildMemoryCellBackendStr(virDomainDefPtr def, mem.info.alias = alias; if ((rc = qemuBuildMemoryBackendProps(&props, alias, cfg, - priv, def, &mem, false)) < 0) + priv, def, &mem, false, false)) < 0) return -1; if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) @@ -3292,7 +3319,7 @@ qemuBuildMemoryDimmBackendStr(virBufferPtr buf, alias = g_strdup_printf("mem%s", mem->info.alias); if (qemuBuildMemoryBackendProps(&props, alias, cfg, - priv, def, mem, true) < 0) + priv, def, mem, true, false) < 0) return -1; if (virQEMUBuildObjectCommandlineFromJSON(buf, props) < 0) @@ -7105,7 +7132,7 @@ qemuBuildMemCommandLineMemoryDefaultBackend(virCommandPtr cmd, mem.info.alias = (char *) defaultRAMid; if (qemuBuildMemoryBackendProps(&props, defaultRAMid, cfg, - priv, def, &mem, false) < 0) + priv, def, &mem, false, true) < 0) return -1; if (virQEMUBuildObjectCommandlineFromJSON(&buf, props) < 0) diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index a33fbf6f4e..bdae117e02 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -161,7 +161,8 @@ int qemuBuildMemoryBackendProps(virJSONValuePtr *backendProps, qemuDomainObjPrivatePtr priv, const virDomainDef *def, const virDomainMemoryDef *mem, - bool force); + bool force, + bool systemMemory); char * qemuBuildMemoryDeviceStr(const virDomainDef *def, diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index dc2b46057c..e7863328db 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -2430,7 +2430,7 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver, goto cleanup; if (qemuBuildMemoryBackendProps(&props, objalias, cfg, - priv, vm->def, mem, true) < 0) + priv, vm->def, mem, true, false) < 0) goto cleanup; if (qemuProcessBuildDestroyMemoryPaths(driver, vm, mem, true) < 0) diff --git a/tests/qemuxml2argvdata/disk-vhostuser.x86_64-latest.args b/tests/qemuxml2argvdata/disk-vhostuser.x86_64-latest.args index 30acd7c78b..9ee855d5c7 100644 --- a/tests/qemuxml2argvdata/disk-vhostuser.x86_64-latest.args +++ b/tests/qemuxml2argvdata/disk-vhostuser.x86_64-latest.args @@ -15,7 +15,8 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \ -machine pc,accel=tcg,usb=off,dump-guest-core=off,memory-backend=pc.ram \ -cpu qemu64 \ -m 214 \ --object memory-backend-memfd,id=pc.ram,share=yes,size=224395264 \ +-object memory-backend-memfd,id=pc.ram,share=yes,\ +x-use-canonical-path-for-ramblock-id=no,size=224395264 \ -overcommit mem-lock=off \ -smp 1,sockets=1,cores=1,threads=1 \ -uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ diff --git a/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args b/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args index 6033950eab..9396441b92 100644 --- a/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args +++ b/tests/qemuxml2argvdata/hugepages-memaccess3.x86_64-latest.args @@ -19,8 +19,8 @@ arch-capabilities=on,ssbd=on,xsaves=on,cmp-legacy=on,amd-ssbd=on,virt-ssbd=on,\ rdctl-no=on,skip-l1dfl-vmentry=on,mds-no=on,pschange-mc-no=on \ -m 4096 \ -object memory-backend-file,id=pc.ram,\ -mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,share=yes,prealloc=yes,\ -size=4294967296 \ +mem-path=/dev/hugepages2M/libvirt/qemu/-1-fedora,share=yes,\ +x-use-canonical-path-for-ramblock-id=no,prealloc=yes,size=4294967296 \ -overcommit mem-lock=off \ -smp 4,sockets=4,cores=1,threads=1 \ -uuid 63840878-0deb-4095-97e6-fc444d9bc9fa \