[PATCH] qemu: add support for max-ram-below-4g option

Zhiyong Ye yezhiyong at bytedance.com
Sun Apr 25 09:33:31 UTC 2021


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 at bytedance.com>
Signed-off-by: zhenwei pi <pizhenwei at bytedance.com>
Signed-off-by: zhangruien <zhangruien at bytedance.com>
---
 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)




More information about the libvir-list mailing list