diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index ed212456ae107c3d3d6046f91a9f3bba59334f27..a872598965997f7803941b1f3bbff7a22dc175ae 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -3521,6 +3521,8 @@ qemuDomainGetMemoryModuleSizeAlignment(const virDomainDef *def, int qemuDomainAlignMemorySizes(virDomainDefPtr def) { + unsigned long long maxmemkb = virMemoryMaxValue(false) >> 10; + unsigned long long maxmemcapped = virMemoryMaxValue(true) >> 10; unsigned long long initialmem = 0; unsigned long long mem; unsigned long long align = qemuDomainGetMemorySizeAlignment(def); @@ -3531,6 +3533,13 @@ qemuDomainAlignMemorySizes(virDomainDefPtr def) for (i = 0; i < ncells; i++) { mem = VIR_ROUND_UP(virDomainNumaGetNodeMemorySize(def->numa, i), align); initialmem += mem; + + if (mem > maxmemkb) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("memory size of NUMA node '%zu' overflowed after " + "alignment"), i); + return -1; + } virDomainNumaSetNodeMemorySize(def->numa, i, mem); } @@ -3539,14 +3548,32 @@ qemuDomainAlignMemorySizes(virDomainDefPtr def) if (initialmem == 0) initialmem = VIR_ROUND_UP(virDomainDefGetMemoryInitial(def), align); + if (initialmem > maxmemcapped) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("initial memory size overflowed after alignment")); + return -1; + } + virDomainDefSetMemoryInitial(def, initialmem); def->mem.max_memory = VIR_ROUND_UP(def->mem.max_memory, align); + if (def->mem.max_memory > maxmemkb) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", + _("maximum memory size overflowed after alignment")); + return -1; + } /* Align memory module sizes */ for (i = 0; i < def->nmems; i++) { align = qemuDomainGetMemoryModuleSizeAlignment(def, def->mems[i]); def->mems[i]->size = VIR_ROUND_UP(def->mems[i]->size, align); + + if (def->mems[i]->size > maxmemkb) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("size of memory module '%zu' overflowed after " + "alignment"), i); + return -1; + } } return 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-memory-align-fail.xml b/tests/qemuxml2argvdata/qemuxml2argv-memory-align-fail.xml new file mode 100644 index 0000000000000000000000000000000000000000..bdbdc5bbdec4ffaedcb603368ad9d82b382fc467 --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-memory-align-fail.xml @@ -0,0 +1,29 @@ + + QEMUGuest1 + c7a5fdbd-edaf-9455-926a-d65c16db1809 + 9007199254740991 + 9007199254740991 + 9007199254740991 + 2 + + hvm + + + + + + + + + + destroy + restart + destroy + + /usr/bin/qemu + + + + + + diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index 6513651853061c466ad108d32102727246686b34..37f806edd3c0f71dce021fc58af4dbe363f5f667 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1660,6 +1660,7 @@ mymain(void) DO_TEST_PARSE_ERROR("shmem-msi-only", NONE); DO_TEST("cpu-host-passthrough-features", QEMU_CAPS_KVM, QEMU_CAPS_CPU_HOST); + DO_TEST_FAILURE("memory-align-fail", NONE); DO_TEST_FAILURE("memory-hotplug-nonuma", QEMU_CAPS_DEVICE_PC_DIMM); DO_TEST_FAILURE("memory-hotplug", NONE); DO_TEST("memory-hotplug", QEMU_CAPS_DEVICE_PC_DIMM, QEMU_CAPS_NUMA);