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 | 15 ++++++++++++ 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, 142 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..a093b2f0eb 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")); @@ -22792,6 +22796,15 @@ virDomainMemtuneCheckABIStability(const virDomainDef *src, return false; } + if (src->mem.max_ram_below_4g != dst->mem.max_ram_below_4g) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain maximum memory below the 4GiB boundary " + "'%llu' doesn't match source '%llu'"), + dst->mem.max_ram_below_4g, + src->mem.max_ram_below_4g); + return false; + } + return true; } @@ -28844,6 +28857,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.11.0