}
+static unsigned long long
+qemuValidateGetNVDIMMAlignedSizePseries(virDomainMemoryDefPtr mem,
+ const virDomainDef *def)
+{
+ unsigned long long ppc64AlignSize = qemuDomainGetMemorySizeAlignment(def);
+ unsigned long long guestArea = mem->size - mem->labelsize;
+
+ /* NVDIMM is already aligned */
+ if (guestArea % ppc64AlignSize == 0)
+ return mem->size;
+
+ /* Suggested aligned size is rounded up */
+ guestArea = (guestArea/ppc64AlignSize + 1) * ppc64AlignSize;
+ return guestArea + mem->labelsize;
+}
+
static int
qemuValidateDomainDeviceDefMemory(virDomainMemoryDefPtr mem,
+ const virDomainDef *def,
virQEMUCapsPtr qemuCaps)
{
- if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM &&
- !virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM)) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("nvdimm isn't supported by this QEMU binary"));
- return -1;
+ if (mem->model == VIR_DOMAIN_MEMORY_MODEL_NVDIMM) {
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVDIMM)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("nvdimm isn't supported by this QEMU binary"));
+ return -1;
+ }
+
+ if (qemuDomainIsPSeries(def)) {
+ unsigned long long alignedNVDIMMSize =
+ qemuValidateGetNVDIMMAlignedSizePseries(mem, def);
+
+ if (mem->size != alignedNVDIMMSize) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("nvdimm size is not aligned. Suggested aligned "
+ "size: %llu KiB"), alignedNVDIMMSize);
+ return -1;
+ }
+ }
}
return 0;
break;
case VIR_DOMAIN_DEVICE_MEMORY:
- ret = qemuValidateDomainDeviceDefMemory(dev->data.memory, qemuCaps);
+ ret = qemuValidateDomainDeviceDefMemory(dev->data.memory, def, qemuCaps);
break;
case VIR_DOMAIN_DEVICE_LEASE:
-smp 2,sockets=2,dies=1,cores=1,threads=1 \
-numa node,nodeid=0,cpus=0-1,mem=1024 \
-object memory-backend-file,id=memnvdimm0,prealloc=yes,mem-path=/tmp/nvdimm,\
-size=537001984 \
+size=805437440 \
-device nvdimm,node=0,label-size=131072,\
uuid=49545eb3-75e1-2d0a-acdd-f0294406c99e,memdev=memnvdimm0,id=nvdimm0,slot=0 \
-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \