The 'below4g' attribute added in 'memory' element can be used to specify the low memory area, which allows to get a larger PCI I/O window below 4G when reduce it to a smaller value, and when raise value allows legacy non-PAE guests to have as much memory as possible in the 32bit address space below 4G. It does not share the ``unit`` parameter with the actual memory size and its unit defaults to "KiB". Signed-off-by: Zhiyong Ye <yezhiyong@xxxxxxxxxxxxx> Signed-off-by: zhenwei pi <pizhenwei@xxxxxxxxxxxxx> Signed-off-by: zhangruien <zhangruien@xxxxxxxxxxxxx> --- docs/formatdomain.rst | 10 ++++-- docs/schemas/domaincommon.rng | 5 +++ src/conf/domain_conf.c | 6 ++++ src/conf/domain_conf.h | 3 ++ src/conf/domain_validate.c | 13 ++++++++ src/qemu/qemu_command.c | 4 +++ tests/qemuxml2argvdata/memory-below4g.args | 29 ++++++++++++++++ tests/qemuxml2argvdata/memory-below4g.xml | 26 +++++++++++++++ tests/qemuxml2argvtest.c | 1 + tests/qemuxml2xmloutdata/memory-below4g.xml | 37 +++++++++++++++++++++ tests/qemuxml2xmltest.c | 1 + 11 files changed, 133 insertions(+), 2 deletions(-) create mode 100644 tests/qemuxml2argvdata/memory-below4g.args create mode 100644 tests/qemuxml2argvdata/memory-below4g.xml create mode 100644 tests/qemuxml2xmloutdata/memory-below4g.xml diff --git a/docs/formatdomain.rst b/docs/formatdomain.rst index 1b9b221611..fd074a224e 100644 --- a/docs/formatdomain.rst +++ b/docs/formatdomain.rst @@ -940,8 +940,14 @@ Memory Allocation `NUMA <#elementsCPU>`__ is configured for the guest the ``memory`` element can be omitted. In the case of crash, optional attribute ``dumpCore`` can be used to control whether the guest memory should be included in the generated - coredump or not (values "on", "off"). ``unit`` :since:`since 0.9.11` , - ``dumpCore`` :since:`since 0.10.2 (QEMU only)` + coredump or not (values "on", "off"). Besides, the optional ``below4g`` + attribute can be used to specify the low memory area, which allows to get a + larger PCI I/O window below 4G when reduce it to a smaller value, and when + raise value allows legacy non-PAE guests to have as much memory as possible + in the 32bit address space below 4G. It does not share the ``unit`` parameter + with the actual memory size and its unit defaults to "KiB". ``unit`` : + since:`since 0.9.11` , ``dumpCore`` : since:`since 0.10.2 (QEMU only)`, + ``below4g`` :since:`since 7.3.0 (QEMU only)`. ``maxMemory`` The run time maximum memory allocation of the guest. The initial memory specified by either the ``<memory>`` element or the NUMA cell size diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index a2e5c50c1d..8f2ac1ad33 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -643,6 +643,11 @@ <ref name="virOnOff"/> </attribute> </optional> + <optional> + <attribute name="below4g"> + <ref name="unsignedLong"/> + </attribute> + </optional> </element> </optional> <optional> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index a72d58f488..272fcd894e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -19786,6 +19786,10 @@ virDomainDefParseMemory(virDomainDef *def, &def->mem.max_memory, false, false) < 0) goto error; + if (virDomainParseMemory("./memory[1]/@below4g", NULL, 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 +28848,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/conf/domain_validate.c b/src/conf/domain_validate.c index 686b9e8d16..afa9e2e821 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1384,6 +1384,19 @@ virDomainDefMemtuneValidate(const virDomainDef *def) } } + if (mem->max_ram_below_4g && + mem->max_ram_below_4g < 1024) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("maximum memory size below the 4GiB boundary must be " + "greater than or equal to 1MiB")); + return -1; + } else if (mem->max_ram_below_4g > 4 * 1024 * 1024) { + virReportError(VIR_ERR_XML_DETAIL, "%s", + _("maximum memory size below the 4GiB boundary must be " + "less than or equal to 4GiB")); + return -1; + } + return 0; } 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"); diff --git a/tests/qemuxml2argvdata/memory-below4g.args b/tests/qemuxml2argvdata/memory-below4g.args new file mode 100644 index 0000000000..f55386a2a2 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-below4g.args @@ -0,0 +1,29 @@ +LC_ALL=C \ +PATH=/bin \ +HOME=/tmp/lib/domain--1-QEMUGuest1 \ +USER=test \ +LOGNAME=test \ +XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \ +XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \ +XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \ +QEMU_AUDIO_DRV=none \ +/usr/bin/qemu-system-i386 \ +-name QEMUGuest1 \ +-S \ +-machine pc,accel=tcg,usb=off,dump-guest-core=off,max-ram-below-4g=112197632 \ +-m 214 \ +-realtime mlock=off \ +-smp 1,sockets=1,cores=1,threads=1 \ +-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \ +-display none \ +-no-user-config \ +-nodefaults \ +-chardev socket,id=charmonitor,path=/tmp/lib/domain--1-QEMUGuest1/monitor.sock,server=on,wait=off \ +-mon chardev=charmonitor,id=monitor,mode=control \ +-rtc base=utc \ +-no-shutdown \ +-no-acpi \ +-usb \ +-drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \ +-device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3 diff --git a/tests/qemuxml2argvdata/memory-below4g.xml b/tests/qemuxml2argvdata/memory-below4g.xml new file mode 100644 index 0000000000..a843ef72a2 --- /dev/null +++ b/tests/qemuxml2argvdata/memory-below4g.xml @@ -0,0 +1,26 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory below4g='109568' unit='MiB'>214</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i386</emulator> + <disk type='block' device='disk'> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'/> + <controller type='ide' index='0'/> + <memballoon model='virtio'/> + </devices> +</domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index f0efe98d7e..d26455d36c 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -1055,6 +1055,7 @@ mymain(void) driver.config->dumpGuestCore = true; DO_TEST("machine-core-off", NONE); driver.config->dumpGuestCore = false; + DO_TEST("memory-below4g", NONE); DO_TEST("machine-smm-opt", QEMU_CAPS_DEVICE_DMI_TO_PCI_BRIDGE, QEMU_CAPS_DEVICE_PCI_BRIDGE, diff --git a/tests/qemuxml2xmloutdata/memory-below4g.xml b/tests/qemuxml2xmloutdata/memory-below4g.xml new file mode 100644 index 0000000000..44f58fc93b --- /dev/null +++ b/tests/qemuxml2xmloutdata/memory-below4g.xml @@ -0,0 +1,37 @@ +<domain type='qemu'> + <name>QEMUGuest1</name> + <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid> + <memory below4g='109568' unit='KiB'>219136</memory> + <currentMemory unit='KiB'>219136</currentMemory> + <vcpu placement='static'>1</vcpu> + <os> + <type arch='i686' machine='pc'>hvm</type> + <boot dev='hd'/> + </os> + <clock offset='utc'/> + <on_poweroff>destroy</on_poweroff> + <on_reboot>restart</on_reboot> + <on_crash>destroy</on_crash> + <devices> + <emulator>/usr/bin/qemu-system-i386</emulator> + <disk type='block' device='disk'> + <driver name='qemu' type='raw'/> + <source dev='/dev/HostVG/QEMUGuest1'/> + <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' target='0' unit='0'/> + </disk> + <controller type='usb' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/> + </controller> + <controller type='ide' index='0'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> + </controller> + <controller type='pci' index='0' model='pci-root'/> + <input type='mouse' bus='ps2'/> + <input type='keyboard' bus='ps2'/> + <audio id='1' type='none'/> + <memballoon model='virtio'> + <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/> + </memballoon> + </devices> +</domain> diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index c37de0c704..21e491cdda 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -220,6 +220,7 @@ mymain(void) DO_TEST_CAPS_LATEST("genid-auto"); DO_TEST("machine-core-on", NONE); DO_TEST("machine-core-off", NONE); + DO_TEST("memory-below4g", NONE); DO_TEST("machine-loadparm-multiple-disks-nets-s390", NONE); DO_TEST("default-kvm-host-arch", NONE); DO_TEST("default-qemu-host-arch", NONE); -- 2.24.3 (Apple Git-128)