ppc64 guests need the dimm to be aligned to 256MiB. The
existing auto-align mechanic in qemuDomainAttachMemory(), via
qemuDomainMemoryDeviceAlignSize(), is rounding up the dimms
to the next 256MiB alignment. This leads to confusing
situations in which the user intended to hotplug 300MiB, but
see 512MiB memory being added, an extra 212MiB due to this
rounding.
The auto-align is also active for x86, but it is currently
broken. qemuDomainMemoryDeviceAlignSize() is checking for the
memory alignment (1MiB) instead of memory module alignment
(2MiB). The end result is that QEMU ends up firing an error,
warning the user of the 2MiB alignment requirement.
Removing the auto-alignment of memory dimms in hotplug/unplug,
warning the user of the dimm alignment error instead, allows
ppc64 users to get a proper error message instead of seeing
unintended extra MBs appearing in the guest. For x86, instead
of fixing the auto-align and changing the current user expectation
of seeing an error message on dimm misalign, while adding yet
another x86 vs ppc64 difference in the code, remove auto-align
for x86 as well. x86 users will benefit from a friendlier error
message, and this time an intended one.
This is the current QEMU error when an misaligned x86 dimm is hotplugged:
$ sudo ./run virsh attach-device memtest mem_err.xml
error: Failed to attach device from mem_err.xml
error: internal error: unable to execute QEMU command 'device_add': backend memory
size must be multiple of 0x200000
This is the new error message:
$ sudo ./run virsh detach-device memtest mem_err.xml
error: Failed to detach device from mem_err.xml
error: unsupported configuration: dimm memory must be aligned with 2 MiB
A similar error message is displayed in the ppc64 case.
Reported-by: Dan Zheng <dzheng(a)redhat.com>
Fixes:
https://bugzilla.redhat.com/show_bug.cgi?id=1780506
Signed-off-by: Daniel Henrique Barboza <danielhb413(a)gmail.com>
---
src/qemu/qemu_hotplug.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index ca18bb9e5f..576eb37f0b 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2317,6 +2317,23 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
}
+static int
+qemuDomainMemoryDimmIsAligned(const virDomainDef *def,
+ virDomainMemoryDefPtr mem)
+{
+ unsigned long long align = qemuDomainGetMemoryModuleSizeAlignment(def);
+
+ if (mem->size % align != 0) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("dimm memory must be aligned with %llu MiB"),
+ align / 1024);
+ return -1;
+ }
+
+ return 0;
+}
+
+
/**
* qemuDomainAttachMemory:
* @driver: qemu driver data
@@ -2348,7 +2365,8 @@ qemuDomainAttachMemory(virQEMUDriverPtr driver,
int id;
int ret = -1;
- qemuDomainMemoryDeviceAlignSize(vm->def, mem);
+ if (qemuDomainMemoryDimmIsAligned(vm->def, mem) < 0)
+ goto cleanup;
if (qemuDomainDefValidateMemoryHotplug(vm->def, priv->qemuCaps, mem) < 0)
goto cleanup;
@@ -5637,7 +5655,8 @@ qemuDomainDetachPrepMemory(virDomainObjPtr vm,
virDomainMemoryDefPtr mem;
int idx;
- qemuDomainMemoryDeviceAlignSize(vm->def, match);
+ if (qemuDomainMemoryDimmIsAligned(vm->def, match) < 0)
+ return -1;
if ((idx = virDomainMemoryFindByDef(vm->def, match)) < 0) {
virReportError(VIR_ERR_DEVICE_MISSING,
--
2.24.1