From 9a72282560fd478e69326617cbe891461375c93a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:08 +0000 Subject: [PATCH 01/31] tests/functional: move aarch64 GPU test into own file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I want to expand the number of tests to cover a wide range of configurations. That starts with splitting off from the normal virt test from which it doesn't really share much code. We can also reduce the timeout of the original virt test now it is now longer burdened with testing the GPU. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-2-alex.bennee@linaro.org> --- MAINTAINERS | 1 + tests/functional/meson.build | 4 +- tests/functional/test_aarch64_virt.py | 71 ----------------- tests/functional/test_aarch64_virt_gpu.py | 94 +++++++++++++++++++++++ 4 files changed, 98 insertions(+), 72 deletions(-) create mode 100755 tests/functional/test_aarch64_virt_gpu.py diff --git a/MAINTAINERS b/MAINTAINERS index 618d75f087..758cc461be 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2631,6 +2631,7 @@ F: hw/display/virtio-gpu* F: hw/display/virtio-vga.* F: include/hw/virtio/virtio-gpu.h F: docs/system/devices/virtio-gpu.rst +F: tests/functional/test_aarch64_virt_gpu.py vhost-user-blk M: Raphael Norwitz diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 5dc66c03fc..7fcc4731d5 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -18,7 +18,8 @@ test_timeouts = { 'aarch64_sbsaref_alpine' : 1200, 'aarch64_sbsaref_freebsd' : 720, 'aarch64_tuxrun' : 240, - 'aarch64_virt' : 720, + 'aarch64_virt' : 360, + 'aarch64_virt_gpu' : 480, 'acpi_bits' : 420, 'arm_aspeed_palmetto' : 120, 'arm_aspeed_romulus' : 120, @@ -84,6 +85,7 @@ tests_aarch64_system_thorough = [ 'aarch64_tcg_plugins', 'aarch64_tuxrun', 'aarch64_virt', + 'aarch64_virt_gpu', 'aarch64_xen', 'aarch64_xlnx_versal', 'multiprocess', diff --git a/tests/functional/test_aarch64_virt.py b/tests/functional/test_aarch64_virt.py index 95f5ce8b4c..884aad7af6 100755 --- a/tests/functional/test_aarch64_virt.py +++ b/tests/functional/test_aarch64_virt.py @@ -134,77 +134,6 @@ class Aarch64VirtMachine(QemuSystemTest): self.common_aarch64_virt("virt,gic-version=2") - ASSET_VIRT_GPU_KERNEL = Asset( - 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' - 'download?path=%2F&files=' - 'Image', - '89e5099d26166204cc5ca4bb6d1a11b92c217e1f82ec67e3ba363d09157462f6') - - ASSET_VIRT_GPU_ROOTFS = Asset( - 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' - 'download?path=%2F&files=' - 'rootfs.ext4.zstd', - '792da7573f5dc2913ddb7c638151d4a6b2d028a4cb2afb38add513c1924bdad4') - - @skipIfMissingCommands('zstd') - def test_aarch64_virt_with_gpu(self): - # This tests boots with a buildroot test image that contains - # vkmark and other GPU exercising tools. We run a headless - # weston that nevertheless still exercises the virtio-gpu - # backend. - - self.set_machine('virt') - self.require_accelerator("tcg") - - kernel_path = self.ASSET_VIRT_GPU_KERNEL.fetch() - image_path = self.uncompress(self.ASSET_VIRT_GPU_ROOTFS, format="zstd") - - self.vm.set_console() - kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + - 'console=ttyAMA0 root=/dev/vda') - - self.vm.add_args("-accel", "tcg") - self.vm.add_args("-cpu", "neoverse-v1,pauth-impdef=on") - self.vm.add_args("-machine", "virt,gic-version=max", - '-kernel', kernel_path, - '-append', kernel_command_line) - self.vm.add_args("-smp", "2", "-m", "2048") - self.vm.add_args("-device", - "virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") - self.vm.add_args("-display", "egl-headless") - self.vm.add_args("-display", "dbus,gl=on") - self.vm.add_args("-device", "virtio-blk-device,drive=hd0") - self.vm.add_args("-blockdev", - "driver=raw,file.driver=file," - "node-name=hd0,read-only=on," - f"file.filename={image_path}") - self.vm.add_args("-snapshot") - - try: - self.vm.launch() - except VMLaunchFailure as excp: - if "old virglrenderer, blob resources unsupported" in excp.output: - self.skipTest("No blob support for virtio-gpu") - elif "old virglrenderer, venus unsupported" in excp.output: - self.skipTest("No venus support for virtio-gpu") - elif "egl: no drm render node available" in excp.output: - self.skipTest("Can't access host DRM render node") - elif "'type' does not accept value 'egl-headless'" in excp.output: - self.skipTest("egl-headless support is not available") - else: - self.log.info(f"unhandled launch failure: {excp.output}") - raise excp - - self.wait_for_console_pattern('buildroot login:') - exec_command(self, 'root') - exec_command(self, 'export XDG_RUNTIME_DIR=/tmp') - exec_command_and_wait_for_pattern(self, - "weston -B headless " - "--renderer gl " - "--shell kiosk " - "-- vkmark -b:duration=1.0", - "vkmark Score") - if __name__ == '__main__': QemuSystemTest.main() diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py new file mode 100755 index 0000000000..32af941cd5 --- /dev/null +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python3 +# +# Functional tests for the various graphics modes we can support. +# +# Copyright (c) 2024, 2025 Linaro Ltd. +# +# Author: +# Alex Bennée +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu.machine.machine import VMLaunchFailure + +from qemu_test import Asset +from qemu_test import exec_command, exec_command_and_wait_for_pattern +from qemu_test import skipIfMissingCommands + +from qemu_test.linuxkernel import LinuxKernelTest + +class Aarch64VirtGPUMachine(LinuxKernelTest): + + ASSET_VIRT_GPU_KERNEL = Asset( + 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' + 'download?path=%2F&files=' + 'Image', + '89e5099d26166204cc5ca4bb6d1a11b92c217e1f82ec67e3ba363d09157462f6') + + ASSET_VIRT_GPU_ROOTFS = Asset( + 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' + 'download?path=%2F&files=' + 'rootfs.ext4.zstd', + '792da7573f5dc2913ddb7c638151d4a6b2d028a4cb2afb38add513c1924bdad4') + + @skipIfMissingCommands('zstd') + def test_aarch64_virt_with_vulkan_gpu(self): + # This tests boots with a buildroot test image that contains + # vkmark and other GPU exercising tools. We run a headless + # weston that nevertheless still exercises the virtio-gpu + # backend. + + self.set_machine('virt') + self.require_accelerator("tcg") + + kernel_path = self.ASSET_VIRT_GPU_KERNEL.fetch() + image_path = self.uncompress(self.ASSET_VIRT_GPU_ROOTFS, format="zstd") + + self.vm.set_console() + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + + 'console=ttyAMA0 root=/dev/vda') + + self.vm.add_args("-accel", "tcg") + self.vm.add_args("-cpu", "neoverse-v1,pauth-impdef=on") + self.vm.add_args("-machine", "virt,gic-version=max", + '-kernel', kernel_path, + '-append', kernel_command_line) + self.vm.add_args("-smp", "2", "-m", "2048") + self.vm.add_args("-device", + "virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") + self.vm.add_args("-display", "egl-headless") + self.vm.add_args("-display", "dbus,gl=on") + self.vm.add_args("-device", "virtio-blk-device,drive=hd0") + self.vm.add_args("-blockdev", + "driver=raw,file.driver=file," + "node-name=hd0,read-only=on," + f"file.filename={image_path}") + self.vm.add_args("-snapshot") + + try: + self.vm.launch() + except VMLaunchFailure as excp: + if "old virglrenderer, blob resources unsupported" in excp.output: + self.skipTest("No blob support for virtio-gpu") + elif "old virglrenderer, venus unsupported" in excp.output: + self.skipTest("No venus support for virtio-gpu") + elif "egl: no drm render node available" in excp.output: + self.skipTest("Can't access host DRM render node") + elif "'type' does not accept value 'egl-headless'" in excp.output: + self.skipTest("egl-headless support is not available") + else: + self.log.info(f"unhandled launch failure: {excp.output}") + raise excp + + self.wait_for_console_pattern('buildroot login:') + exec_command(self, 'root') + exec_command(self, 'export XDG_RUNTIME_DIR=/tmp') + exec_command_and_wait_for_pattern(self, + "weston -B headless " + "--renderer gl " + "--shell kiosk " + "-- vkmark -b:duration=1.0", + "vkmark Score") + +if __name__ == '__main__': + LinuxKernelTest.main() From 868c7703e052a14f9c612c38f7171581cb626f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:09 +0000 Subject: [PATCH 02/31] tests/functional: factor out common code in gpu test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for handling more tests split out the common machine setup details from the test specific stuff and add a helper for launching the weston test. Instead of searching for "vkmark score" we set a custom PS1 and wait for a successful completion. This ensures we capture the score in the console log which otherwise wouldn't log anything. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-3-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 38 +++++++++++++---------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index 32af941cd5..b4679c0460 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -12,7 +12,7 @@ from qemu.machine.machine import VMLaunchFailure from qemu_test import Asset -from qemu_test import exec_command, exec_command_and_wait_for_pattern +from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait from qemu_test import skipIfMissingCommands from qemu_test.linuxkernel import LinuxKernelTest @@ -31,12 +31,7 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): 'rootfs.ext4.zstd', '792da7573f5dc2913ddb7c638151d4a6b2d028a4cb2afb38add513c1924bdad4') - @skipIfMissingCommands('zstd') - def test_aarch64_virt_with_vulkan_gpu(self): - # This tests boots with a buildroot test image that contains - # vkmark and other GPU exercising tools. We run a headless - # weston that nevertheless still exercises the virtio-gpu - # backend. + def _launch_virt_gpu(self, gpu_device): self.set_machine('virt') self.require_accelerator("tcg") @@ -54,10 +49,10 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): '-kernel', kernel_path, '-append', kernel_command_line) self.vm.add_args("-smp", "2", "-m", "2048") - self.vm.add_args("-device", - "virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") + self.vm.add_args("-device", gpu_device) self.vm.add_args("-display", "egl-headless") self.vm.add_args("-display", "dbus,gl=on") + self.vm.add_args("-device", "virtio-blk-device,drive=hd0") self.vm.add_args("-blockdev", "driver=raw,file.driver=file," @@ -81,14 +76,23 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): raise excp self.wait_for_console_pattern('buildroot login:') - exec_command(self, 'root') - exec_command(self, 'export XDG_RUNTIME_DIR=/tmp') - exec_command_and_wait_for_pattern(self, - "weston -B headless " - "--renderer gl " - "--shell kiosk " - "-- vkmark -b:duration=1.0", - "vkmark Score") + ec_and_wait(self, 'root', '#') + + def _run_virt_weston_test(self, cmd): + + # make it easier to detect successful return to shell + PS1 = 'RES=[$?] # ' + OK_CMD = 'RES=[0] # ' + + ec_and_wait(self, 'export XDG_RUNTIME_DIR=/tmp', '#') + ec_and_wait(self, f"export PS1='{PS1}'", OK_CMD) + full_cmd = f"weston -B headless --renderer gl --shell kiosk -- {cmd}" + ec_and_wait(self, full_cmd, OK_CMD) + + @skipIfMissingCommands('zstd') + def test_aarch64_virt_with_vulkan_gpu(self): + self._launch_virt_gpu("virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") + self._run_virt_weston_test("vkmark -b:duration=1.0") if __name__ == '__main__': LinuxKernelTest.main() From 94634fbc66869b31491e95c26eab731d67c13e7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:10 +0000 Subject: [PATCH 03/31] tests/functional: ensure we have a GPU device for tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It's possible to build QEMU without support for the GL enabled GPU devices and we can catch that earlier with an explicit check. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-4-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index b4679c0460..9a1ee2befc 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -91,6 +91,9 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): @skipIfMissingCommands('zstd') def test_aarch64_virt_with_vulkan_gpu(self): + + self.require_device('virtio-gpu-gl-pci') + self._launch_virt_gpu("virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") self._run_virt_weston_test("vkmark -b:duration=1.0") From 4e4e6986b62d0bb29282e4aeb09ca5b959b0afe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:11 +0000 Subject: [PATCH 04/31] tests/functional: bail early if vkmark hangs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The message: MESA-VIRTIO: debug: stuck in fence wait with iter at %d Seems to occur more often on debug builds. Rather than waiting for our long timeout to hit we might as well bail as soon as we see the message. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-5-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index 9a1ee2befc..eea1e8c973 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -78,7 +78,7 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): self.wait_for_console_pattern('buildroot login:') ec_and_wait(self, 'root', '#') - def _run_virt_weston_test(self, cmd): + def _run_virt_weston_test(self, cmd, fail = None): # make it easier to detect successful return to shell PS1 = 'RES=[$?] # ' @@ -87,7 +87,7 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): ec_and_wait(self, 'export XDG_RUNTIME_DIR=/tmp', '#') ec_and_wait(self, f"export PS1='{PS1}'", OK_CMD) full_cmd = f"weston -B headless --renderer gl --shell kiosk -- {cmd}" - ec_and_wait(self, full_cmd, OK_CMD) + ec_and_wait(self, full_cmd, OK_CMD, fail) @skipIfMissingCommands('zstd') def test_aarch64_virt_with_vulkan_gpu(self): @@ -95,7 +95,9 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): self.require_device('virtio-gpu-gl-pci') self._launch_virt_gpu("virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") - self._run_virt_weston_test("vkmark -b:duration=1.0") + self._run_virt_weston_test("vkmark -b:duration=1.0", + "debug: stuck in fence wait with iter at") + if __name__ == '__main__': LinuxKernelTest.main() From 9f7e493d117c852be4af529c1670c293eab063b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:12 +0000 Subject: [PATCH 05/31] tests/functional: skip vulkan tests with nVidia MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While running the new GPU tests it was noted that the proprietary nVidia driver barfed when run under the sanitiser: 2025-02-20 11:13:08,226: [11:13:07.782] Output 'headless' attempts EOTF mode SDR and colorimetry mode default. 2025-02-20 11:13:08,227: [11:13:07.784] Output 'headless' using color profile: stock sRGB color profile and that's the last thing it outputs. The sanitizer reports that when the framework sends the SIGTERM because of the timeout we get a write to a NULL pointer (but interesting not this time in an atexit callback): UndefinedBehaviorSanitizer:DEADLYSIGNAL ==471863==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7a18ceaafe80 bp 0x000000000000 sp 0x7ffe8e3ff6d0 T471863) ==471863==The signal is caused by a WRITE memory access. ==471863==Hint: address points to the zero page. #0 0x7a18ceaafe80 (/lib/x86_64-linux-gnu/libnvidia-eglcore.so.535.183.01+0x16afe80) (BuildId: 24b0d0b90369112e3de888a93eb8d7e00304a6db) #1 0x7a18ce9e72c0 (/lib/x86_64-linux-gnu/libnvidia-eglcore.so.535.183.01+0x15e72c0) (BuildId: 24b0d0b90369112e3de888a93eb8d7e00304a6db) #2 0x7a18ce9f11bb (/lib/x86_64-linux-gnu/libnvidia-eglcore.so.535.183.01+0x15f11bb) (BuildId: 24b0d0b90369112e3de888a93eb8d7e00304a6db) #3 0x7a18ce6dc9d1 (/lib/x86_64-linux-gnu/libnvidia-eglcore.so.535.183.01+0x12dc9d1) (BuildId: 24b0d0b90369112e3de888a93eb8d7e00304a6db) #4 0x7a18e7d15326 in vrend_renderer_create_fence /usr/src/virglrenderer-1.0.0-1ubuntu2/obj-x86_64-linux-gnu/../src/vrend_renderer.c:10883:26 #5 0x55bfb6621871 in virtio_gpu_virgl_process_cmd The #dri-devel channel confirmed: stsquad: nv driver is known to not work with venus, don't use it for testing So lets skip running the test to avoid known failures. As we now use vulkaninfo to probe we also need to handle the case where there is no Vulkan driver configured for the hardware. Reviewed-by: Thomas Huth Reported-by: Peter Maydell Cc: Dmitry Osipenko [AJB: also skip if vulkaninfo can't find environment] Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-6-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index eea1e8c973..8e6f081544 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -17,6 +17,9 @@ from qemu_test import skipIfMissingCommands from qemu_test.linuxkernel import LinuxKernelTest +from re import search +from subprocess import check_output, CalledProcessError + class Aarch64VirtGPUMachine(LinuxKernelTest): ASSET_VIRT_GPU_KERNEL = Asset( @@ -72,7 +75,7 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): elif "'type' does not accept value 'egl-headless'" in excp.output: self.skipTest("egl-headless support is not available") else: - self.log.info(f"unhandled launch failure: {excp.output}") + self.log.info("unhandled launch failure: %s", excp.output) raise excp self.wait_for_console_pattern('buildroot login:') @@ -94,6 +97,15 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): self.require_device('virtio-gpu-gl-pci') + try: + vk_info = check_output(["vulkaninfo", "--summary"], + encoding="utf-8") + except CalledProcessError as excp: + self.skipTest(f"Miss-configured host Vulkan: {excp.output}") + + if search(r"driverID\s+=\s+DRIVER_ID_NVIDIA_PROPRIETARY", vk_info): + self.skipTest("Test skipped on NVIDIA proprietary driver") + self._launch_virt_gpu("virtio-gpu-gl-pci,hostmem=4G,blob=on,venus=on") self._run_virt_weston_test("vkmark -b:duration=1.0", "debug: stuck in fence wait with iter at") From 8233f4f26d831c72970d00164f8f58a63c73ecfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:13 +0000 Subject: [PATCH 06/31] tests/functional: expand tests to cover virgl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two more test modes using glmark2-wayland to exercise the OpenGL pass-through modes with virgl. Virgl can run with or without the hostmem blob support. To avoid repeating ourselves too much we make the initial pass a simple --validate pass. We might want to eventually add more directed tests and individual features later on but the glmark/vkmark tests are a good general smoke test for accelerated 3D. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-7-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index 8e6f081544..56a3ed3193 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -92,6 +92,28 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): full_cmd = f"weston -B headless --renderer gl --shell kiosk -- {cmd}" ec_and_wait(self, full_cmd, OK_CMD, fail) + @skipIfMissingCommands('zstd') + def test_aarch64_virt_with_virgl_gpu(self): + + self.require_device('virtio-gpu-gl-pci') + + self._launch_virt_gpu("virtio-gpu-gl-pci") + + # subset of the glmark tests + tests = " ".join([f"-b {test}" for test in + ["build", "texture", "shading", + "bump", "desktop", "buffer"]]) + + self._run_virt_weston_test("glmark2-wayland --validate " + tests) + + @skipIfMissingCommands('zstd') + def test_aarch64_virt_with_virgl_blobs_gpu(self): + + self.require_device('virtio-gpu-gl-pci') + + self._launch_virt_gpu("virtio-gpu-gl-pci,hostmem=4G,blob=on") + self._run_virt_weston_test("glmark2-wayland -b:duration=1.0") + @skipIfMissingCommands('zstd') def test_aarch64_virt_with_vulkan_gpu(self): From d69178d3705994c1e4f7f919dfb6dd31b8b11d80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:14 +0000 Subject: [PATCH 07/31] tests/functional: update the aarch64_virg_gpu images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update to the most recent aarch64_virt_gpu image. The principle differences are: - target a v8.0 baseline CPU - latest vkmark (2025.1) - actually uses the rootfs (previously was initrd) - rootfs includes more testing tools for interactive use See README.md in https://fileserver.linaro.org/s/ce5jXBFinPxtEdx for details about the image creation and the buildroot config. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-8-alex.bennee@linaro.org> --- tests/functional/test_aarch64_virt_gpu.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/test_aarch64_virt_gpu.py index 56a3ed3193..f19a47f8b6 100755 --- a/tests/functional/test_aarch64_virt_gpu.py +++ b/tests/functional/test_aarch64_virt_gpu.py @@ -25,14 +25,14 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): ASSET_VIRT_GPU_KERNEL = Asset( 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' 'download?path=%2F&files=' - 'Image', - '89e5099d26166204cc5ca4bb6d1a11b92c217e1f82ec67e3ba363d09157462f6') + 'Image.6.12.16.aarch64', + '7888c51c55d37e86bbbdeb5acea9f08c34e6b0f03c1f5b2463285f6a6f6eec8b') ASSET_VIRT_GPU_ROOTFS = Asset( 'https://fileserver.linaro.org/s/ce5jXBFinPxtEdx/' 'download?path=%2F&files=' - 'rootfs.ext4.zstd', - '792da7573f5dc2913ddb7c638151d4a6b2d028a4cb2afb38add513c1924bdad4') + 'rootfs.aarch64.ext2.zstd', + 'd45118c899420b7e673f1539a37a35480134b3e36e3a59e2cb69b1781cbb14ef') def _launch_virt_gpu(self, gpu_device): @@ -47,7 +47,7 @@ class Aarch64VirtGPUMachine(LinuxKernelTest): 'console=ttyAMA0 root=/dev/vda') self.vm.add_args("-accel", "tcg") - self.vm.add_args("-cpu", "neoverse-v1,pauth-impdef=on") + self.vm.add_args("-cpu", "cortex-a72") self.vm.add_args("-machine", "virt,gic-version=max", '-kernel', kernel_path, '-append', kernel_command_line) From 892b06c40e46656b07579b9f4fb7a8f2652cacf2 Mon Sep 17 00:00:00 2001 From: Pierrick Bouvier Date: Tue, 4 Mar 2025 22:24:15 +0000 Subject: [PATCH 08/31] plugins: add explicit dependency in functional tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ./tests/functional/test_aarch64_tcg_plugins.py needs to have plugin libinsn built. However, it's not listed as a dependency, so meson can't know it needs to be built. Thus, we keep track of all plugins, and add them as an explicit dependency. Fixes: 4c134d07b9e ("tests: add a new set of tests to exercise plugins") Signed-off-by: Pierrick Bouvier Tested-by: Philippe Mathieu-Daudé Signed-off-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-9-alex.bennee@linaro.org> --- contrib/plugins/meson.build | 2 ++ meson.build | 1 + tests/functional/meson.build | 2 +- tests/tcg/plugins/meson.build | 2 ++ 4 files changed, 6 insertions(+), 1 deletion(-) diff --git a/contrib/plugins/meson.build b/contrib/plugins/meson.build index 484b9a808c..fa8a426c8b 100644 --- a/contrib/plugins/meson.build +++ b/contrib/plugins/meson.build @@ -26,3 +26,5 @@ if t.length() > 0 else run_target('contrib-plugins', command: find_program('true')) endif + +plugin_modules += t diff --git a/meson.build b/meson.build index 4899d896de..9d9c11731f 100644 --- a/meson.build +++ b/meson.build @@ -3668,6 +3668,7 @@ qtest_module_ss = ss.source_set() modules = {} target_modules = {} +plugin_modules = [] hw_arch = {} target_arch = {} target_system_arch = {} diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 7fcc4731d5..e78560a901 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -385,7 +385,7 @@ foreach speed : ['quick', 'thorough'] # 'run_target' logic below & in Makefile.include test('func-' + testname, python, - depends: [test_deps, test_emulator, emulator_modules], + depends: [test_deps, test_emulator, emulator_modules, plugin_modules], env: test_env, args: [testpath], protocol: 'tap', diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build index 87a17d67bd..c8cb0626a6 100644 --- a/tests/tcg/plugins/meson.build +++ b/tests/tcg/plugins/meson.build @@ -19,3 +19,5 @@ if t.length() > 0 else run_target('test-plugins', command: find_program('true')) endif + +plugin_modules += t From 3a7b9054b8d761e61628e67e90b118d05b4a4697 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 4 Mar 2025 22:24:16 +0000 Subject: [PATCH 09/31] tests/functional: Introduce the dso_suffix() helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce a helper to get the default shared library suffix used on the host. Suggested-by: Pierrick Bouvier Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Pierrick Bouvier Reviewed-by: Thomas Huth Message-Id: <20250220080215.49165-3-philmd@linaro.org> [AJB: dropped whitespace cmd.py damage] Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-10-alex.bennee@linaro.org> --- tests/functional/qemu_test/__init__.py | 2 +- tests/functional/qemu_test/config.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py index 5c972843a6..45f7befa37 100644 --- a/tests/functional/qemu_test/__init__.py +++ b/tests/functional/qemu_test/__init__.py @@ -7,7 +7,7 @@ from .asset import Asset -from .config import BUILD_DIR +from .config import BUILD_DIR, dso_suffix from .cmd import is_readable_executable_file, \ interrupt_interactive_console_until_pattern, wait_for_console_pattern, \ exec_command, exec_command_and_wait_for_pattern, get_qemu_img, which diff --git a/tests/functional/qemu_test/config.py b/tests/functional/qemu_test/config.py index edd75b7fd0..6d4c9c3ce1 100644 --- a/tests/functional/qemu_test/config.py +++ b/tests/functional/qemu_test/config.py @@ -13,6 +13,7 @@ import os from pathlib import Path +import platform def _source_dir(): @@ -34,3 +35,14 @@ def _build_dir(): raise Exception("Cannot identify build dir, set QEMU_BUILD_ROOT") BUILD_DIR = _build_dir() + +def dso_suffix(): + '''Return the dynamic libraries suffix for the current platform''' + + if platform.system() == "Darwin": + return "dylib" + + if platform.system() == "Windows": + return "dll" + + return "so" From ed557cc544b2162eec8ec977af65cdd09277d44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Date: Tue, 4 Mar 2025 22:24:17 +0000 Subject: [PATCH 10/31] tests/functional: Allow running TCG plugins tests on non-Linux/BSD hosts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Not all platforms use the '.so' suffix for shared libraries, which is how plugins are built. Use the recently introduced dso_suffix() helper to get the proper host suffix. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2804 Suggested-by: Pierrick Bouvier Suggested-by: Daniel P. Berrangé Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Pierrick Bouvier Reviewed-by: Thomas Huth Message-Id: <20250220080215.49165-4-philmd@linaro.org> [AJB: moved plugin_file into testcase.py] Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-11-alex.bennee@linaro.org> --- tests/functional/qemu_test/testcase.py | 12 +++++++++++- tests/functional/test_aarch64_tcg_plugins.py | 5 +++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py index 058bf270ec..50d232a7c6 100644 --- a/tests/functional/qemu_test/testcase.py +++ b/tests/functional/qemu_test/testcase.py @@ -27,7 +27,7 @@ from qemu.utils import kvm_available, tcg_available from .archive import archive_extract from .asset import Asset -from .config import BUILD_DIR +from .config import BUILD_DIR, dso_suffix from .uncompress import uncompress @@ -183,6 +183,16 @@ class QemuBaseTest(unittest.TestCase): def log_file(self, *args): return str(Path(self.outputdir, *args)) + ''' + @params plugin name + + Return the full path to the plugin taking into account any host OS + specific suffixes. + ''' + def plugin_file(self, plugin_name): + sfx = dso_suffix() + return os.path.join('tests', 'tcg', 'plugins', f'{plugin_name}.{sfx}') + def assets_available(self): for name, asset in vars(self.__class__).items(): if name.startswith("ASSET_") and type(asset) == Asset: diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/test_aarch64_tcg_plugins.py index 7e8beacc83..4ea71f5f88 100755 --- a/tests/functional/test_aarch64_tcg_plugins.py +++ b/tests/functional/test_aarch64_tcg_plugins.py @@ -13,6 +13,7 @@ import tempfile import mmap +import os import re from qemu.machine.machine import VMLaunchFailure @@ -74,7 +75,7 @@ class PluginKernelNormal(PluginKernelBase): suffix=".log") self.run_vm(kernel_path, kernel_command_line, - "tests/tcg/plugins/libinsn.so", plugin_log.name, + self.plugin_file('libinsn'), plugin_log.name, console_pattern) with plugin_log as lf, \ @@ -100,7 +101,7 @@ class PluginKernelNormal(PluginKernelBase): suffix=".log") self.run_vm(kernel_path, kernel_command_line, - "tests/tcg/plugins/libinsn.so", plugin_log.name, + self.plugin_file('libinsn'), plugin_log.name, console_pattern, args=('-icount', 'shift=1')) From 4748be5e9df56e13045c0f76fe9f60fa7655fed7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:18 +0000 Subject: [PATCH 11/31] libvirt-ci: bump to latest for vulkan-tools MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The alpine baseline has also been updated in the meantime so we need to address that while we are at it. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-12-alex.bennee@linaro.org> --- .gitlab-ci.d/cirrus/freebsd-14.vars | 2 +- .gitlab-ci.d/cirrus/macos-14.vars | 2 +- scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml | 1 + scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml | 1 + tests/docker/dockerfiles/alpine.docker | 5 +++-- tests/docker/dockerfiles/centos9.docker | 1 + tests/docker/dockerfiles/debian-amd64-cross.docker | 3 ++- tests/docker/dockerfiles/debian-arm64-cross.docker | 3 ++- tests/docker/dockerfiles/debian-armhf-cross.docker | 3 ++- tests/docker/dockerfiles/debian-i686-cross.docker | 3 ++- tests/docker/dockerfiles/debian-mips64el-cross.docker | 3 ++- tests/docker/dockerfiles/debian-mipsel-cross.docker | 3 ++- tests/docker/dockerfiles/debian-ppc64el-cross.docker | 3 ++- tests/docker/dockerfiles/debian-s390x-cross.docker | 3 ++- tests/docker/dockerfiles/debian.docker | 3 ++- tests/docker/dockerfiles/fedora-rust-nightly.docker | 1 + tests/docker/dockerfiles/fedora-win64-cross.docker | 1 + tests/docker/dockerfiles/fedora.docker | 1 + tests/docker/dockerfiles/opensuse-leap.docker | 1 + tests/docker/dockerfiles/ubuntu2204.docker | 1 + tests/lcitool/libvirt-ci | 2 +- tests/lcitool/projects/qemu.yml | 1 + tests/lcitool/refresh | 2 +- tests/vm/generated/freebsd.json | 1 + 24 files changed, 35 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.d/cirrus/freebsd-14.vars b/.gitlab-ci.d/cirrus/freebsd-14.vars index 0997c47af5..19ca0d3663 100644 --- a/.gitlab-ci.d/cirrus/freebsd-14.vars +++ b/.gitlab-ci.d/cirrus/freebsd-14.vars @@ -11,6 +11,6 @@ MAKE='/usr/local/bin/gmake' NINJA='/usr/local/bin/ninja' PACKAGING_COMMAND='pkg' PIP3='/usr/local/bin/pip' -PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache4 cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk-vnc gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py311-numpy py311-pillow py311-pip py311-pyyaml py311-sphinx py311-sphinx_rtd_theme py311-tomli python3 rpm2cpio rust rust-bindgen-cli sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 xorriso zstd' +PKGS='alsa-lib bash bison bzip2 ca_root_nss capstone4 ccache4 cmocka ctags curl cyrus-sasl dbus diffutils dtc flex fusefs-libs3 gettext git glib gmake gnutls gsed gtk-vnc gtk3 json-c libepoxy libffi libgcrypt libjpeg-turbo libnfs libslirp libspice-server libssh libtasn1 llvm lzo2 meson mtools ncurses nettle ninja opencv pixman pkgconf png py311-numpy py311-pillow py311-pip py311-pyyaml py311-sphinx py311-sphinx_rtd_theme py311-tomli python3 rpm2cpio rust rust-bindgen-cli sdl2 sdl2_image snappy sndio socat spice-protocol tesseract usbredir virglrenderer vte3 vulkan-tools xorriso zstd' PYPI_PKGS='' PYTHON='/usr/local/bin/python3' diff --git a/.gitlab-ci.d/cirrus/macos-14.vars b/.gitlab-ci.d/cirrus/macos-14.vars index 25dff322e6..b039465f56 100644 --- a/.gitlab-ci.d/cirrus/macos-14.vars +++ b/.gitlab-ci.d/cirrus/macos-14.vars @@ -11,6 +11,6 @@ MAKE='/opt/homebrew/bin/gmake' NINJA='/opt/homebrew/bin/ninja' PACKAGING_COMMAND='brew' PIP3='/opt/homebrew/bin/pip3' -PKGS='bash bc bindgen bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 gtk-vnc jemalloc jpeg-turbo json-c libcbor libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio rust sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 xorriso zlib zstd' +PKGS='bash bc bindgen bison bzip2 capstone ccache cmocka ctags curl dbus diffutils dtc flex gcovr gettext git glib gnu-sed gnutls gtk+3 gtk-vnc jemalloc jpeg-turbo json-c libcbor libepoxy libffi libgcrypt libiscsi libnfs libpng libslirp libssh libtasn1 libusb llvm lzo make meson mtools ncurses nettle ninja pixman pkg-config python3 rpm2cpio rust sdl2 sdl2_image snappy socat sparse spice-protocol swtpm tesseract usbredir vde vte3 vulkan-tools xorriso zlib zstd' PYPI_PKGS='PyYAML numpy pillow sphinx sphinx-rtd-theme tomli' PYTHON='/opt/homebrew/bin/python3' diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml index 288156d1e4..dbcd2e076d 100644 --- a/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml +++ b/scripts/ci/setup/ubuntu/ubuntu-2204-aarch64.yaml @@ -123,6 +123,7 @@ packages: - tar - tesseract-ocr - tesseract-ocr-eng + - vulkan-tools - xorriso - zlib1g-dev - zstd diff --git a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml index d497139ef3..4b8ee3d885 100644 --- a/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml +++ b/scripts/ci/setup/ubuntu/ubuntu-2204-s390x.yaml @@ -121,6 +121,7 @@ packages: - tar - tesseract-ocr - tesseract-ocr-eng + - vulkan-tools - xorriso - zlib1g-dev - zstd diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker index f87c40fbfe..bf3bd5a30d 100644 --- a/tests/docker/dockerfiles/alpine.docker +++ b/tests/docker/dockerfiles/alpine.docker @@ -1,10 +1,10 @@ # THIS FILE WAS AUTO-GENERATED # -# $ lcitool dockerfile --layers all alpine-319 qemu +# $ lcitool dockerfile --layers all alpine-321 qemu # # https://gitlab.com/libvirt/libvirt-ci -FROM docker.io/library/alpine:3.19 +FROM docker.io/library/alpine:3.21 RUN apk update && \ apk upgrade && \ @@ -111,6 +111,7 @@ RUN apk update && \ vde2-dev \ virglrenderer-dev \ vte3-dev \ + vulkan-tools \ which \ xen-dev \ xorriso \ diff --git a/tests/docker/dockerfiles/centos9.docker b/tests/docker/dockerfiles/centos9.docker index a9681c8a96..a942835a1d 100644 --- a/tests/docker/dockerfiles/centos9.docker +++ b/tests/docker/dockerfiles/centos9.docker @@ -115,6 +115,7 @@ RUN dnf distro-sync -y && \ usbredir-devel \ util-linux \ vte291-devel \ + vulkan-tools \ which \ xorriso \ zlib-devel \ diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker index 644fd3734d..0535585428 100644 --- a/tests/docker/dockerfiles/debian-amd64-cross.docker +++ b/tests/docker/dockerfiles/debian-amd64-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -135,7 +136,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:amd64 \ libspice-protocol-dev:amd64 \ libspice-server-dev:amd64 \ - libssh-gcrypt-dev:amd64 \ + libssh-dev:amd64 \ libsystemd-dev:amd64 \ libtasn1-6-dev:amd64 \ libubsan1:amd64 \ diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker index 060da53796..6b1e4fc827 100644 --- a/tests/docker/dockerfiles/debian-arm64-cross.docker +++ b/tests/docker/dockerfiles/debian-arm64-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -134,7 +135,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:arm64 \ libspice-protocol-dev:arm64 \ libspice-server-dev:arm64 \ - libssh-gcrypt-dev:arm64 \ + libssh-dev:arm64 \ libsystemd-dev:arm64 \ libtasn1-6-dev:arm64 \ libubsan1:arm64 \ diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker index a481fc9695..cf0fe63af9 100644 --- a/tests/docker/dockerfiles/debian-armhf-cross.docker +++ b/tests/docker/dockerfiles/debian-armhf-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -134,7 +135,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:armhf \ libspice-protocol-dev:armhf \ libspice-server-dev:armhf \ - libssh-gcrypt-dev:armhf \ + libssh-dev:armhf \ libsystemd-dev:armhf \ libtasn1-6-dev:armhf \ libubsan1:armhf \ diff --git a/tests/docker/dockerfiles/debian-i686-cross.docker b/tests/docker/dockerfiles/debian-i686-cross.docker index 61bc361e85..1c84dfb945 100644 --- a/tests/docker/dockerfiles/debian-i686-cross.docker +++ b/tests/docker/dockerfiles/debian-i686-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -134,7 +135,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:i386 \ libspice-protocol-dev:i386 \ libspice-server-dev:i386 \ - libssh-gcrypt-dev:i386 \ + libssh-dev:i386 \ libsystemd-dev:i386 \ libtasn1-6-dev:i386 \ libubsan1:i386 \ diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker index 9f6c4763c5..257204eae4 100644 --- a/tests/docker/dockerfiles/debian-mips64el-cross.docker +++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -133,7 +134,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:mips64el \ libspice-protocol-dev:mips64el \ libspice-server-dev:mips64el \ - libssh-gcrypt-dev:mips64el \ + libssh-dev:mips64el \ libsystemd-dev:mips64el \ libtasn1-6-dev:mips64el \ libudev-dev:mips64el \ diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker index 2e979111e0..395c84d65b 100644 --- a/tests/docker/dockerfiles/debian-mipsel-cross.docker +++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -133,7 +134,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:mipsel \ libspice-protocol-dev:mipsel \ libspice-server-dev:mipsel \ - libssh-gcrypt-dev:mipsel \ + libssh-dev:mipsel \ libsystemd-dev:mipsel \ libtasn1-6-dev:mipsel \ libudev-dev:mipsel \ diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker index 8ee450dba0..1ae227ccde 100644 --- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker +++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -134,7 +135,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev:ppc64el \ libspice-protocol-dev:ppc64el \ libspice-server-dev:ppc64el \ - libssh-gcrypt-dev:ppc64el \ + libssh-dev:ppc64el \ libsystemd-dev:ppc64el \ libtasn1-6-dev:ppc64el \ libubsan1:ppc64el \ diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker index f451a07c4c..afa81a57ba 100644 --- a/tests/docker/dockerfiles/debian-s390x-cross.docker +++ b/tests/docker/dockerfiles/debian-s390x-cross.docker @@ -58,6 +58,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zstd && \ eatmydata apt-get autoremove -y && \ @@ -133,7 +134,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsnappy-dev:s390x \ libsndio-dev:s390x \ libspice-protocol-dev:s390x \ - libssh-gcrypt-dev:s390x \ + libssh-dev:s390x \ libsystemd-dev:s390x \ libtasn1-6-dev:s390x \ libubsan1:s390x \ diff --git a/tests/docker/dockerfiles/debian.docker b/tests/docker/dockerfiles/debian.docker index 505330a9e2..5b3bac43cc 100644 --- a/tests/docker/dockerfiles/debian.docker +++ b/tests/docker/dockerfiles/debian.docker @@ -87,7 +87,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ libsndio-dev \ libspice-protocol-dev \ libspice-server-dev \ - libssh-gcrypt-dev \ + libssh-dev \ libsystemd-dev \ libtasn1-6-dev \ libubsan1 \ @@ -131,6 +131,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zlib1g-dev \ zstd && \ diff --git a/tests/docker/dockerfiles/fedora-rust-nightly.docker b/tests/docker/dockerfiles/fedora-rust-nightly.docker index a8e4fb279a..fe4a6ed48d 100644 --- a/tests/docker/dockerfiles/fedora-rust-nightly.docker +++ b/tests/docker/dockerfiles/fedora-rust-nightly.docker @@ -132,6 +132,7 @@ exec "$@"\n' > /usr/bin/nosync && \ util-linux \ virglrenderer-devel \ vte291-devel \ + vulkan-tools \ which \ xen-devel \ xorriso \ diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker index 7dc3eb03f5..a950344402 100644 --- a/tests/docker/dockerfiles/fedora-win64-cross.docker +++ b/tests/docker/dockerfiles/fedora-win64-cross.docker @@ -61,6 +61,7 @@ exec "$@"\n' > /usr/bin/nosync && \ tesseract \ tesseract-langpack-eng \ util-linux \ + vulkan-tools \ which \ xorriso \ zstd && \ diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker index b64399af66..014e3ccf17 100644 --- a/tests/docker/dockerfiles/fedora.docker +++ b/tests/docker/dockerfiles/fedora.docker @@ -132,6 +132,7 @@ exec "$@"\n' > /usr/bin/nosync && \ util-linux \ virglrenderer-devel \ vte291-devel \ + vulkan-tools \ which \ xen-devel \ xorriso \ diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker index 4d5fb3e3a1..e90225dc23 100644 --- a/tests/docker/dockerfiles/opensuse-leap.docker +++ b/tests/docker/dockerfiles/opensuse-leap.docker @@ -115,6 +115,7 @@ RUN zypper update -y && \ util-linux \ virglrenderer-devel \ vte-devel \ + vulkan-tools \ which \ xen-devel \ xorriso \ diff --git a/tests/docker/dockerfiles/ubuntu2204.docker b/tests/docker/dockerfiles/ubuntu2204.docker index e1b70b536d..88ce4ef9a9 100644 --- a/tests/docker/dockerfiles/ubuntu2204.docker +++ b/tests/docker/dockerfiles/ubuntu2204.docker @@ -130,6 +130,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \ tar \ tesseract-ocr \ tesseract-ocr-eng \ + vulkan-tools \ xorriso \ zlib1g-dev \ zstd && \ diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci index b6a65806bc..18c4bfe02c 160000 --- a/tests/lcitool/libvirt-ci +++ b/tests/lcitool/libvirt-ci @@ -1 +1 @@ -Subproject commit b6a65806bc9b2b56985f5e97c936b77c7e7a99fc +Subproject commit 18c4bfe02c467e5639bf9a687139735ccd7a3fff diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml index 80bcac0902..c07242f272 100644 --- a/tests/lcitool/projects/qemu.yml +++ b/tests/lcitool/projects/qemu.yml @@ -122,6 +122,7 @@ packages: - usbredir - virglrenderer - vte + - vulkan-tools - which - xen - xorriso diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh index 53f8d2585f..aa551aca9b 100755 --- a/tests/lcitool/refresh +++ b/tests/lcitool/refresh @@ -163,7 +163,7 @@ try: # # Standard native builds # - generate_dockerfile("alpine", "alpine-319") + generate_dockerfile("alpine", "alpine-321") generate_dockerfile("centos9", "centos-stream-9") generate_dockerfile("debian", "debian-12", trailer="".join(debian12_extras)) diff --git a/tests/vm/generated/freebsd.json b/tests/vm/generated/freebsd.json index 81fc38d798..c03e1cd586 100644 --- a/tests/vm/generated/freebsd.json +++ b/tests/vm/generated/freebsd.json @@ -73,6 +73,7 @@ "usbredir", "virglrenderer", "vte3", + "vulkan-tools", "xorriso", "zstd" ], From 830bbfb965274c2ac577420d28c7adecf8a39fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:19 +0000 Subject: [PATCH 12/31] tests/vm: bump timeout for shutdown MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On my fairly beefy machine the timeout was triggering leaving a corrupted disk image due to power being pulled before the disk had synced. Triple the timeout to avoid this. Reviewed-by: Thomas Huth Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-13-alex.bennee@linaro.org> --- tests/vm/basevm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/vm/basevm.py b/tests/vm/basevm.py index 6d41ac7574..9e879e966a 100644 --- a/tests/vm/basevm.py +++ b/tests/vm/basevm.py @@ -83,7 +83,7 @@ class BaseVM(object): # command to halt the guest, can be overridden by subclasses poweroff = "poweroff" # Time to wait for shutdown to finish. - shutdown_timeout_default = 30 + shutdown_timeout_default = 90 # enable IPv6 networking ipv6 = True # This is the timeout on the wait for console bytes. From 33629b82aeadb070a803e5887d3a5de59b1c95c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:20 +0000 Subject: [PATCH 13/31] tests/tcg: mark test-vma as a linux-only test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The main multiarch tests should compile for any POSIX system, however test-vma's usage of MAP_NORESERVE makes it a linux-only test. Simply moving the source file is enough for the build logic to skip on BSD's. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-14-alex.bennee@linaro.org> --- tests/tcg/multiarch/{ => linux}/test-vma.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/tcg/multiarch/{ => linux}/test-vma.c (100%) diff --git a/tests/tcg/multiarch/test-vma.c b/tests/tcg/multiarch/linux/test-vma.c similarity index 100% rename from tests/tcg/multiarch/test-vma.c rename to tests/tcg/multiarch/linux/test-vma.c From 0cee7cfc2495c2c7d108c38a9b07162af78553b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:21 +0000 Subject: [PATCH 14/31] tests/tcg: add message to _Static_assert in test-avx MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for enabling clang and avoiding: error: '_Static_assert' with no message is a C2x extension [-Werror,-Wc2x-extensions] let us just add the message to silence the warning. Reviewed-by: Thomas Huth Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-15-alex.bennee@linaro.org> --- tests/tcg/i386/test-avx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tcg/i386/test-avx.c b/tests/tcg/i386/test-avx.c index 230e6d84b8..80fe363cfc 100644 --- a/tests/tcg/i386/test-avx.c +++ b/tests/tcg/i386/test-avx.c @@ -244,7 +244,7 @@ v4di indexd = {0x00000002ffffffcdull, 0xfffffff500000010ull, 0x0000003afffffff0ull, 0x000000000000000eull}; v4di gather_mem[0x20]; -_Static_assert(sizeof(gather_mem) == 1024); +_Static_assert(sizeof(gather_mem) == 1024, "gather_mem not expected size"); void init_f16reg(v4di *r) { From 77f005f954ea3cd0a161618a9f6c3f9d874c5b58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:22 +0000 Subject: [PATCH 15/31] tests/tcg: fix constraints in test-i386-adcox MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clang complains: clang -O2 -m64 -mcx16 /home/alex/lsrc/qemu.git/tests/tcg/i386/test-i386-adcox.c -o test-i386-adcox -static /home/alex/lsrc/qemu.git/tests/tcg/i386/test-i386-adcox.c:32:26: error: invalid input constraint '0' in asm : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); ^ /home/alex/lsrc/qemu.git/tests/tcg/i386/test-i386-adcox.c:57:26: error: invalid input constraint '0' in asm : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); ^ 2 errors generated. Pointing out a numbered input constraint can't point to a read/write output [1]. Convert to a read-only input constraint to allow this. [1] https://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20101101/036036.html Suggested-by: Daniel P. Berrangé Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-16-alex.bennee@linaro.org> --- tests/tcg/i386/test-i386-adcox.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/tcg/i386/test-i386-adcox.c b/tests/tcg/i386/test-i386-adcox.c index 16169efff8..a717064adb 100644 --- a/tests/tcg/i386/test-i386-adcox.c +++ b/tests/tcg/i386/test-i386-adcox.c @@ -29,7 +29,7 @@ void test_adox_adcx(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_ope "adcx %3, %1;" "pushf; pop %0" : "+r" (flags), "+r" (out_adcx), "+r" (out_adox) - : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); + : "r" ((REG) - 1), "0" (flags), "1" (out_adcx), "2" (out_adox)); assert(out_adcx == in_c + adcx_operand - 1); assert(out_adox == in_o + adox_operand - 1); @@ -53,8 +53,8 @@ void test_adcx_adox(uint32_t in_c, uint32_t in_o, REG adcx_operand, REG adox_ope "adcx %3, %1;" "adox %3, %2;" "pushf; pop %0" - : "+r" (flags), "+r" (out_adcx), "+r" (out_adox) - : "r" ((REG)-1), "0" (flags), "1" (out_adcx), "2" (out_adox)); + : "+r"(flags), "+r"(out_adcx), "+r"(out_adox) + : "r" ((REG)-1)); assert(out_adcx == in_c + adcx_operand - 1); assert(out_adox == in_o + adox_operand - 1); From 874c712dc148142dfdaf2589d66a17391fe331f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:23 +0000 Subject: [PATCH 16/31] tests/tcg: enable -fwrapv for test-i386-bmi MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We allow things like: tests/tcg/i386/test-i386-bmi2.c:124:35: warning: shifting a negative signed value is undefined [-Wshift-negative-value] assert(result == (mask & ~(-1 << 30))); in the main code, so allow it for the test. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-17-alex.bennee@linaro.org> --- tests/tcg/i386/Makefile.target | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/tcg/i386/Makefile.target b/tests/tcg/i386/Makefile.target index bbe2c44b2a..f1df40411b 100644 --- a/tests/tcg/i386/Makefile.target +++ b/tests/tcg/i386/Makefile.target @@ -22,7 +22,7 @@ run-test-i386-sse-exceptions: QEMU_OPTS += -cpu max test-i386-pcmpistri: CFLAGS += -msse4.2 run-test-i386-pcmpistri: QEMU_OPTS += -cpu max -test-i386-bmi2: CFLAGS=-O2 +test-i386-bmi2: CFLAGS=-O2 -fwrapv run-test-i386-bmi2: QEMU_OPTS += -cpu max test-i386-adcox: CFLAGS=-O2 From c05aec9d4a9cc0ab6615efad209acff6c750c40a Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 4 Mar 2025 22:24:24 +0000 Subject: [PATCH 17/31] tests/tcg: Suppress compiler false-positive warning on sha1.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GCC versions at least 12 through 15 incorrectly report a warning about code in sha1.c: tests/tcg/multiarch/sha1.c:161:13: warning: ‘SHA1Transform’ reading 64 bytes from a region of size 0 [-Wstringop-overread] 161 | SHA1Transform(context->state, &data[i]); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This is a piece of stock library code for doing SHA1 which we've simply copied, rather than writing ourselves. The bug has been reported to upstream GCC (about a different library's use of this code): https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106709 For our test case, since this isn't our original code and there isn't actually a bug in it, suppress the incorrect warning rather than trying to modify the code to work around the compiler issue. Resolves: https://gitlab.com/qemu-project/qemu/-/issues/2328 Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-Id: <20250227141343.1675415-1-peter.maydell@linaro.org> [AJB: -Wno-unknown-warning-option for clang's sake] Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-18-alex.bennee@linaro.org> --- tests/tcg/aarch64/Makefile.target | 3 ++- tests/tcg/arm/Makefile.target | 3 ++- tests/tcg/hexagon/Makefile.target | 2 +- tests/tcg/multiarch/Makefile.target | 8 ++++++++ 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target index 9efe2f81ad..16ddcf4f88 100644 --- a/tests/tcg/aarch64/Makefile.target +++ b/tests/tcg/aarch64/Makefile.target @@ -83,7 +83,8 @@ test-aes: CFLAGS += -O -march=armv8-a+aes test-aes: test-aes-main.c.inc # Vector SHA1 -sha1-vector: CFLAGS=-O3 +# Work around compiler false-positive warning, as we do for the 'sha1' test +sha1-vector: CFLAGS=-O3 -Wno-stringop-overread sha1-vector: sha1.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) run-sha1-vector: sha1-vector run-sha1 diff --git a/tests/tcg/arm/Makefile.target b/tests/tcg/arm/Makefile.target index 99a953b667..6189d7a0e2 100644 --- a/tests/tcg/arm/Makefile.target +++ b/tests/tcg/arm/Makefile.target @@ -61,7 +61,8 @@ endif ARM_TESTS += commpage # Vector SHA1 -sha1-vector: CFLAGS=-O3 +# Work around compiler false-positive warning, as we do for the 'sha1' test +sha1-vector: CFLAGS=-O3 -Wno-stringop-overread sha1-vector: sha1.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) run-sha1-vector: sha1-vector run-sha1 diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index e5182c01d8..4dfc39bc98 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -18,7 +18,7 @@ # Hexagon doesn't support gdb, so skip the EXTRA_RUNS EXTRA_RUNS = -CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal +CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal -Wno-unknown-warning-option CFLAGS += -fno-unroll-loops -fno-stack-protector HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target index 688a6be203..c769a7d69d 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -45,6 +45,14 @@ vma-pthread: LDFLAGS+=-pthread sigreturn-sigmask: CFLAGS+=-pthread sigreturn-sigmask: LDFLAGS+=-pthread +# GCC versions 12/13/14/15 at least incorrectly complain about +# "'SHA1Transform' reading 64 bytes from a region of size 0"; see the gcc bug +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106709 +# Since this is just a standard piece of library code we've borrowed for a +# TCG test case, suppress the warning rather than trying to modify the +# code to work around the compiler. +sha1: CFLAGS+=-Wno-stringop-overread + # The vma-pthread seems very sensitive on gitlab and we currently # don't know if its exposing a real bug or the test is flaky. ifneq ($(GITLAB_CI),) From 3df360cb03d56cecdc23abc5855ffceedfcbfa0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:25 +0000 Subject: [PATCH 18/31] gitlab: add a new build_unit job to track build size MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We want to reduce the total number of build units in the system to get on our way to a single binary. It will help to have some numbers so lets add a job to gitlab to track our progress. Cc: Pierrick Bouvier Cc: Philippe Mathieu-Daudé Cc: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-19-alex.bennee@linaro.org> --- .gitlab-ci.d/check-units.py | 66 ++++++++++++++++++++++++++++++++++ .gitlab-ci.d/static_checks.yml | 22 ++++++++++++ 2 files changed, 88 insertions(+) create mode 100755 .gitlab-ci.d/check-units.py diff --git a/.gitlab-ci.d/check-units.py b/.gitlab-ci.d/check-units.py new file mode 100755 index 0000000000..268a4118d5 --- /dev/null +++ b/.gitlab-ci.d/check-units.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 +# +# check-units.py: check the number of compilation units and identify +# those that are rebuilt multiple times +# +# Copyright (C) 2025 Linaro Ltd. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from os import access, R_OK, path +from sys import argv, exit +import json +from collections import Counter + + +def extract_build_units(cc_path): + """ + Extract the build units and their counds from compile_commands.json file. + + Returns: + Hash table of ["unit"] = count + """ + + j = json.load(open(cc_path, 'r')) + files = [f['file'] for f in j] + build_units = Counter(files) + + return build_units + + +def analyse_units(build_units): + """ + Analyse the build units and report stats and the top 10 rebuilds + """ + + print(f"Total source files: {len(build_units.keys())}") + print(f"Total build units: {sum(units.values())}") + + # Create a sorted list by number of rebuilds + sorted_build_units = sorted(build_units.items(), + key=lambda item: item[1], + reverse=True) + + print("Most rebuilt units:") + for unit, count in sorted_build_units[:20]: + print(f" {unit} built {count} times") + + print("Least rebuilt units:") + for unit, count in sorted_build_units[-10:]: + print(f" {unit} built {count} times") + + +if __name__ == "__main__": + if len(argv) != 2: + script_name = path.basename(argv[0]) + print(f"Usage: {script_name} ") + exit(1) + + cc_path = argv[1] + if path.isfile(cc_path) and access(cc_path, R_OK): + units = extract_build_units(cc_path) + analyse_units(units) + exit(0) + else: + print(f"{cc_path} doesn't exist or isn't readable") + exit(1) diff --git a/.gitlab-ci.d/static_checks.yml b/.gitlab-ci.d/static_checks.yml index c0ba453382..c3ed6de453 100644 --- a/.gitlab-ci.d/static_checks.yml +++ b/.gitlab-ci.d/static_checks.yml @@ -70,3 +70,25 @@ check-rust-tools-nightly: expire_in: 2 days paths: - rust/target/doc + +check-build-units: + extends: .base_job_template + stage: build + image: $CI_REGISTRY_IMAGE/qemu/debian:$QEMU_CI_CONTAINER_TAG + needs: + job: amd64-debian-container + before_script: + - source scripts/ci/gitlab-ci-section + - section_start setup "Install Tools" + - apt install --assume-yes --no-install-recommends jq + - section_end setup + script: + - mkdir build + - cd build + - section_start configure "Running configure" + - ../configure + - cd .. + - section_end configure + - section_start analyse "Analyse" + - .gitlab-ci.d/check-units.py build/compile_commands.json + - section_end analyse From 2a8e8544b285ace2a6f21b72e18d823738fc8167 Mon Sep 17 00:00:00 2001 From: Pierrick Bouvier Date: Tue, 4 Mar 2025 22:24:26 +0000 Subject: [PATCH 19/31] tests/functional: add boot error detection for RME tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was identified that those tests randomly fail with a synchronous exception at boot (reported by EDK2). While we solve this problem, report failure immediately so tests don't timeout in CI. Signed-off-by: Pierrick Bouvier Reviewed-by: Philippe Mathieu-Daudé Message-Id: <20250303185745.2504842-1-pierrick.bouvier@linaro.org> Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-20-alex.bennee@linaro.org> --- tests/functional/test_aarch64_rme_sbsaref.py | 3 ++- tests/functional/test_aarch64_rme_virt.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/functional/test_aarch64_rme_sbsaref.py b/tests/functional/test_aarch64_rme_sbsaref.py index 93bb528338..ddcc9493a6 100755 --- a/tests/functional/test_aarch64_rme_sbsaref.py +++ b/tests/functional/test_aarch64_rme_sbsaref.py @@ -60,7 +60,8 @@ class Aarch64RMESbsaRefMachine(QemuSystemTest): self.vm.launch() # Wait for host VM boot to complete. - wait_for_console_pattern(self, 'Welcome to Buildroot') + wait_for_console_pattern(self, 'Welcome to Buildroot', + failure_message='Synchronous Exception at') exec_command_and_wait_for_pattern(self, 'root', '#') test_realms_guest(self) diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/test_aarch64_rme_virt.py index 42b9229b4c..38e01721a4 100755 --- a/tests/functional/test_aarch64_rme_virt.py +++ b/tests/functional/test_aarch64_rme_virt.py @@ -89,7 +89,8 @@ class Aarch64RMEVirtMachine(QemuSystemTest): self.vm.launch() # Wait for host VM boot to complete. - wait_for_console_pattern(self, 'Welcome to Buildroot') + wait_for_console_pattern(self, 'Welcome to Buildroot', + failure_message='Synchronous Exception at') exec_command_and_wait_for_pattern(self, 'root', '#') test_realms_guest(self) From 9d06b0ccb1089f8713c4244109958bed8374ada4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:27 +0000 Subject: [PATCH 20/31] plugins/api: use qemu_target_page_mask() to get value MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Requiring TARGET_PAGE_MASK to be defined gets in the way of building this unit once. qemu_target_page_mask() will tell us what it is. Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-21-alex.bennee@linaro.org> --- plugins/api.c | 3 ++- tests/tcg/hexagon/Makefile.target | 2 +- tests/tcg/multiarch/Makefile.target | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/api.c b/plugins/api.c index cf8cdf076a..fa4d495277 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -43,6 +43,7 @@ #include "tcg/tcg.h" #include "exec/exec-all.h" #include "exec/gdbstub.h" +#include "exec/target_page.h" #include "exec/translation-block.h" #include "exec/translator.h" #include "disas/disas.h" @@ -287,7 +288,7 @@ uint64_t qemu_plugin_insn_vaddr(const struct qemu_plugin_insn *insn) void *qemu_plugin_insn_haddr(const struct qemu_plugin_insn *insn) { const DisasContextBase *db = tcg_ctx->plugin_db; - vaddr page0_last = db->pc_first | ~TARGET_PAGE_MASK; + vaddr page0_last = db->pc_first | ~qemu_target_page_mask(); if (db->fake_insn) { return NULL; diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target index 4dfc39bc98..e5182c01d8 100644 --- a/tests/tcg/hexagon/Makefile.target +++ b/tests/tcg/hexagon/Makefile.target @@ -18,7 +18,7 @@ # Hexagon doesn't support gdb, so skip the EXTRA_RUNS EXTRA_RUNS = -CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal -Wno-unknown-warning-option +CFLAGS += -Wno-incompatible-pointer-types -Wno-undefined-internal CFLAGS += -fno-unroll-loops -fno-stack-protector HEX_SRC=$(SRC_PATH)/tests/tcg/hexagon diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target index c769a7d69d..45c9cfe18c 100644 --- a/tests/tcg/multiarch/Makefile.target +++ b/tests/tcg/multiarch/Makefile.target @@ -51,7 +51,7 @@ sigreturn-sigmask: LDFLAGS+=-pthread # Since this is just a standard piece of library code we've borrowed for a # TCG test case, suppress the warning rather than trying to modify the # code to work around the compiler. -sha1: CFLAGS+=-Wno-stringop-overread +sha1: CFLAGS+=-Wno-stringop-overread -Wno-unknown-warning-option # The vma-pthread seems very sensitive on gitlab and we currently # don't know if its exposing a real bug or the test is flaky. From 1d9a9743589e3622a93a46b593820ffb22cbda1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:28 +0000 Subject: [PATCH 21/31] plugins/loader: populate target_name with target_name() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have a function we can call for this, lets not rely on macros that stop us building once. Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-22-alex.bennee@linaro.org> --- plugins/loader.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/loader.c b/plugins/loader.c index 99686b5466..827473c8b6 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -297,7 +297,7 @@ int qemu_plugin_load_list(QemuPluginList *head, Error **errp) struct qemu_plugin_desc *desc, *next; g_autofree qemu_info_t *info = g_new0(qemu_info_t, 1); - info->target_name = TARGET_NAME; + info->target_name = target_name(); info->version.min = QEMU_PLUGIN_MIN_VERSION; info->version.cur = QEMU_PLUGIN_VERSION; #ifndef CONFIG_USER_ONLY From 4752ed52727acf7f0e798de75ec024fc92e92af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:29 +0000 Subject: [PATCH 22/31] include/qemu: plugin-memory.h doesn't need cpu-defs.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hwaddr is a fixed size on all builds. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-23-alex.bennee@linaro.org> --- include/qemu/plugin-memory.h | 1 - 1 file changed, 1 deletion(-) diff --git a/include/qemu/plugin-memory.h b/include/qemu/plugin-memory.h index 71c1123308..6065ec7aaf 100644 --- a/include/qemu/plugin-memory.h +++ b/include/qemu/plugin-memory.h @@ -9,7 +9,6 @@ #ifndef PLUGIN_MEMORY_H #define PLUGIN_MEMORY_H -#include "exec/cpu-defs.h" #include "exec/hwaddr.h" struct qemu_plugin_hwaddr { From f85a28dedfde2d530b3fb6cf3dc12e4b67e02909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:30 +0000 Subject: [PATCH 23/31] plugins/api: clean-up the includes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to re-factoring and clean-up work (especially to exec-all) we no longer need such broad headers for the api. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-24-alex.bennee@linaro.org> --- plugins/api.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/api.c b/plugins/api.c index fa4d495277..c3ba1e98e8 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -39,9 +39,7 @@ #include "qemu/main-loop.h" #include "qemu/plugin.h" #include "qemu/log.h" -#include "qemu/timer.h" #include "tcg/tcg.h" -#include "exec/exec-all.h" #include "exec/gdbstub.h" #include "exec/target_page.h" #include "exec/translation-block.h" @@ -51,7 +49,6 @@ #ifndef CONFIG_USER_ONLY #include "qapi/error.h" #include "migration/blocker.h" -#include "exec/ram_addr.h" #include "qemu/plugin-memory.h" #include "hw/boards.h" #else From 5dd09b8157a132468547ad8a392ec9f8d836c169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:31 +0000 Subject: [PATCH 24/31] plugins/plugin.h: include queue.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Headers should bring in what they need so don't rely on getting queue.h by side effects. This will help with clean-ups in the following patches. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-25-alex.bennee@linaro.org> --- plugins/plugin.h | 1 + 1 file changed, 1 insertion(+) diff --git a/plugins/plugin.h b/plugins/plugin.h index 30e2299a54..9ed20b5c41 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -13,6 +13,7 @@ #define PLUGIN_H #include +#include "qemu/queue.h" #include "qemu/qht.h" #define QEMU_PLUGIN_MIN_VERSION 2 From 8c15f6e435a15e90456d26ff26199861369c9d63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:32 +0000 Subject: [PATCH 25/31] plugins/loader: compile loader only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There is very little in loader that is different between builds save for a tiny user/system mode difference in the plugin_info structure. Create two new files, user and system to hold mode specific helpers and move loader into common_ss. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-26-alex.bennee@linaro.org> --- plugins/loader.c | 13 ++----------- plugins/meson.build | 7 ++++++- plugins/plugin.h | 6 ++++++ plugins/system.c | 24 ++++++++++++++++++++++++ plugins/user.c | 19 +++++++++++++++++++ 5 files changed, 57 insertions(+), 12 deletions(-) create mode 100644 plugins/system.c create mode 100644 plugins/user.c diff --git a/plugins/loader.c b/plugins/loader.c index 827473c8b6..7523d554f0 100644 --- a/plugins/loader.c +++ b/plugins/loader.c @@ -31,9 +31,6 @@ #include "qemu/memalign.h" #include "hw/core/cpu.h" #include "exec/tb-flush.h" -#ifndef CONFIG_USER_ONLY -#include "hw/boards.h" -#endif #include "plugin.h" @@ -300,14 +297,8 @@ int qemu_plugin_load_list(QemuPluginList *head, Error **errp) info->target_name = target_name(); info->version.min = QEMU_PLUGIN_MIN_VERSION; info->version.cur = QEMU_PLUGIN_VERSION; -#ifndef CONFIG_USER_ONLY - MachineState *ms = MACHINE(qdev_get_machine()); - info->system_emulation = true; - info->system.smp_vcpus = ms->smp.cpus; - info->system.max_vcpus = ms->smp.max_cpus; -#else - info->system_emulation = false; -#endif + + qemu_plugin_fillin_mode_info(info); QTAILQ_FOREACH_SAFE(desc, head, entry, next) { int err; diff --git a/plugins/meson.build b/plugins/meson.build index d60be2a4d6..f7820806d3 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -57,8 +57,13 @@ if host_os == 'windows' command: dlltool_cmd ) endif + +user_ss.add(files('user.c')) +system_ss.add(files('system.c')) + +common_ss.add(files('loader.c')) + specific_ss.add(files( - 'loader.c', 'core.c', 'api.c', )) diff --git a/plugins/plugin.h b/plugins/plugin.h index 9ed20b5c41..6fbc443b96 100644 --- a/plugins/plugin.h +++ b/plugins/plugin.h @@ -119,4 +119,10 @@ struct qemu_plugin_scoreboard *plugin_scoreboard_new(size_t element_size); void plugin_scoreboard_free(struct qemu_plugin_scoreboard *score); +/** + * qemu_plugin_fillin_mode_info() - populate mode specific info + * info: pointer to qemu_info_t structure + */ +void qemu_plugin_fillin_mode_info(qemu_info_t *info); + #endif /* PLUGIN_H */ diff --git a/plugins/system.c b/plugins/system.c new file mode 100644 index 0000000000..b3ecc33ba5 --- /dev/null +++ b/plugins/system.c @@ -0,0 +1,24 @@ +/* + * QEMU Plugin system-emulation helpers + * + * Helpers that are specific to system emulation. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/plugin.h" +#include "hw/boards.h" + +#include "plugin.h" + +void qemu_plugin_fillin_mode_info(qemu_info_t *info) +{ + MachineState *ms = MACHINE(qdev_get_machine()); + info->system_emulation = true; + info->system.smp_vcpus = ms->smp.cpus; + info->system.max_vcpus = ms->smp.max_cpus; +} diff --git a/plugins/user.c b/plugins/user.c new file mode 100644 index 0000000000..250d542502 --- /dev/null +++ b/plugins/user.c @@ -0,0 +1,19 @@ +/* + * QEMU Plugin user-mode helpers + * + * Helpers that are specific to user-mode. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/plugin.h" +#include "plugin.h" + +void qemu_plugin_fillin_mode_info(qemu_info_t *info) +{ + info->system_emulation = false; +} From 903e870f2453731f9b44ce9734cfcb5509304677 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:33 +0000 Subject: [PATCH 26/31] plugins/api: split out binary path/start/end/entry code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To move the main api.c to a single build compilation object we need to start splitting out user and system specific code. As we need to grob around host headers we move these particular helpers into the *-user mode directories. The binary/start/end/entry helpers are all NOPs for system mode. While using the plugin-api.c.inc trick means we build for both linux-user and bsd-user the BSD user-mode command line is still missing -plugin. This can be enabled once we have reliable check-tcg tests working for the BSDs. Reviewed-by: Richard Henderson Reviewed-by: Warner Losh Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-27-alex.bennee@linaro.org> --- bsd-user/meson.build | 1 + bsd-user/plugin-api.c | 15 +++++++++++++ common-user/plugin-api.c.inc | 43 ++++++++++++++++++++++++++++++++++++ linux-user/meson.build | 1 + linux-user/plugin-api.c | 15 +++++++++++++ plugins/api-system.c | 39 ++++++++++++++++++++++++++++++++ plugins/api.c | 43 ------------------------------------ plugins/meson.build | 2 +- 8 files changed, 115 insertions(+), 44 deletions(-) create mode 100644 bsd-user/plugin-api.c create mode 100644 common-user/plugin-api.c.inc create mode 100644 linux-user/plugin-api.c create mode 100644 plugins/api-system.c diff --git a/bsd-user/meson.build b/bsd-user/meson.build index 39bad0ae33..37b7cd6de8 100644 --- a/bsd-user/meson.build +++ b/bsd-user/meson.build @@ -13,6 +13,7 @@ bsd_user_ss.add(files( 'elfload.c', 'main.c', 'mmap.c', + 'plugin-api.c', 'signal.c', 'strace.c', 'uaccess.c', diff --git a/bsd-user/plugin-api.c b/bsd-user/plugin-api.c new file mode 100644 index 0000000000..6ccef7eaa0 --- /dev/null +++ b/bsd-user/plugin-api.c @@ -0,0 +1,15 @@ +/* + * QEMU Plugin API - bsd-user-mode only implementations + * + * Common user-mode only APIs are in plugins/api-user. These helpers + * are only specific to bsd-user. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "common-user/plugin-api.c.inc" diff --git a/common-user/plugin-api.c.inc b/common-user/plugin-api.c.inc new file mode 100644 index 0000000000..5b8a1396b6 --- /dev/null +++ b/common-user/plugin-api.c.inc @@ -0,0 +1,43 @@ +/* + * QEMU Plugin API - *-user-mode only implementations + * + * Common user-mode only APIs are in plugins/api-user. These helpers + * are only specific to the *-user frontends. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "qemu/plugin.h" +#include "qemu.h" + +/* + * Binary path, start and end locations. Host specific due to TaskState. + */ +const char *qemu_plugin_path_to_binary(void) +{ + TaskState *ts = get_task_state(current_cpu); + return g_strdup(ts->bprm->filename); +} + +uint64_t qemu_plugin_start_code(void) +{ + TaskState *ts = get_task_state(current_cpu); + return ts->info->start_code; +} + +uint64_t qemu_plugin_end_code(void) +{ + TaskState *ts = get_task_state(current_cpu); + return ts->info->end_code; +} + +uint64_t qemu_plugin_entry_code(void) +{ + TaskState *ts = get_task_state(current_cpu); + return ts->info->entry; +} diff --git a/linux-user/meson.build b/linux-user/meson.build index f75b4fe0e3..f47a213ca3 100644 --- a/linux-user/meson.build +++ b/linux-user/meson.build @@ -27,6 +27,7 @@ linux_user_ss.add(libdw) linux_user_ss.add(when: 'TARGET_HAS_BFLT', if_true: files('flatload.c')) linux_user_ss.add(when: 'TARGET_I386', if_true: files('vm86.c')) linux_user_ss.add(when: 'CONFIG_ARM_COMPATIBLE_SEMIHOSTING', if_true: files('semihost.c')) +linux_user_ss.add(when: 'CONFIG_TCG_PLUGINS', if_true: files('plugin-api.c')) syscall_nr_generators = {} diff --git a/linux-user/plugin-api.c b/linux-user/plugin-api.c new file mode 100644 index 0000000000..66755df526 --- /dev/null +++ b/linux-user/plugin-api.c @@ -0,0 +1,15 @@ +/* + * QEMU Plugin API - linux-user-mode only implementations + * + * Common user-mode only APIs are in plugins/api-user. These helpers + * are only specific to linux-user. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu.h" +#include "common-user/plugin-api.c.inc" diff --git a/plugins/api-system.c b/plugins/api-system.c new file mode 100644 index 0000000000..cb0dd8f730 --- /dev/null +++ b/plugins/api-system.c @@ -0,0 +1,39 @@ +/* + * QEMU Plugin API - System specific implementations + * + * This provides the APIs that have a specific system implementation + * or are only relevant to system-mode. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/main-loop.h" +#include "qemu/plugin.h" + +/* + * In system mode we cannot trace the binary being executed so the + * helpers all return NULL/0. + */ +const char *qemu_plugin_path_to_binary(void) +{ + return NULL; +} + +uint64_t qemu_plugin_start_code(void) +{ + return 0; +} + +uint64_t qemu_plugin_end_code(void) +{ + return 0; +} + +uint64_t qemu_plugin_entry_code(void) +{ + return 0; +} diff --git a/plugins/api.c b/plugins/api.c index c3ba1e98e8..ffccd71e4b 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -471,49 +471,6 @@ bool qemu_plugin_bool_parse(const char *name, const char *value, bool *ret) return name && value && qapi_bool_parse(name, value, ret, NULL); } -/* - * Binary path, start and end locations - */ -const char *qemu_plugin_path_to_binary(void) -{ - char *path = NULL; -#ifdef CONFIG_USER_ONLY - TaskState *ts = get_task_state(current_cpu); - path = g_strdup(ts->bprm->filename); -#endif - return path; -} - -uint64_t qemu_plugin_start_code(void) -{ - uint64_t start = 0; -#ifdef CONFIG_USER_ONLY - TaskState *ts = get_task_state(current_cpu); - start = ts->info->start_code; -#endif - return start; -} - -uint64_t qemu_plugin_end_code(void) -{ - uint64_t end = 0; -#ifdef CONFIG_USER_ONLY - TaskState *ts = get_task_state(current_cpu); - end = ts->info->end_code; -#endif - return end; -} - -uint64_t qemu_plugin_entry_code(void) -{ - uint64_t entry = 0; -#ifdef CONFIG_USER_ONLY - TaskState *ts = get_task_state(current_cpu); - entry = ts->info->entry; -#endif - return entry; -} - /* * Create register handles. * diff --git a/plugins/meson.build b/plugins/meson.build index f7820806d3..9c9bc9e5bb 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -59,7 +59,7 @@ if host_os == 'windows' endif user_ss.add(files('user.c')) -system_ss.add(files('system.c')) +system_ss.add(files('system.c', 'api-system.c')) common_ss.add(files('loader.c')) From 455a2d265cf6c3947243d772b9e5d1b8dd13a9bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:34 +0000 Subject: [PATCH 27/31] plugins/api: split out the vaddr/hwaddr helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These only work for system-mode and are NOPs for user-mode. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-28-alex.bennee@linaro.org> --- plugins/api-system.c | 58 ++++++++++++++++++++++++++++++++++++ plugins/api-user.c | 40 +++++++++++++++++++++++++ plugins/api.c | 70 -------------------------------------------- plugins/meson.build | 2 +- 4 files changed, 99 insertions(+), 71 deletions(-) create mode 100644 plugins/api-user.c diff --git a/plugins/api-system.c b/plugins/api-system.c index cb0dd8f730..38560de342 100644 --- a/plugins/api-system.c +++ b/plugins/api-system.c @@ -12,6 +12,10 @@ #include "qemu/osdep.h" #include "qemu/main-loop.h" +#include "qapi/error.h" +#include "migration/blocker.h" +#include "hw/boards.h" +#include "qemu/plugin-memory.h" #include "qemu/plugin.h" /* @@ -37,3 +41,57 @@ uint64_t qemu_plugin_entry_code(void) { return 0; } + +/* + * Virtual Memory queries + */ + +static __thread struct qemu_plugin_hwaddr hwaddr_info; + +struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, + uint64_t vaddr) +{ + CPUState *cpu = current_cpu; + unsigned int mmu_idx = get_mmuidx(info); + enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); + hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0; + + assert(mmu_idx < NB_MMU_MODES); + + if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx, + hwaddr_info.is_store, &hwaddr_info)) { + error_report("invalid use of qemu_plugin_get_hwaddr"); + return NULL; + } + + return &hwaddr_info; +} + +bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr) +{ + return haddr->is_io; +} + +uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr) +{ + if (haddr) { + return haddr->phys_addr; + } + return 0; +} + +const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) +{ + if (h && h->is_io) { + MemoryRegion *mr = h->mr; + if (!mr->name) { + unsigned maddr = (uintptr_t)mr; + g_autofree char *temp = g_strdup_printf("anon%08x", maddr); + return g_intern_string(temp); + } else { + return g_intern_string(mr->name); + } + } else { + return g_intern_static_string("RAM"); + } +} diff --git a/plugins/api-user.c b/plugins/api-user.c new file mode 100644 index 0000000000..867b420339 --- /dev/null +++ b/plugins/api-user.c @@ -0,0 +1,40 @@ +/* + * QEMU Plugin API - user-mode only implementations + * + * This provides the APIs that have a user-mode specific + * implementations or are only relevant to user-mode. + * + * Copyright (C) 2017, Emilio G. Cota + * Copyright (C) 2019-2025, Linaro + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/plugin.h" + +/* + * Virtual Memory queries - these are all NOPs for user-mode which + * only ever has visibility of virtual addresses. + */ + +struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, + uint64_t vaddr) +{ + return NULL; +} + +bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr) +{ + return false; +} + +uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr) +{ + return 0; +} + +const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) +{ + return g_intern_static_string("Invalid"); +} diff --git a/plugins/api.c b/plugins/api.c index ffccd71e4b..82241699a5 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -383,76 +383,6 @@ qemu_plugin_mem_value qemu_plugin_mem_get_value(qemu_plugin_meminfo_t info) return value; } -/* - * Virtual Memory queries - */ - -#ifdef CONFIG_SOFTMMU -static __thread struct qemu_plugin_hwaddr hwaddr_info; -#endif - -struct qemu_plugin_hwaddr *qemu_plugin_get_hwaddr(qemu_plugin_meminfo_t info, - uint64_t vaddr) -{ -#ifdef CONFIG_SOFTMMU - CPUState *cpu = current_cpu; - unsigned int mmu_idx = get_mmuidx(info); - enum qemu_plugin_mem_rw rw = get_plugin_meminfo_rw(info); - hwaddr_info.is_store = (rw & QEMU_PLUGIN_MEM_W) != 0; - - assert(mmu_idx < NB_MMU_MODES); - - if (!tlb_plugin_lookup(cpu, vaddr, mmu_idx, - hwaddr_info.is_store, &hwaddr_info)) { - error_report("invalid use of qemu_plugin_get_hwaddr"); - return NULL; - } - - return &hwaddr_info; -#else - return NULL; -#endif -} - -bool qemu_plugin_hwaddr_is_io(const struct qemu_plugin_hwaddr *haddr) -{ -#ifdef CONFIG_SOFTMMU - return haddr->is_io; -#else - return false; -#endif -} - -uint64_t qemu_plugin_hwaddr_phys_addr(const struct qemu_plugin_hwaddr *haddr) -{ -#ifdef CONFIG_SOFTMMU - if (haddr) { - return haddr->phys_addr; - } -#endif - return 0; -} - -const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) -{ -#ifdef CONFIG_SOFTMMU - if (h && h->is_io) { - MemoryRegion *mr = h->mr; - if (!mr->name) { - unsigned maddr = (uintptr_t)mr; - g_autofree char *temp = g_strdup_printf("anon%08x", maddr); - return g_intern_string(temp); - } else { - return g_intern_string(mr->name); - } - } else { - return g_intern_static_string("RAM"); - } -#else - return g_intern_static_string("Invalid"); -#endif -} - int qemu_plugin_num_vcpus(void) { return plugin_num_vcpus(); diff --git a/plugins/meson.build b/plugins/meson.build index 9c9bc9e5bb..942b59e904 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -58,7 +58,7 @@ if host_os == 'windows' ) endif -user_ss.add(files('user.c')) +user_ss.add(files('user.c', 'api-user.c')) system_ss.add(files('system.c', 'api-system.c')) common_ss.add(files('loader.c')) From 1d3e745f7ada921d544f29fbf84c6f0f63025e61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:35 +0000 Subject: [PATCH 28/31] plugins/api: split out time control helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These are only usable in system mode where we control the timer. For user-mode make them NOPs. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-29-alex.bennee@linaro.org> --- plugins/api-system.c | 34 ++++++++++++++++++++++++++++++++++ plugins/api-user.c | 17 +++++++++++++++++ plugins/api.c | 41 ----------------------------------------- 3 files changed, 51 insertions(+), 41 deletions(-) diff --git a/plugins/api-system.c b/plugins/api-system.c index 38560de342..cc190b167e 100644 --- a/plugins/api-system.c +++ b/plugins/api-system.c @@ -95,3 +95,37 @@ const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) return g_intern_static_string("RAM"); } } + +/* + * Time control + */ +static bool has_control; +static Error *migration_blocker; + +const void *qemu_plugin_request_time_control(void) +{ + if (!has_control) { + has_control = true; + error_setg(&migration_blocker, + "TCG plugin time control does not support migration"); + migrate_add_blocker(&migration_blocker, NULL); + return &has_control; + } + return NULL; +} + +static void advance_virtual_time__async(CPUState *cpu, run_on_cpu_data data) +{ + int64_t new_time = data.host_ulong; + qemu_clock_advance_virtual_time(new_time); +} + +void qemu_plugin_update_ns(const void *handle, int64_t new_time) +{ + if (handle == &has_control) { + /* Need to execute out of cpu_exec, so bql can be locked. */ + async_run_on_cpu(current_cpu, + advance_virtual_time__async, + RUN_ON_CPU_HOST_ULONG(new_time)); + } +} diff --git a/plugins/api-user.c b/plugins/api-user.c index 867b420339..28704a89e8 100644 --- a/plugins/api-user.c +++ b/plugins/api-user.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "qemu/plugin.h" +#include "exec/log.h" /* * Virtual Memory queries - these are all NOPs for user-mode which @@ -38,3 +39,19 @@ const char *qemu_plugin_hwaddr_device_name(const struct qemu_plugin_hwaddr *h) { return g_intern_static_string("Invalid"); } + +/* + * Time control - for user mode the only real time is wall clock time + * so realistically all you can do in user mode is slow down execution + * which doesn't require the ability to mess with the clock. + */ + +const void *qemu_plugin_request_time_control(void) +{ + return NULL; +} + +void qemu_plugin_update_ns(const void *handle, int64_t new_time) +{ + qemu_log_mask(LOG_UNIMP, "user-mode can't control time"); +} diff --git a/plugins/api.c b/plugins/api.c index 82241699a5..832bf6ee5e 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -526,44 +526,3 @@ uint64_t qemu_plugin_u64_sum(qemu_plugin_u64 entry) return total; } -/* - * Time control - */ -static bool has_control; -#ifdef CONFIG_SOFTMMU -static Error *migration_blocker; -#endif - -const void *qemu_plugin_request_time_control(void) -{ - if (!has_control) { - has_control = true; -#ifdef CONFIG_SOFTMMU - error_setg(&migration_blocker, - "TCG plugin time control does not support migration"); - migrate_add_blocker(&migration_blocker, NULL); -#endif - return &has_control; - } - return NULL; -} - -#ifdef CONFIG_SOFTMMU -static void advance_virtual_time__async(CPUState *cpu, run_on_cpu_data data) -{ - int64_t new_time = data.host_ulong; - qemu_clock_advance_virtual_time(new_time); -} -#endif - -void qemu_plugin_update_ns(const void *handle, int64_t new_time) -{ -#ifdef CONFIG_SOFTMMU - if (handle == &has_control) { - /* Need to execute out of cpu_exec, so bql can be locked. */ - async_run_on_cpu(current_cpu, - advance_virtual_time__async, - RUN_ON_CPU_HOST_ULONG(new_time)); - } -#endif -} From 40988ed9dfca934791bd2aeb1cc2d11e3a239265 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:36 +0000 Subject: [PATCH 29/31] plugins/api: build only once MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now all the softmmu/user-mode stuff has been split out we can build this compilation unit only once. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-30-alex.bennee@linaro.org> --- plugins/api.c | 11 ----------- plugins/meson.build | 3 +-- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/plugins/api.c b/plugins/api.c index 832bf6ee5e..604ce06802 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -46,17 +46,6 @@ #include "exec/translator.h" #include "disas/disas.h" #include "plugin.h" -#ifndef CONFIG_USER_ONLY -#include "qapi/error.h" -#include "migration/blocker.h" -#include "qemu/plugin-memory.h" -#include "hw/boards.h" -#else -#include "qemu.h" -#ifdef CONFIG_LINUX -#include "loader.h" -#endif -#endif /* Uninstall and Reset handlers */ diff --git a/plugins/meson.build b/plugins/meson.build index 942b59e904..d27220d5ff 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -61,9 +61,8 @@ endif user_ss.add(files('user.c', 'api-user.c')) system_ss.add(files('system.c', 'api-system.c')) -common_ss.add(files('loader.c')) +common_ss.add(files('loader.c', 'api.c')) specific_ss.add(files( 'core.c', - 'api.c', )) From 606ad7fe17a0baee43a29d71469fee246a09a7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:37 +0000 Subject: [PATCH 30/31] plugins/core: make a single build unit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trim through the includes and remove everything not needed for the core. Only include tcg-op-common.h to remove the need to TARGET_LONG_BITS and move the build unit into the common set. Reviewed-by: Richard Henderson Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-31-alex.bennee@linaro.org> --- plugins/core.c | 10 +--------- plugins/meson.build | 5 +---- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/plugins/core.c b/plugins/core.c index bb105e8e68..eb9281fe54 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -12,22 +12,14 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ #include "qemu/osdep.h" -#include "qemu/error-report.h" -#include "qemu/config-file.h" -#include "qapi/error.h" #include "qemu/lockable.h" #include "qemu/option.h" #include "qemu/plugin.h" #include "qemu/queue.h" #include "qemu/rcu_queue.h" -#include "qemu/xxhash.h" #include "qemu/rcu.h" -#include "hw/core/cpu.h" - -#include "exec/exec-all.h" #include "exec/tb-flush.h" -#include "tcg/tcg.h" -#include "tcg/tcg-op.h" +#include "tcg/tcg-op-common.h" #include "plugin.h" struct qemu_plugin_cb { diff --git a/plugins/meson.build b/plugins/meson.build index d27220d5ff..3be8245a69 100644 --- a/plugins/meson.build +++ b/plugins/meson.build @@ -61,8 +61,5 @@ endif user_ss.add(files('user.c', 'api-user.c')) system_ss.add(files('system.c', 'api-system.c')) -common_ss.add(files('loader.c', 'api.c')) +common_ss.add(files('loader.c', 'api.c', 'core.c')) -specific_ss.add(files( - 'core.c', -)) From 0d3dea7d7a49c22897e7435e8e09d9f587bc56c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20Benn=C3=A9e?= Date: Tue, 4 Mar 2025 22:24:38 +0000 Subject: [PATCH 31/31] MAINTAINERS: remove widely sanctioned entities MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The following organisations appear on the US sanctions list: Yadro: https://sanctionssearch.ofac.treas.gov/Details.aspx?id=41125 ISPRAS: https://sanctionssearch.ofac.treas.gov/Details.aspx?id=50890 As a result maintainers interacting with such entities would face legal risk in a number of jurisdictions. To reduce the risk of inadvertent non-compliance remove entries from these organisations from the MAINTAINERS file. Mark the pcf8574 system as orphaned until someone volunteers to step up as a maintainer. Add myself as a second reviewer to record/replay so I can help with what odd fixes I can. Reviewed-by: Markus Armbruster Reviewed-by: Daniel P. Berrangé Acked-by: Paolo Bonzini Signed-off-by: Alex Bennée Message-Id: <20250304222439.2035603-32-alex.bennee@linaro.org> --- MAINTAINERS | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 758cc461be..0e5db7a574 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2547,8 +2547,7 @@ F: hw/i2c/i2c_mux_pca954x.c F: include/hw/i2c/i2c_mux_pca954x.h pcf8574 -M: Dmitrii Sharikhin -S: Maintained +S: Orphaned F: hw/gpio/pcf8574.c F: include/gpio/pcf8574.h @@ -3660,10 +3659,10 @@ F: net/filter-mirror.c F: tests/qtest/test-filter* Record/replay -M: Pavel Dovgalyuk R: Paolo Bonzini +R: Alex Bennée W: https://wiki.qemu.org/Features/record-replay -S: Supported +S: Odd Fixes F: replay/* F: block/blkreplay.c F: net/filter-replay.c