Limit the amount of ram below 4G. This can increase the address space used by PCI devices below 4G and it can be used by adding attributes in XML like this: <domain> ... <memory unit="MiB" below4g="2048">4096</memory> ... </domain> Signed-off-by: Zhiyong Ye <yezhiyong@xxxxxxxxxxxxx> Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx> Signed-off-by: zhangruien <zhangruien@xxxxxxxxxxxxx> --- src/conf/domain_conf.c | 19 +++++++++++++++++++ src/conf/domain_conf.h | 3 +++ src/qemu/qemu_command.c | 4 ++++ 3 files changed, 26 insertions(+) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a72d58f488..c211a69ed1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -4720,6 +4720,19 @@ virDomainDefPostParseMemory(virDomainDef *def, return -1; } + if (def->mem.max_ram_below_4g && + def->mem.max_ram_below_4g < (1ULL << 10)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("maximum memory size below the 4GiB boundary is too small, " + "BIOS may not work with less than 1MiB")); + return -1; + } else if (def->mem.max_ram_below_4g > (1ULL << 22)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("maximum memory size below the 4GiB boundary must be " + "less than or equal to 4GiB")); + return -1; + } + return 0; } @@ -19786,6 +19799,10 @@ virDomainDefParseMemory(virDomainDef *def, &def->mem.max_memory, false, false) < 0) goto error; + if (virDomainParseMemory("./memory[1]/@below4g", "./memory[1]/@unit", ctxt, + &def->mem.max_ram_below_4g, false, true) < 0) + goto error; + if (virXPathUInt("string(./maxMemory[1]/@slots)", ctxt, &def->mem.memory_slots) == -2) { virReportError(VIR_ERR_XML_ERROR, "%s", _("Failed to parse memory slot count")); @@ -28844,6 +28861,8 @@ virDomainDefFormatInternalSetRootName(virDomainDef *def, if (def->mem.dump_core) virBufferAsprintf(buf, " dumpCore='%s'", virTristateSwitchTypeToString(def->mem.dump_core)); + if (def->mem.max_ram_below_4g > 0) + virBufferAsprintf(buf, " below4g='%llu'", def->mem.max_ram_below_4g); virBufferAsprintf(buf, " unit='KiB'>%llu</memory>\n", virDomainDefGetMemoryTotal(def)); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 4838687edf..a939d43e93 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -2597,6 +2597,9 @@ struct _virDomainMemtune { unsigned long long max_memory; /* in kibibytes */ unsigned int memory_slots; /* maximum count of RAM memory slots */ + /* maximum memory below the 4GiB boundary (32bit boundary) */ + unsigned long long max_ram_below_4g; /* in kibibytes */ + bool nosharepages; bool locked; int dump_core; /* enum virTristateSwitch */ diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index be93182092..c69ad781e6 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6961,6 +6961,10 @@ qemuBuildMachineCommandLine(virCommand *cmd, cfg->dumpGuestCore ? "on" : "off"); } + if (def->mem.max_ram_below_4g > 0) + virBufferAsprintf(&buf, ",max-ram-below-4g=%llu", + def->mem.max_ram_below_4g * 1024); + if (def->mem.nosharepages) virBufferAddLit(&buf, ",mem-merge=off"); -- 2.24.3 (Apple Git-128)