On Fri, Apr 23, 2021 at 15:24:33 +0200, Michal Privoznik wrote: > The qemuDomainSetMemoryFlags() allows for memballoon > (<currentMemory/>) changes for both active and inactive guests. > And just before doing any change, we have to make sure that the > new size is not greater than the total memory (<memory/>). > > However, the total memory includes not only the regular guest > memory, but also sum of maximum sizes of all virtio-mems (in fact > all memory devices for that matter). But virtio-mem devices are > modified differently (via virDomainUpdateDevice()) and thus the > upper limit for new balloon size has to be lowered. > > Signed-off-by: Michal Privoznik <mprivozn@xxxxxxxxxx> > --- > src/qemu/qemu_driver.c | 20 ++++++++++++++++++-- > 1 file changed, 18 insertions(+), 2 deletions(-) > > diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c > index e376a64bee..6a9da62ded 100644 > --- a/src/qemu/qemu_driver.c > +++ b/src/qemu/qemu_driver.c > @@ -2433,12 +2433,28 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem, > } else { > /* resize the current memory */ > unsigned long oldmax = 0; > + size_t i; > > - if (def) > + if (def) { > oldmax = virDomainDefGetMemoryTotal(def); > + > + /* While virtio-mem is regular mem from guest POV, it can't be > + * modified through this API. */ > + for (i = 0; i < def->nmems; i++) { > + if (def->mems[i]->model == VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM) > + oldmax -= def->mems[i]->size; > + } > + } > + > if (persistentDef) { > - if (!oldmax || oldmax > virDomainDefGetMemoryTotal(persistentDef)) > + if (!oldmax || oldmax > virDomainDefGetMemoryTotal(persistentDef)) { IMO this code will not be correct any more when you do the subtraction of virtio-mem devices above as you compare it with the total memory of the persistent def.