virDomainMemoryDefCheckConflict: Validate dimm slot too

Since we're iterating over def->mems array, might as well check
for dimm slot duplicates.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
Michal Privoznik
2023-11-02 16:35:00 +01:00
parent 3c2cb7d7b3
commit b475dbecb9

View File

@@ -2221,6 +2221,7 @@ static int
virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem, virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
const virDomainDef *def) const virDomainDef *def)
{ {
const virDomainDeviceDimmAddress *thisAddr = NULL;
unsigned long long thisStart = 0; unsigned long long thisStart = 0;
unsigned long long thisEnd = 0; unsigned long long thisEnd = 0;
size_t i; size_t i;
@@ -2235,6 +2236,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
case VIR_DOMAIN_MEMORY_MODEL_DIMM: case VIR_DOMAIN_MEMORY_MODEL_DIMM:
case VIR_DOMAIN_MEMORY_MODEL_NVDIMM: case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) { if (mem->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM) {
thisAddr = &mem->info.addr.dimm;
thisStart = mem->info.addr.dimm.base; thisStart = mem->info.addr.dimm.base;
} }
break; break;
@@ -2244,7 +2246,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
break; break;
} }
if (thisStart == 0) { if (thisStart == 0 && !thisAddr) {
return 0; return 0;
} }
@@ -2258,10 +2260,17 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
if (other == mem) if (other == mem)
continue; continue;
/* In case we're updating an existing memory device (e.g. virtio-mem), if (thisAddr && other->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM &&
* then pointers will be different. But addresses and aliases are the thisAddr->slot == other->info.addr.dimm.slot) {
* same. However, STREQ_NULLABLE() returns true if both strings are virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
* NULL which is not what we want. */ _("memory device slot '%1$u' is already being used by another memory device"),
thisAddr->slot);
return -1;
} else if (!thisAddr) {
/* In case we're updating an existing memory device (e.g.
* virtio-mem), then pointers will be different. But addresses and
* aliases are the same. However, STREQ_NULLABLE() returns true if
* both strings are NULL which is not what we want. */
if (virDomainDeviceInfoAddressIsEqual(&other->info, if (virDomainDeviceInfoAddressIsEqual(&other->info,
&mem->info)) { &mem->info)) {
continue; continue;
@@ -2272,6 +2281,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
mem->info.alias)) { mem->info.alias)) {
continue; continue;
} }
}
switch (other->model) { switch (other->model) {
case VIR_DOMAIN_MEMORY_MODEL_NONE: case VIR_DOMAIN_MEMORY_MODEL_NONE:
@@ -2294,7 +2304,7 @@ virDomainMemoryDefCheckConflict(const virDomainMemoryDef *mem,
break; break;
} }
if (otherStart == 0) if (thisStart == 0 || otherStart == 0)
continue; continue;
if (thisStart <= otherStart && thisEnd > otherStart) { if (thisStart <= otherStart && thisEnd > otherStart) {