From 7448ed2eaf56756e313bf883a516fdff3f54d02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Tue, 14 Jul 2026 18:42:57 +0200 Subject: [PATCH] tests: reduce maxmem of HVM when running in nested virt Nested EPT is super slow, which makes the initial balloon down very long - sometimes over a minute. PVH are not affected, as those are running with memory hotplug instead of populate-on-demand on boot, and balloon down doesn't happen. But HVM are incompatible with memory hotplug (looks like QEMU limitation), so initial balloon down does happen there. And before that, Linux thinks it has up to maxmem memory and will try to clear it. This may look like this for example: [ 0.879054] mem auto-init: stack:all(zero), heap alloc:on, heap free:on [ 0.879060] mem auto-init: clearing system memory may take some time... [ 86.287478] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=2, Nodes=1 Reduce the impact when running tests in nested virt by reducing maxmem to 1G in those cases. QubesOS/qubes-issues#10723 --- qubes/tests/__init__.py | 15 +++++++++++++++ qubes/tests/extra.py | 2 ++ qubes/tests/integ/audio.py | 8 ++++---- qubes/tests/integ/grub.py | 2 ++ 4 files changed, 23 insertions(+), 4 deletions(-) diff --git a/qubes/tests/__init__.py b/qubes/tests/__init__.py index b9ffae7cd..ba50fa5a2 100644 --- a/qubes/tests/__init__.py +++ b/qubes/tests/__init__.py @@ -921,6 +921,21 @@ def close_qdb_on_remove(self, app, event, vm, **kwargs): vm._qdb_connection_watch.close() vm._qdb_connection_watch = None + @staticmethod + def set_hvm(vm): + vm.virt_mode = "hvm" + # when running test in nested virt, set lower maxmem to workaround + # https://github.com/QubesOS/qubes-issues/issues/10723 + qemu = False + try: + with open("/sys/firmware/dmi/entries/1-0/raw", "rb") as f: + if b"QEMU" in f.read(): + qemu = True + except OSError: + pass + if qemu: + vm.maxmem = 1024 + def cleanup_app(self): self.remove_test_vms() diff --git a/qubes/tests/extra.py b/qubes/tests/extra.py index ed5c6772f..38c4963e6 100644 --- a/qubes/tests/extra.py +++ b/qubes/tests/extra.py @@ -64,6 +64,8 @@ def __getattr__(self, item): def __setattr__(self, key, value): if key.startswith("_"): return super(VMWrapper, self).__setattr__(key, value) + if key == "virt_mode" and value == "hvm": + qubes.tests.SystemTestCase.set_hvm(self._vm) return setattr(self._vm, key, value) def __str__(self): diff --git a/qubes/tests/integ/audio.py b/qubes/tests/integ/audio.py index b67f53697..ceeb0d621 100644 --- a/qubes/tests/integ/audio.py +++ b/qubes/tests/integ/audio.py @@ -606,7 +606,7 @@ def test_222_audio_rec_unmuted_pulseaudio(self): "pulseaudio-utils not installed in dom0", ) def test_223_audio_play_hvm(self): - self.testvm1.virt_mode = "hvm" + self.set_hvm(self.testvm1) self.testvm1.features["audio-model"] = "ich6" self.prepare_audio_test("pulseaudio") try: @@ -625,7 +625,7 @@ def test_223_audio_play_hvm(self): "pulseaudio-utils not installed in dom0", ) def test_224_audio_rec_muted_hvm(self): - self.testvm1.virt_mode = "hvm" + self.set_hvm(self.testvm1) self.testvm1.features["audio-model"] = "ich6" self.prepare_audio_test("pulseaudio") try: @@ -647,7 +647,7 @@ def test_224_audio_rec_muted_hvm(self): "pulseaudio-utils not installed in dom0", ) def test_225_audio_rec_unmuted_hvm(self): - self.testvm1.virt_mode = "hvm" + self.set_hvm(self.testvm1) self.testvm1.features["audio-model"] = "ich6" self.prepare_audio_test("pulseaudio") pa_info = self.loop.run_until_complete( @@ -683,7 +683,7 @@ def test_225_audio_rec_unmuted_hvm(self): def test_252_audio_playback_audiovm_switch_hvm(self): self.create_audio_vm("pulseaudio") self.testvm1.audiovm = self.audiovm - self.testvm1.virt_mode = "hvm" + self.set_hvm(self.testvm1) self.testvm1.features["audio-model"] = "ich6" self.testvm1.features["stubdom-qrexec"] = "1" self.prepare_audio_test("pulseaudio") diff --git a/qubes/tests/integ/grub.py b/qubes/tests/integ/grub.py index 16f90be8c..bcad29ef5 100644 --- a/qubes/tests/integ/grub.py +++ b/qubes/tests/integ/grub.py @@ -140,6 +140,8 @@ def test_000_standalone_vm(self): "StandaloneVM", name=self.make_vm_name("vm1"), label="red" ) self.testvm1.virt_mode = self.virt_mode + if self.virt_mode == "hvm": + self.set_hvm(self.testvm1) self.testvm1.features.update(self.app.domains[self.template].features) self.testvm1.clone_properties(self.app.domains[self.template]) self.loop.run_until_complete(