summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.gitlab-ci.d/windows.yml2
-rw-r--r--MAINTAINERS203
-rw-r--r--hw/arm/virt.c9
-rw-r--r--hw/core/machine.c3
-rw-r--r--hw/i386/pc.c3
-rw-r--r--hw/i386/pc_piix.c13
-rw-r--r--hw/i386/pc_q35.c13
-rw-r--r--hw/m68k/virt.c9
-rw-r--r--hw/ppc/spapr.c15
-rw-r--r--hw/s390x/s390-virtio-ccw.c14
-rw-r--r--include/hw/boards.h3
-rw-r--r--include/hw/i386/pc.h3
-rw-r--r--tests/functional/aarch64/meson.build48
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700.py (renamed from tests/functional/test_aarch64_aspeed_ast2700.py)0
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700fc.py (renamed from tests/functional/test_aarch64_aspeed_ast2700fc.py)0
-rwxr-xr-xtests/functional/aarch64/test_device_passthrough.py (renamed from tests/functional/test_aarch64_device_passthrough.py)0
-rwxr-xr-xtests/functional/aarch64/test_hotplug_pci.py (renamed from tests/functional/test_aarch64_hotplug_pci.py)0
-rwxr-xr-xtests/functional/aarch64/test_imx8mp_evk.py (renamed from tests/functional/test_aarch64_imx8mp_evk.py)0
-rwxr-xr-xtests/functional/aarch64/test_kvm.py (renamed from tests/functional/test_aarch64_kvm.py)0
-rwxr-xr-xtests/functional/aarch64/test_migration.py26
-rwxr-xr-xtests/functional/aarch64/test_multiprocess.py31
-rwxr-xr-xtests/functional/aarch64/test_raspi3.py (renamed from tests/functional/test_aarch64_raspi3.py)0
-rwxr-xr-xtests/functional/aarch64/test_raspi4.py (renamed from tests/functional/test_aarch64_raspi4.py)0
-rwxr-xr-xtests/functional/aarch64/test_replay.py (renamed from tests/functional/test_aarch64_replay.py)0
-rwxr-xr-xtests/functional/aarch64/test_reverse_debug.py (renamed from tests/functional/test_aarch64_reverse_debug.py)4
-rwxr-xr-xtests/functional/aarch64/test_rme_sbsaref.py (renamed from tests/functional/test_aarch64_rme_sbsaref.py)2
-rwxr-xr-xtests/functional/aarch64/test_rme_virt.py (renamed from tests/functional/test_aarch64_rme_virt.py)0
-rwxr-xr-xtests/functional/aarch64/test_sbsaref.py (renamed from tests/functional/test_aarch64_sbsaref.py)0
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_alpine.py (renamed from tests/functional/test_aarch64_sbsaref_alpine.py)2
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_freebsd.py (renamed from tests/functional/test_aarch64_sbsaref_freebsd.py)2
-rwxr-xr-xtests/functional/aarch64/test_smmu.py (renamed from tests/functional/test_aarch64_smmu.py)0
-rwxr-xr-xtests/functional/aarch64/test_tcg_plugins.py (renamed from tests/functional/test_aarch64_tcg_plugins.py)0
-rwxr-xr-xtests/functional/aarch64/test_tuxrun.py (renamed from tests/functional/test_aarch64_tuxrun.py)0
-rwxr-xr-xtests/functional/aarch64/test_virt.py (renamed from tests/functional/test_aarch64_virt.py)0
-rwxr-xr-xtests/functional/aarch64/test_virt_gpu.py (renamed from tests/functional/test_aarch64_virt_gpu.py)2
-rwxr-xr-xtests/functional/aarch64/test_xen.py (renamed from tests/functional/test_aarch64_xen.py)0
-rwxr-xr-xtests/functional/aarch64/test_xlnx_versal.py (renamed from tests/functional/test_aarch64_xlnx_versal.py)0
-rw-r--r--tests/functional/alpha/meson.build10
-rwxr-xr-xtests/functional/alpha/test_clipper.py (renamed from tests/functional/test_alpha_clipper.py)0
-rwxr-xr-xtests/functional/alpha/test_migration.py26
-rwxr-xr-xtests/functional/alpha/test_replay.py (renamed from tests/functional/test_alpha_replay.py)0
-rw-r--r--tests/functional/arm/meson.build62
-rwxr-xr-xtests/functional/arm/test_aspeed_ast1030.py (renamed from tests/functional/test_arm_aspeed_ast1030.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2500.py (renamed from tests/functional/test_arm_aspeed_ast2500.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2600.py (renamed from tests/functional/test_arm_aspeed_ast2600.py)0
-rwxr-xr-x[-rw-r--r--]tests/functional/arm/test_aspeed_bletchley.py (renamed from tests/functional/test_arm_aspeed_bletchley.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_catalina.py (renamed from tests/functional/test_arm_aspeed_catalina.py)0
-rwxr-xr-x[-rw-r--r--]tests/functional/arm/test_aspeed_gb200nvl_bmc.py (renamed from tests/functional/test_arm_aspeed_gb200nvl_bmc.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_palmetto.py (renamed from tests/functional/test_arm_aspeed_palmetto.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_rainier.py (renamed from tests/functional/test_arm_aspeed_rainier.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_romulus.py (renamed from tests/functional/test_arm_aspeed_romulus.py)0
-rwxr-xr-x[-rw-r--r--]tests/functional/arm/test_aspeed_witherspoon.py (renamed from tests/functional/test_arm_aspeed_witherspoon.py)0
-rwxr-xr-xtests/functional/arm/test_bflt.py (renamed from tests/functional/test_arm_bflt.py)0
-rwxr-xr-xtests/functional/arm/test_bpim2u.py (renamed from tests/functional/test_arm_bpim2u.py)0
-rwxr-xr-xtests/functional/arm/test_canona1100.py (renamed from tests/functional/test_arm_canona1100.py)0
-rwxr-xr-xtests/functional/arm/test_collie.py (renamed from tests/functional/test_arm_collie.py)0
-rwxr-xr-xtests/functional/arm/test_cubieboard.py (renamed from tests/functional/test_arm_cubieboard.py)0
-rwxr-xr-xtests/functional/arm/test_emcraft_sf2.py (renamed from tests/functional/test_arm_emcraft_sf2.py)0
-rwxr-xr-xtests/functional/arm/test_integratorcp.py (renamed from tests/functional/test_arm_integratorcp.py)0
-rwxr-xr-xtests/functional/arm/test_max78000fthr.py (renamed from tests/functional/test_arm_max78000fthr.py)0
-rwxr-xr-xtests/functional/arm/test_microbit.py (renamed from tests/functional/test_arm_microbit.py)0
-rwxr-xr-xtests/functional/arm/test_migration.py26
-rwxr-xr-xtests/functional/arm/test_orangepi.py (renamed from tests/functional/test_arm_orangepi.py)0
-rwxr-xr-xtests/functional/arm/test_quanta_gsj.py (renamed from tests/functional/test_arm_quanta_gsj.py)0
-rwxr-xr-xtests/functional/arm/test_raspi2.py (renamed from tests/functional/test_arm_raspi2.py)0
-rwxr-xr-xtests/functional/arm/test_realview.py (renamed from tests/functional/test_arm_realview.py)0
-rwxr-xr-xtests/functional/arm/test_replay.py (renamed from tests/functional/test_arm_replay.py)0
-rwxr-xr-xtests/functional/arm/test_smdkc210.py (renamed from tests/functional/test_arm_smdkc210.py)0
-rwxr-xr-xtests/functional/arm/test_stellaris.py (renamed from tests/functional/test_arm_stellaris.py)0
-rwxr-xr-xtests/functional/arm/test_sx1.py (renamed from tests/functional/test_arm_sx1.py)0
-rwxr-xr-xtests/functional/arm/test_tuxrun.py (renamed from tests/functional/test_arm_tuxrun.py)0
-rwxr-xr-xtests/functional/arm/test_vexpress.py (renamed from tests/functional/test_arm_vexpress.py)0
-rwxr-xr-xtests/functional/arm/test_virt.py (renamed from tests/functional/test_arm_virt.py)0
-rw-r--r--tests/functional/avr/meson.build6
-rwxr-xr-xtests/functional/avr/test_mega2560.py (renamed from tests/functional/test_avr_mega2560.py)0
-rwxr-xr-xtests/functional/avr/test_uno.py (renamed from tests/functional/test_avr_uno.py)0
-rw-r--r--tests/functional/generic/meson.build14
-rwxr-xr-xtests/functional/generic/test_empty_cpu_model.py (renamed from tests/functional/test_empty_cpu_model.py)0
-rwxr-xr-xtests/functional/generic/test_info_usernet.py (renamed from tests/functional/test_info_usernet.py)0
-rwxr-xr-xtests/functional/generic/test_version.py (renamed from tests/functional/test_version.py)0
-rwxr-xr-xtests/functional/generic/test_vnc.py (renamed from tests/functional/test_vnc.py)0
-rw-r--r--tests/functional/hppa/meson.build5
-rwxr-xr-xtests/functional/hppa/test_seabios.py (renamed from tests/functional/test_hppa_seabios.py)0
-rw-r--r--tests/functional/i386/meson.build10
-rwxr-xr-xtests/functional/i386/test_migration.py26
-rwxr-xr-xtests/functional/i386/test_replay.py (renamed from tests/functional/test_i386_replay.py)0
-rwxr-xr-xtests/functional/i386/test_tuxrun.py (renamed from tests/functional/test_i386_tuxrun.py)0
-rw-r--r--tests/functional/loongarch64/meson.build5
-rwxr-xr-xtests/functional/loongarch64/test_virt.py (renamed from tests/functional/test_loongarch64_virt.py)0
-rw-r--r--tests/functional/m68k/meson.build9
-rwxr-xr-xtests/functional/m68k/test_mcf5208evb.py (renamed from tests/functional/test_m68k_mcf5208evb.py)0
-rwxr-xr-xtests/functional/m68k/test_nextcube.py (renamed from tests/functional/test_m68k_nextcube.py)0
-rwxr-xr-xtests/functional/m68k/test_q800.py (renamed from tests/functional/test_m68k_q800.py)0
-rwxr-xr-xtests/functional/m68k/test_replay.py (renamed from tests/functional/test_m68k_replay.py)0
-rwxr-xr-xtests/functional/m68k/test_tuxrun.py (renamed from tests/functional/test_m68k_tuxrun.py)0
-rw-r--r--tests/functional/meson.build382
-rw-r--r--tests/functional/microblaze/meson.build6
-rwxr-xr-xtests/functional/microblaze/test_replay.py (renamed from tests/functional/test_microblaze_replay.py)0
-rwxr-xr-xtests/functional/microblaze/test_s3adsp1800.py (renamed from tests/functional/test_microblaze_s3adsp1800.py)0
-rw-r--r--tests/functional/microblazeel/meson.build5
-rwxr-xr-xtests/functional/microblazeel/test_s3adsp1800.py (renamed from tests/functional/test_microblazeel_s3adsp1800.py)2
-rw-r--r--[-rwxr-xr-x]tests/functional/migration.py (renamed from tests/functional/test_migration.py)35
-rw-r--r--tests/functional/mips/meson.build11
-rwxr-xr-xtests/functional/mips/test_malta.py (renamed from tests/functional/test_mips_malta.py)0
-rwxr-xr-xtests/functional/mips/test_replay.py (renamed from tests/functional/test_mips_replay.py)0
-rwxr-xr-xtests/functional/mips/test_tuxrun.py (renamed from tests/functional/test_mips_tuxrun.py)0
-rw-r--r--tests/functional/mips64/meson.build10
-rwxr-xr-xtests/functional/mips64/test_malta.py (renamed from tests/functional/test_mips64_malta.py)2
-rwxr-xr-xtests/functional/mips64/test_tuxrun.py (renamed from tests/functional/test_mips64_tuxrun.py)0
-rw-r--r--tests/functional/mips64el/meson.build14
-rwxr-xr-xtests/functional/mips64el/test_fuloong2e.py (renamed from tests/functional/test_mips64el_fuloong2e.py)0
-rwxr-xr-xtests/functional/mips64el/test_loongson3v.py (renamed from tests/functional/test_mips64el_loongson3v.py)0
-rwxr-xr-xtests/functional/mips64el/test_malta.py (renamed from tests/functional/test_mips64el_malta.py)4
-rwxr-xr-xtests/functional/mips64el/test_replay.py (renamed from tests/functional/test_mips64el_replay.py)0
-rwxr-xr-xtests/functional/mips64el/test_tuxrun.py (renamed from tests/functional/test_mips64el_tuxrun.py)0
-rw-r--r--tests/functional/mipsel/meson.build12
-rwxr-xr-xtests/functional/mipsel/test_malta.py (renamed from tests/functional/test_mipsel_malta.py)2
-rwxr-xr-x[-rw-r--r--]tests/functional/mipsel/test_replay.py (renamed from tests/functional/test_mipsel_replay.py)0
-rwxr-xr-xtests/functional/mipsel/test_tuxrun.py (renamed from tests/functional/test_mipsel_tuxrun.py)0
-rw-r--r--[-rwxr-xr-x]tests/functional/multiprocess.py (renamed from tests/functional/test_multiprocess.py)40
-rw-r--r--tests/functional/or1k/meson.build6
-rwxr-xr-xtests/functional/or1k/test_replay.py (renamed from tests/functional/test_or1k_replay.py)0
-rwxr-xr-xtests/functional/or1k/test_sim.py (renamed from tests/functional/test_or1k_sim.py)0
-rw-r--r--tests/functional/ppc/meson.build22
-rwxr-xr-xtests/functional/ppc/test_40p.py (renamed from tests/functional/test_ppc_40p.py)0
-rwxr-xr-xtests/functional/ppc/test_74xx.py (renamed from tests/functional/test_ppc_74xx.py)0
-rwxr-xr-xtests/functional/ppc/test_amiga.py (renamed from tests/functional/test_ppc_amiga.py)0
-rwxr-xr-xtests/functional/ppc/test_bamboo.py (renamed from tests/functional/test_ppc_bamboo.py)0
-rwxr-xr-xtests/functional/ppc/test_mac.py (renamed from tests/functional/test_ppc_mac.py)0
-rwxr-xr-xtests/functional/ppc/test_migration.py26
-rwxr-xr-xtests/functional/ppc/test_mpc8544ds.py (renamed from tests/functional/test_ppc_mpc8544ds.py)0
-rwxr-xr-xtests/functional/ppc/test_replay.py (renamed from tests/functional/test_ppc_replay.py)0
-rwxr-xr-x[-rw-r--r--]tests/functional/ppc/test_sam460ex.py (renamed from tests/functional/test_ppc_sam460ex.py)0
-rwxr-xr-xtests/functional/ppc/test_tuxrun.py (renamed from tests/functional/test_ppc_tuxrun.py)0
-rwxr-xr-xtests/functional/ppc/test_virtex_ml507.py (renamed from tests/functional/test_ppc_virtex_ml507.py)0
-rw-r--r--tests/functional/ppc64/meson.build25
-rwxr-xr-xtests/functional/ppc64/test_e500.py (renamed from tests/functional/test_ppc64_e500.py)0
-rwxr-xr-xtests/functional/ppc64/test_hv.py (renamed from tests/functional/test_ppc64_hv.py)0
-rwxr-xr-xtests/functional/ppc64/test_mac99.py (renamed from tests/functional/test_ppc64_mac99.py)0
-rwxr-xr-xtests/functional/ppc64/test_migration.py26
-rwxr-xr-xtests/functional/ppc64/test_powernv.py (renamed from tests/functional/test_ppc64_powernv.py)0
-rwxr-xr-xtests/functional/ppc64/test_pseries.py (renamed from tests/functional/test_ppc64_pseries.py)0
-rwxr-xr-xtests/functional/ppc64/test_replay.py (renamed from tests/functional/test_ppc64_replay.py)0
-rwxr-xr-xtests/functional/ppc64/test_reverse_debug.py (renamed from tests/functional/test_ppc64_reverse_debug.py)0
-rwxr-xr-xtests/functional/ppc64/test_tuxrun.py (renamed from tests/functional/test_ppc64_tuxrun.py)0
-rw-r--r--tests/functional/qemu_test/ports.py5
-rw-r--r--tests/functional/qemu_test/testcase.py1
-rw-r--r--tests/functional/riscv32/meson.build10
-rwxr-xr-xtests/functional/riscv32/test_migration.py26
-rwxr-xr-xtests/functional/riscv32/test_opensbi.py10
-rwxr-xr-xtests/functional/riscv32/test_tuxrun.py (renamed from tests/functional/test_riscv32_tuxrun.py)0
-rw-r--r--tests/functional/riscv64/meson.build15
-rwxr-xr-xtests/functional/riscv64/test_migration.py26
-rwxr-xr-xtests/functional/riscv64/test_opensbi.py (renamed from tests/functional/test_riscv_opensbi.py)0
-rwxr-xr-xtests/functional/riscv64/test_sifive_u.py (renamed from tests/functional/test_riscv64_sifive_u.py)0
-rwxr-xr-xtests/functional/riscv64/test_tuxrun.py (renamed from tests/functional/test_riscv64_tuxrun.py)0
-rw-r--r--tests/functional/rx/meson.build5
-rwxr-xr-xtests/functional/rx/test_gdbsim.py (renamed from tests/functional/test_rx_gdbsim.py)0
-rw-r--r--tests/functional/s390x/meson.build13
-rwxr-xr-xtests/functional/s390x/test_ccw_virtio.py (renamed from tests/functional/test_s390x_ccw_virtio.py)0
-rwxr-xr-xtests/functional/s390x/test_pxelinux.py (renamed from tests/functional/test_s390x_pxelinux.py)0
-rwxr-xr-xtests/functional/s390x/test_replay.py (renamed from tests/functional/test_s390x_replay.py)0
-rwxr-xr-xtests/functional/s390x/test_topology.py (renamed from tests/functional/test_s390x_topology.py)0
-rwxr-xr-xtests/functional/s390x/test_tuxrun.py (renamed from tests/functional/test_s390x_tuxrun.py)0
-rw-r--r--tests/functional/sh4/meson.build10
-rwxr-xr-xtests/functional/sh4/test_r2d.py (renamed from tests/functional/test_sh4_r2d.py)0
-rwxr-xr-xtests/functional/sh4/test_tuxrun.py (renamed from tests/functional/test_sh4_tuxrun.py)0
-rw-r--r--tests/functional/sh4eb/meson.build5
-rwxr-xr-xtests/functional/sh4eb/test_r2d.py (renamed from tests/functional/test_sh4eb_r2d.py)0
-rw-r--r--tests/functional/sparc/meson.build10
-rwxr-xr-xtests/functional/sparc/test_migration.py26
-rwxr-xr-xtests/functional/sparc/test_replay.py (renamed from tests/functional/test_sparc_replay.py)0
-rwxr-xr-xtests/functional/sparc/test_sun4m.py (renamed from tests/functional/test_sparc_sun4m.py)0
-rw-r--r--tests/functional/sparc64/meson.build10
-rwxr-xr-xtests/functional/sparc64/test_migration.py26
-rwxr-xr-xtests/functional/sparc64/test_sun4u.py (renamed from tests/functional/test_sparc64_sun4u.py)0
-rwxr-xr-xtests/functional/sparc64/test_tuxrun.py (renamed from tests/functional/test_sparc64_tuxrun.py)0
-rw-r--r--tests/functional/x86_64/meson.build36
-rwxr-xr-xtests/functional/x86_64/test_acpi_bits.py (renamed from tests/functional/test_acpi_bits.py)0
-rwxr-xr-xtests/functional/x86_64/test_cpu_model_versions.py (renamed from tests/functional/test_x86_cpu_model_versions.py)0
-rwxr-xr-xtests/functional/x86_64/test_cpu_queries.py (renamed from tests/functional/test_cpu_queries.py)0
-rwxr-xr-xtests/functional/x86_64/test_hotplug_blk.py (renamed from tests/functional/test_x86_64_hotplug_blk.py)0
-rwxr-xr-xtests/functional/x86_64/test_hotplug_cpu.py (renamed from tests/functional/test_x86_64_hotplug_cpu.py)0
-rwxr-xr-xtests/functional/x86_64/test_intel_iommu.py (renamed from tests/functional/test_intel_iommu.py)0
-rwxr-xr-xtests/functional/x86_64/test_kvm_xen.py (renamed from tests/functional/test_x86_64_kvm_xen.py)0
-rwxr-xr-xtests/functional/x86_64/test_linux_initrd.py (renamed from tests/functional/test_linux_initrd.py)0
-rwxr-xr-xtests/functional/x86_64/test_mem_addr_space.py (renamed from tests/functional/test_mem_addr_space.py)0
-rwxr-xr-xtests/functional/x86_64/test_memlock.py (renamed from tests/functional/test_memlock.py)0
-rwxr-xr-xtests/functional/x86_64/test_migration.py26
-rwxr-xr-xtests/functional/x86_64/test_multiprocess.py31
-rwxr-xr-xtests/functional/x86_64/test_netdev_ethtool.py (renamed from tests/functional/test_netdev_ethtool.py)0
-rwxr-xr-xtests/functional/x86_64/test_pc_cpu_hotplug_props.py (renamed from tests/functional/test_pc_cpu_hotplug_props.py)0
-rwxr-xr-xtests/functional/x86_64/test_replay.py (renamed from tests/functional/test_x86_64_replay.py)0
-rwxr-xr-xtests/functional/x86_64/test_reverse_debug.py (renamed from tests/functional/test_x86_64_reverse_debug.py)0
-rwxr-xr-xtests/functional/x86_64/test_tuxrun.py (renamed from tests/functional/test_x86_64_tuxrun.py)0
-rwxr-xr-xtests/functional/x86_64/test_virtio_balloon.py (renamed from tests/functional/test_virtio_balloon.py)0
-rwxr-xr-xtests/functional/x86_64/test_virtio_gpu.py (renamed from tests/functional/test_virtio_gpu.py)0
-rwxr-xr-xtests/functional/x86_64/test_virtio_version.py (renamed from tests/functional/test_virtio_version.py)0
-rw-r--r--tests/functional/xtensa/meson.build6
-rwxr-xr-xtests/functional/xtensa/test_lx60.py (renamed from tests/functional/test_xtensa_lx60.py)0
-rwxr-xr-xtests/functional/xtensa/test_replay.py (renamed from tests/functional/test_xtensa_replay.py)0
201 files changed, 1008 insertions, 525 deletions
diff --git a/.gitlab-ci.d/windows.yml b/.gitlab-ci.d/windows.yml
index 45ed0c96fe..beac39e5bd 100644
--- a/.gitlab-ci.d/windows.yml
+++ b/.gitlab-ci.d/windows.yml
@@ -77,7 +77,7 @@ msys2-64bit:
       git grep make sed
       mingw-w64-x86_64-binutils
       mingw-w64-x86_64-ccache
-      mingw-w64-x86_64-curl
+      mingw-w64-x86_64-curl-winssl
       mingw-w64-x86_64-gcc
       mingw-w64-x86_64-glib2
       mingw-w64-x86_64-libnfs
diff --git a/MAINTAINERS b/MAINTAINERS
index a07086ed76..a64b5b849b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -146,6 +146,8 @@ F: target/i386/*.[ch]
 F: target/i386/Kconfig
 F: target/i386/meson.build
 F: tools/i386/
+F: tests/functional/i386/
+F: tests/functional/x86_64/
 
 Guest CPU cores (TCG)
 ---------------------
@@ -189,6 +191,7 @@ M: Richard Henderson <richard.henderson@linaro.org>
 S: Maintained
 F: target/alpha/
 F: tests/tcg/alpha/
+F: tests/functional/alpha/
 F: disas/alpha.c
 
 ARM TCG CPUs
@@ -212,7 +215,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/arm/smmu*
 F: include/hw/arm/smmu*
-F: tests/functional/test_aarch64_smmu.py
+F: tests/functional/aarch64/test_smmu.py
 
 AVR TCG CPUs
 M: Michael Rolnik <mrolnik@gmail.com>
@@ -220,7 +223,7 @@ S: Maintained
 F: docs/system/target-avr.rst
 F: gdb-xml/avr-cpu.xml
 F: target/avr/
-F: tests/functional/test_avr_*.py
+F: tests/functional/avr/
 
 Hexagon TCG CPUs
 M: Brian Cain <brian.cain@oss.qualcomm.com>
@@ -256,7 +259,7 @@ M: Song Gao <gaosong@loongson.cn>
 S: Maintained
 F: target/loongarch/
 F: tests/tcg/loongarch64/
-F: tests/functional/test_loongarch64_virt.py
+F: tests/functional/loongarch64/test_virt.py
 
 M68K TCG CPUs
 M: Laurent Vivier <laurent@vivier.eu>
@@ -308,7 +311,7 @@ F: configs/devices/ppc*
 F: docs/system/ppc/embedded.rst
 F: docs/system/target-ppc.rst
 F: tests/tcg/ppc*/*
-F: tests/functional/test_ppc_74xx.py
+F: tests/functional/ppc/test_74xx.py
 
 RISC-V TCG CPUs
 M: Palmer Dabbelt <palmer@dabbelt.com>
@@ -330,7 +333,8 @@ F: include/hw/riscv/
 F: linux-user/host/riscv32/
 F: linux-user/host/riscv64/
 F: common-user/host/riscv*
-F: tests/functional/test_riscv*
+F: tests/functional/riscv32
+F: tests/functional/riscv64
 F: tests/tcg/riscv64/
 
 RISC-V XThead* extensions
@@ -443,6 +447,7 @@ M: Peter Maydell <peter.maydell@linaro.org>
 L: qemu-arm@nongnu.org
 S: Maintained
 F: target/arm/kvm.c
+F: tests/functional/aarch64/test_kvm.py
 
 MIPS KVM CPUs
 M: Huacai Chen <chenhuacai@kernel.org>
@@ -479,7 +484,7 @@ F: docs/system/i386/sgx.rst
 F: target/i386/kvm/
 F: target/i386/sev*
 F: scripts/kvm/vmxcap
-F: tests/functional/test_x86_64_hotplug_cpu.py
+F: tests/functional/x86_64/test_hotplug_cpu.py
 
 Xen emulation on X86 KVM CPUs
 M: David Woodhouse <dwmw2@infradead.org>
@@ -488,7 +493,7 @@ S: Supported
 F: include/system/kvm_xen.h
 F: target/i386/kvm/xen*
 F: hw/i386/kvm/xen*
-F: tests/functional/test_x86_64_kvm_xen.py
+F: tests/functional/x86_64/test_kvm_xen.py
 
 Guest CPU Cores (other accelerators)
 ------------------------------------
@@ -656,7 +661,7 @@ S: Maintained
 F: hw/alpha/
 F: hw/isa/smc37c669-superio.c
 F: tests/tcg/alpha/system/
-F: tests/functional/test_alpha_clipper.py
+F: tests/functional/alpha/test_clipper.py
 
 ARM Machines
 ------------
@@ -672,7 +677,7 @@ F: include/hw/*/allwinner*
 F: hw/arm/cubieboard.c
 F: docs/system/arm/cubieboard.rst
 F: hw/misc/axp209.c
-F: tests/functional/test_arm_cubieboard.py
+F: tests/functional/arm/test_cubieboard.py
 
 Allwinner-h3
 M: Niek Linnenbank <nieklinnenbank@gmail.com>
@@ -682,7 +687,7 @@ F: hw/*/allwinner-h3*
 F: include/hw/*/allwinner-h3*
 F: hw/arm/orangepi.c
 F: docs/system/arm/orangepi.rst
-F: tests/functional/test_arm_orangepi.py
+F: tests/functional/arm/test_orangepi.py
 
 ARM PrimeCell and CMSDK devices
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -752,7 +757,7 @@ F: docs/system/arm/bananapi_m2u.rst
 F: hw/*/allwinner-r40*.c
 F: hw/arm/bananapi_m2u.c
 F: include/hw/*/allwinner-r40*.h
-F: tests/functional/test_arm_bpim2u.py
+F: tests/functional/arm/test_bpim2u.py
 
 B-L475E-IOT01A IoT Node
 M: Samuel Tardieu <sam@rfc1149.net>
@@ -770,7 +775,7 @@ S: Odd Fixes
 F: hw/*/exynos*
 F: include/hw/*/exynos*
 F: docs/system/arm/exynos.rst
-F: tests/functional/test_arm_smdkc210.py
+F: tests/functional/arm/test_smdkc210.py
 
 Calxeda Highbank
 M: Rob Herring <robh@kernel.org>
@@ -789,7 +794,7 @@ S: Odd Fixes
 F: include/hw/arm/digic.h
 F: hw/*/digic*
 F: include/hw/*/digic*
-F: tests/functional/test_arm_canona1100.py
+F: tests/functional/arm/test_canona1100.py
 F: docs/system/arm/digic.rst
 
 Goldfish RTC
@@ -832,7 +837,7 @@ S: Odd Fixes
 F: hw/arm/integratorcp.c
 F: hw/misc/arm_integrator_debug.c
 F: include/hw/misc/arm_integrator_debug.h
-F: tests/functional/test_arm_integratorcp.py
+F: tests/functional/arm/test_integratorcp.py
 F: docs/system/arm/integratorcp.rst
 
 MCIMX6UL EVK / i.MX6ul
@@ -874,7 +879,7 @@ F: include/hw/arm/fsl-imx8mp.h
 F: include/hw/misc/imx8mp_*.h
 F: include/hw/pci-host/fsl_imx8m_phy.h
 F: docs/system/arm/imx8mp-evk.rst
-F: tests/functional/test_aarch64_imx8mp_evk.py
+F: tests/functional/aarch64/test_imx8mp_evk.py
 F: tests/qtest/rs5c372-test.c
 
 MPS2 / MPS3
@@ -938,7 +943,7 @@ F: pc-bios/npcm7xx_bootrom.bin
 F: pc-bios/npcm8xx_bootrom.bin
 F: roms/vbootrom
 F: docs/system/arm/nuvoton.rst
-F: tests/functional/test_arm_quanta_gsj.py
+F: tests/functional/arm/test_quanta_gsj.py
 
 Raspberry Pi
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -951,9 +956,8 @@ F: hw/*/bcm283*
 F: include/hw/arm/rasp*
 F: include/hw/*/bcm283*
 F: docs/system/arm/raspi.rst
-F: tests/functional/test_arm_raspi2.py
-F: tests/functional/test_aarch64_raspi3.py
-F: tests/functional/test_aarch64_raspi4.py
+F: tests/functional/arm/test_raspi2.py
+F: tests/functional/aarch64/test_raspi*.py
 
 Real View
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -964,7 +968,7 @@ F: hw/cpu/realview_mpcore.c
 F: hw/intc/realview_gic.c
 F: include/hw/intc/realview_gic.h
 F: docs/system/arm/realview.rst
-F: tests/functional/test_arm_realview.py
+F: tests/functional/arm/test_realview.py
 
 SABRELITE / i.MX6
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -993,7 +997,7 @@ F: hw/misc/sbsa_ec.c
 F: hw/watchdog/sbsa_gwdt.c
 F: include/hw/watchdog/sbsa_gwdt.h
 F: docs/system/arm/sbsa.rst
-F: tests/functional/test_aarch64_*sbsaref*.py
+F: tests/functional/aarch64/test_*sbsaref*.py
 
 Sharp SL-5500 (Collie) PDA
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -1004,7 +1008,7 @@ F: hw/arm/strongarm*
 F: hw/gpio/zaurus.c
 F: include/hw/arm/sharpsl.h
 F: docs/system/arm/collie.rst
-F: tests/functional/test_arm_collie.py
+F: tests/functional/arm/test_collie.py
 
 Stellaris
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -1015,7 +1019,7 @@ F: hw/display/ssd03*
 F: include/hw/input/stellaris_gamepad.h
 F: include/hw/timer/stellaris-gptm.h
 F: docs/system/arm/stellaris.rst
-F: tests/functional/test_arm_stellaris.py
+F: tests/functional/arm/test_stellaris.py
 
 STM32L4x5 SoC Family
 M: Samuel Tardieu <sam@rfc1149.net>
@@ -1044,7 +1048,7 @@ S: Odd Fixes
 F: hw/arm/vexpress.c
 F: hw/display/sii9022.c
 F: docs/system/arm/vexpress.rst
-F: tests/functional/test_arm_vexpress.py
+F: tests/functional/arm/test_vexpress.py
 
 Versatile PB
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -1063,10 +1067,10 @@ S: Maintained
 F: hw/arm/virt*
 F: include/hw/arm/virt.h
 F: docs/system/arm/virt.rst
-F: tests/functional/test_aarch64_*virt*.py
-F: tests/functional/test_aarch64_tuxrun.py
-F: tests/functional/test_arm_tuxrun.py
-F: tests/functional/test_arm_virt.py
+F: tests/functional/aarch64/test_*virt*.py
+F: tests/functional/aarch64/test_tuxrun.py
+F: tests/functional/arm/test_tuxrun.py
+F: tests/functional/arm/test_virt.py
 
 Xilinx Zynq
 M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@@ -1096,7 +1100,7 @@ F: hw/display/dpcd.c
 F: include/hw/display/dpcd.h
 F: docs/system/arm/xlnx-versal-virt.rst
 F: docs/system/arm/xlnx-zcu102.rst
-F: tests/functional/test_aarch64_xlnx_versal.py
+F: tests/functional/aarch64/test_xlnx_versal.py
 
 Xilinx Versal OSPI
 M: Francisco Iglesias <francisco.iglesias@amd.com>
@@ -1187,7 +1191,7 @@ L: qemu-arm@nongnu.org
 S: Maintained
 F: hw/arm/msf2-som.c
 F: docs/system/arm/emcraft-sf2.rst
-F: tests/functional/test_arm_emcraft_sf2.py
+F: tests/functional/arm/test_emcraft_sf2.py
 
 ASPEED BMCs
 M: Cédric Le Goater <clg@kaod.org>
@@ -1205,6 +1209,7 @@ F: hw/net/ftgmac100.c
 F: include/hw/net/ftgmac100.h
 F: docs/system/arm/aspeed.rst
 F: docs/system/arm/fby35.rst
+F: tests/functional/*/*aspeed*
 F: tests/*/*aspeed*
 F: tests/*/*ast2700*
 F: hw/arm/fby35.c
@@ -1220,7 +1225,7 @@ F: hw/*/microbit*.c
 F: include/hw/*/nrf51*.h
 F: include/hw/*/microbit*.h
 F: tests/qtest/microbit-test.c
-F: tests/functional/test_arm_microbit.py
+F: tests/functional/arm/test_microbit.py
 F: docs/system/arm/nrf.rst
 
 ARM PL011 Rust device
@@ -1247,7 +1252,7 @@ Arduino
 M: Philippe Mathieu-Daudé <philmd@linaro.org>
 S: Maintained
 F: hw/avr/arduino.c
-F: tests/functional/test_avr_uno.py
+F: tests/functional/avr/test_uno.py
 
 HP-PARISC Machines
 ------------------
@@ -1271,7 +1276,7 @@ F: include/hw/pci-host/astro.h
 F: include/hw/pci-host/dino.h
 F: pc-bios/hppa-firmware.img
 F: roms/seabios-hppa/
-F: tests/functional/test_hppa_seabios.py
+F: tests/functional/hppa/test_seabios.py
 
 LoongArch Machines
 ------------------
@@ -1309,7 +1314,7 @@ F: hw/m68k/mcf_intc.c
 F: hw/char/mcf_uart.c
 F: hw/net/mcf_fec.c
 F: include/hw/m68k/mcf*.h
-F: tests/functional/test_m68k_mcf5208evb.py
+F: tests/functional/m68k/test_mcf5208evb.py
 
 NeXTcube
 M: Thomas Huth <huth@tuxfamily.org>
@@ -1317,7 +1322,7 @@ S: Odd Fixes
 F: hw/m68k/next-*.c
 F: hw/display/next-fb.c
 F: include/hw/m68k/next-cube.h
-F: tests/functional/test_m68k_nextcube.py
+F: tests/functional/m68k/test_nextcube.py
 
 q800
 M: Laurent Vivier <laurent@vivier.eu>
@@ -1343,7 +1348,7 @@ F: include/hw/m68k/q800-glue.h
 F: include/hw/misc/djmemc.h
 F: include/hw/misc/iosb.h
 F: include/hw/audio/asc.h
-F: tests/functional/test_m68k_q800.py
+F: tests/functional/m68k/test_q800.py
 
 virt
 M: Laurent Vivier <laurent@vivier.eu>
@@ -1358,7 +1363,7 @@ F: include/hw/intc/goldfish_pic.h
 F: include/hw/intc/m68k_irqc.h
 F: include/hw/misc/virt_ctrl.h
 F: docs/specs/virt-ctlr.rst
-F: tests/functional/test_m68k_tuxrun.py
+F: tests/functional/m68k/test_tuxrun.py
 
 MicroBlaze Machines
 -------------------
@@ -1367,7 +1372,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
 S: Maintained
 F: hw/microblaze/petalogix_s3adsp1800_mmu.c
 F: include/hw/char/xilinx_uartlite.h
-F: tests/functional/test_microblaze*.py
+F: tests/functional/microblaze*/test_s3adsp1800.py
 
 petalogix_ml605
 M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@@ -1403,8 +1408,8 @@ F: hw/acpi/piix4.c
 F: hw/mips/malta.c
 F: hw/pci-host/gt64120.c
 F: include/hw/southbridge/piix.h
-F: tests/functional/test_mips*_malta.py
-F: tests/functional/test_mips*_tuxrun.py
+F: tests/functional/mips*/test_malta.py
+F: tests/functional/mips*/test_tuxrun.py
 
 Mipssim
 R: Aleksandar Rikalo <arikalo@gmail.com>
@@ -1420,7 +1425,7 @@ S: Odd Fixes
 F: hw/mips/fuloong2e.c
 F: hw/pci-host/bonito.c
 F: include/hw/pci-host/bonito.h
-F: tests/functional/test_mips64el_fuloong2e.py
+F: tests/functional/mips64el/test_fuloong2e.py
 
 Loongson-3 virtual platforms
 M: Huacai Chen <chenhuacai@kernel.org>
@@ -1435,7 +1440,7 @@ F: hw/mips/loongson3_virt.c
 F: include/hw/intc/loongson_ipi_common.h
 F: include/hw/intc/loongson_ipi.h
 F: include/hw/intc/loongson_liointc.h
-F: tests/functional/test_mips64el_loongson3v.py
+F: tests/functional/mips64el/test_loongson3v.py
 
 Boston
 M: Paul Burton <paulburton@kernel.org>
@@ -1454,7 +1459,7 @@ S: Maintained
 F: docs/system/openrisc/or1k-sim.rst
 F: hw/intc/ompic.c
 F: hw/openrisc/openrisc_sim.c
-F: tests/functional/test_or1k_sim.py
+F: tests/functional/or1k/test_sim.py
 
 PowerPC Machines
 ----------------
@@ -1463,7 +1468,7 @@ L: qemu-ppc@nongnu.org
 S: Orphan
 F: hw/ppc/ppc440_bamboo.c
 F: hw/pci-host/ppc4xx_pci.c
-F: tests/functional/test_ppc_bamboo.py
+F: tests/functional/ppc/test_bamboo.py
 
 e500
 M: Bernhard Beschow <shentey@gmail.com>
@@ -1481,8 +1486,8 @@ F: pc-bios/u-boot.e500
 F: hw/intc/openpic_kvm.c
 F: include/hw/ppc/openpic_kvm.h
 F: docs/system/ppc/ppce500.rst
-F: tests/functional/test_ppc64_e500.py
-F: tests/functional/test_ppc_tuxrun.py
+F: tests/functional/ppc64/test_e500.py
+F: tests/functional/ppc/test_tuxrun.py
 
 mpc8544ds
 M: Bernhard Beschow <shentey@gmail.com>
@@ -1490,7 +1495,7 @@ L: qemu-ppc@nongnu.org
 S: Odd Fixes
 F: hw/ppc/mpc8544ds.c
 F: hw/ppc/mpc8544_guts.c
-F: tests/functional/test_ppc_mpc8544ds.py
+F: tests/functional/ppc/test_mpc8544ds.py
 
 New World (mac99)
 M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
@@ -1512,8 +1517,8 @@ F: include/hw/ppc/mac_dbdma.h
 F: include/hw/pci-host/uninorth.h
 F: include/hw/input/adb*
 F: pc-bios/qemu_vga.ndrv
-F: tests/functional/test_ppc_mac.py
-F: tests/functional/test_ppc64_mac99.py
+F: tests/functional/ppc/test_mac.py
+F: tests/functional/ppc64/test_mac99.py
 
 Old World (g3beige)
 M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
@@ -1529,7 +1534,7 @@ F: include/hw/intc/heathrow_pic.h
 F: include/hw/input/adb*
 F: include/hw/pci-host/grackle.h
 F: pc-bios/qemu_vga.ndrv
-F: tests/functional/test_ppc_mac.py
+F: tests/functional/ppc/test_mac.py
 
 PReP
 M: Hervé Poussineau <hpoussin@reactos.org>
@@ -1546,7 +1551,7 @@ F: hw/dma/i82374.c
 F: hw/rtc/m48t59-isa.c
 F: include/hw/isa/pc87312.h
 F: include/hw/rtc/m48t59.h
-F: tests/functional/test_ppc_40p.py
+F: tests/functional/ppc/test_40p.py
 
 sPAPR (pseries)
 M: Nicholas Piggin <npiggin@gmail.com>
@@ -1569,9 +1574,9 @@ F: tests/qtest/spapr*
 F: tests/qtest/libqos/*spapr*
 F: tests/qtest/rtas*
 F: tests/qtest/libqos/rtas*
-F: tests/functional/test_ppc64_pseries.py
-F: tests/functional/test_ppc64_hv.py
-F: tests/functional/test_ppc64_tuxrun.py
+F: tests/functional/ppc64/test_pseries.py
+F: tests/functional/ppc64/test_hv.py
+F: tests/functional/ppc64/test_tuxrun.py
 
 PowerNV (Non-Virtualized)
 M: Nicholas Piggin <npiggin@gmail.com>
@@ -1590,7 +1595,7 @@ F: include/hw/ssi/pnv_spi*
 F: pc-bios/skiboot.lid
 F: pc-bios/pnv-pnor.bin
 F: tests/qtest/pnv*
-F: tests/functional/test_ppc64_powernv.py
+F: tests/functional/ppc64/test_powernv.py
 
 pca955x
 M: Glenn Miles <milesg@linux.ibm.com>
@@ -1605,7 +1610,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
 L: qemu-ppc@nongnu.org
 S: Odd Fixes
 F: hw/ppc/virtex_ml507.c
-F: tests/functional/test_ppc_virtex_ml507.py
+F: tests/functional/ppc/test_virtex_ml507.py
 
 sam460ex
 M: BALATON Zoltan <balaton@eik.bme.hu>
@@ -1621,7 +1626,7 @@ F: pc-bios/dtb/canyonlands.dt[sb]
 F: pc-bios/u-boot-sam460ex-20100605.bin
 F: roms/u-boot-sam460ex
 F: docs/system/ppc/amigang.rst
-F: tests/functional/test_ppc_sam460ex.py
+F: tests/functional/ppc/test_sam460ex.py
 
 pegasos2
 M: BALATON Zoltan <balaton@eik.bme.hu>
@@ -1639,7 +1644,7 @@ S: Maintained
 F: hw/ppc/amigaone.c
 F: hw/pci-host/articia.c
 F: include/hw/pci-host/articia.h
-F: tests/functional/test_ppc_amiga.py
+F: tests/functional/ppc/test_amiga.py
 
 Virtual Open Firmware (VOF)
 M: Alexey Kardashevskiy <aik@ozlabs.ru>
@@ -1717,7 +1722,7 @@ R: Yoshinori Sato <yoshinori.sato@nifty.com>
 S: Orphan
 F: docs/system/target-rx.rst
 F: hw/rx/rx-gdbsim.c
-F: tests/functional/test_rx_gdbsim.py
+F: tests/functional/rx/test_gdbsim.py
 
 SH4 Machines
 ------------
@@ -1732,8 +1737,8 @@ F: hw/pci-host/sh_pci.c
 F: hw/timer/sh_timer.c
 F: include/hw/sh4/sh_intc.h
 F: include/hw/timer/tmu012.h
-F: tests/functional/test_sh4*_r2d.py
-F: tests/functional/test_sh4_tuxrun.py
+F: tests/functional/sh4*/test_r2d.py
+F: tests/functional/sh4/test_tuxrun.py
 
 SPARC Machines
 --------------
@@ -1751,7 +1756,7 @@ F: include/hw/nvram/sun_nvram.h
 F: include/hw/sparc/sparc32_dma.h
 F: include/hw/sparc/sun4m_iommu.h
 F: pc-bios/openbios-sparc32
-F: tests/functional/test_sparc_sun4m.py
+F: tests/functional/sparc/test_sun4m.py
 
 Sun4u
 M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
@@ -1764,8 +1769,8 @@ F: include/hw/pci-host/sabre.h
 F: hw/pci-bridge/simba.c
 F: include/hw/pci-bridge/simba.h
 F: pc-bios/openbios-sparc64
-F: tests/functional/test_sparc64_sun4u.py
-F: tests/functional/test_sparc64_tuxrun.py
+F: tests/functional/sparc64/test_sun4u.py
+F: tests/functional/sparc64/test_tuxrun.py
 
 Sun4v
 M: Artyom Tarasenko <atar4qemu@gmail.com>
@@ -1793,7 +1798,7 @@ S: Supported
 F: hw/s390x/
 F: include/hw/s390x/
 F: configs/devices/s390x-softmmu/default.mak
-F: tests/functional/test_s390x_*
+F: tests/functional/s390x
 T: git https://github.com/borntraeger/qemu.git s390-next
 L: qemu-s390x@nongnu.org
 
@@ -1807,7 +1812,7 @@ F: hw/s390x/ipl.*
 F: pc-bios/s390-ccw/
 F: pc-bios/s390-ccw.img
 F: docs/devel/s390-dasd-ipl.rst
-F: tests/functional/test_s390x_pxelinux.py
+F: tests/functional/s390x/test_pxelinux.py
 T: git https://github.com/borntraeger/qemu.git s390-next
 L: qemu-s390x@nongnu.org
 
@@ -1861,7 +1866,7 @@ F: hw/s390x/cpu-topology.c
 F: target/s390x/kvm/stsi-topology.c
 F: docs/devel/s390-cpu-topology.rst
 F: docs/system/s390x/cpu-topology.rst
-F: tests/functional/test_s390x_topology.py
+F: tests/functional/s390x/test_topology.py
 
 X86 Machines
 ------------
@@ -1889,12 +1894,12 @@ F: hw/isa/apm.c
 F: include/hw/isa/apm.h
 F: tests/unit/test-x86-topo.c
 F: tests/qtest/test-x86-cpuid-compat.c
-F: tests/functional/test_i386_tuxrun.py
-F: tests/functional/test_linux_initrd.py
-F: tests/functional/test_mem_addr_space.py
-F: tests/functional/test_pc_cpu_hotplug_props.py
-F: tests/functional/test_x86_64_tuxrun.py
-F: tests/functional/test_x86_cpu_model_versions.py
+F: tests/functional/i386/test_tuxrun.py
+F: tests/functional/x86_64/test_linux_initrd.py
+F: tests/functional/x86_64/test_mem_addr_space.py
+F: tests/functional/x86_64/test_pc_cpu_hotplug_props.py
+F: tests/functional/x86_64/test_tuxrun.py
+F: tests/functional/x86_64/test_cpu_model_versions.py
 
 PC Chipset
 M: Michael S. Tsirkin <mst@redhat.com>
@@ -1970,8 +1975,8 @@ F: include/hw/boards.h
 F: include/hw/core/cpu.h
 F: include/hw/cpu/cluster.h
 F: include/system/numa.h
-F: tests/functional/test_cpu_queries.py
-F: tests/functional/test_empty_cpu_model.py
+F: tests/functional/x86_64/test_cpu_queries.py
+F: tests/functional/generic/test_empty_cpu_model.py
 F: tests/unit/test-smp-parse.c
 T: git https://gitlab.com/ehabkost/qemu.git machine-next
 
@@ -2000,7 +2005,7 @@ S: Maintained
 F: hw/xtensa/xtfpga.c
 F: hw/net/opencores_eth.c
 F: include/hw/xtensa/mx_pic.h
-F: tests/functional/test_xtensa_lx60.py
+F: tests/functional/xtensa/test_lx60.py
 
 Devices
 -------
@@ -2077,7 +2082,7 @@ S: Odd Fixes
 F: hw/*/omap*
 F: include/hw/arm/omap.h
 F: docs/system/arm/sx1.rst
-F: tests/functional/test_arm_sx1.py
+F: tests/functional/arm/test_sx1.py
 
 IPack
 M: Alberto Garcia <berto@igalia.com>
@@ -2109,7 +2114,7 @@ ARM PCI Hotplug
 M: Gustavo Romero <gustavo.romero@linaro.org>
 L: qemu-arm@nongnu.org
 S: Supported
-F: tests/functional/test_aarch64_hotplug_pci.py
+F: tests/functional/aarch64/test_hotplug_pci.py
 
 ACPI/SMBIOS
 M: Michael S. Tsirkin <mst@redhat.com>
@@ -2155,7 +2160,7 @@ M: Ani Sinha <anisinha@redhat.com>
 M: Michael S. Tsirkin <mst@redhat.com>
 S: Supported
 F: tests/functional/acpi-bits/*
-F: tests/functional/test_acpi_bits.py
+F: tests/functional/x86_64/test_acpi_bits.py
 F: docs/devel/testing/acpi-bits.rst
 
 ACPI/HEST/GHES
@@ -2192,7 +2197,7 @@ S: Odd Fixes
 F: hw/net/
 F: include/hw/net/
 F: tests/qtest/virtio-net-test.c
-F: tests/functional/test_info_usernet.py
+F: tests/functional/generic/test_info_usernet.py
 F: docs/system/virtio-net-failover.rst
 T: git https://github.com/jasowang/qemu.git net
 
@@ -2263,6 +2268,7 @@ F: util/vfio-helpers.c
 F: include/hw/vfio/
 F: docs/devel/migration/vfio.rst
 F: qapi/vfio.json
+F: tests/functional/aarch64/test_device_passthrough.py
 
 vfio-igd
 M: Alex Williamson <alex.williamson@redhat.com>
@@ -2340,7 +2346,7 @@ F: net/vhost-user.c
 F: include/hw/virtio/
 F: docs/devel/virtio*
 F: docs/devel/migration/virtio.rst
-F: tests/functional/test_virtio_version.py
+F: tests/functional/x86_64/test_virtio_version.py
 
 virtio-balloon
 M: Michael S. Tsirkin <mst@redhat.com>
@@ -2352,7 +2358,7 @@ F: include/hw/virtio/virtio-balloon.h
 F: system/balloon.c
 F: include/system/balloon.h
 F: tests/qtest/virtio-balloon-test.c
-F: tests/functional/test_virtio_balloon.py
+F: tests/functional/x86_64/test_virtio_balloon.py
 
 virtio-9p
 M: Christian Schoenebeck <qemu_oss@crudebyte.com>
@@ -2375,7 +2381,7 @@ F: hw/block/virtio-blk.c
 F: hw/block/dataplane/*
 F: include/hw/virtio/virtio-blk-common.h
 F: tests/qtest/virtio-blk-test.c
-F: tests/functional/test_x86_64_hotplug_blk.py
+F: tests/functional/x86_64/test_hotplug_blk.py
 T: git https://github.com/stefanha/qemu.git block
 
 virtio-ccw
@@ -2599,7 +2605,7 @@ R: Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>
 S: Odd Fixes
 F: docs/system/devices/igb.rst
 F: hw/net/igb*
-F: tests/functional/test_netdev_ethtool.py
+F: tests/functional/x86_64/test_netdev_ethtool.py
 F: tests/qtest/igb-test.c
 F: tests/qtest/libqos/igb.c
 
@@ -2638,7 +2644,7 @@ M: Alex Bennée <alex.bennee@linaro.org>
 S: Maintained
 F: hw/core/guest-loader.c
 F: docs/system/guest-loader.rst
-F: tests/functional/test_aarch64_xen.py
+F: tests/functional/aarch64/test_xen.py
 
 Intel Hexadecimal Object File Loader
 M: Su Hang <suhang16@mails.ucas.ac.cn>
@@ -2707,7 +2713,8 @@ 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
+F: tests/functional/aarch64/test_virt_gpu.py
+F: tests/functional/x86_64/test_virtio_gpu.py
 
 vhost-user-blk
 M: Raphael Norwitz <raphael@enfabrica.net>
@@ -3127,7 +3134,7 @@ S: Supported
 F: include/qemu/option.h
 F: tests/unit/test-keyval.c
 F: tests/unit/test-qemu-opts.c
-F: tests/functional/test_version.py
+F: tests/functional/generic/test_version.py
 F: util/keyval.c
 F: util/qemu-option.c
 
@@ -3245,7 +3252,7 @@ F: include/ui/
 F: qapi/ui.json
 F: util/drm.c
 F: docs/devel/ui.rst
-F: tests/functional/test_vnc.py
+F: tests/functional/generic/test_vnc.py
 
 Cocoa graphics
 M: Peter Maydell <peter.maydell@linaro.org>
@@ -3597,7 +3604,8 @@ F: include/migration/
 F: include/qemu/userfaultfd.h
 F: migration/
 F: scripts/vmstate-static-checker.py
-F: tests/functional/test_migration.py
+F: tests/functional/migration.py
+F: tests/functional/*/*migration.py
 F: tests/vmstate-static-checker-data/
 F: tests/qtest/migration/
 F: tests/qtest/migration-*
@@ -3766,8 +3774,10 @@ F: include/system/replay.h
 F: docs/devel/replay.rst
 F: docs/system/replay.rst
 F: stubs/replay.c
-F: tests/functional/*reverse_debug*.py
-F: tests/functional/*replay*.py
+F: tests/functional/replay_kernel.py
+F: tests/functional/reverse_debugging.py
+F: tests/functional/*/*replay*.py
+F: tests/functional/*/*reverse_debug*.py
 F: qapi/replay.json
 
 IOVA Tree
@@ -3851,7 +3861,7 @@ S: Supported
 F: hw/i386/intel_iommu.c
 F: hw/i386/intel_iommu_internal.h
 F: include/hw/i386/intel_iommu.h
-F: tests/functional/test_intel_iommu.py
+F: tests/functional/x86_64/test_intel_iommu.py
 F: tests/qtest/intel-iommu-test.c
 
 AMD-Vi Emulation
@@ -3913,7 +3923,7 @@ F: configs/targets/*linux-user.mak
 F: scripts/qemu-binfmt-conf.sh
 F: scripts/update-syscalltbl.sh
 F: scripts/update-mips-syscall-args.sh
-F: tests/functional/test_arm_bflt.py
+F: tests/functional/arm/test_bflt.py
 
 Tiny Code Generator (TCG)
 -------------------------
@@ -3933,7 +3943,7 @@ S: Maintained
 F: docs/devel/tcg-plugins.rst
 F: plugins/
 F: tests/tcg/plugins/
-F: tests/functional/test_aarch64_tcg_plugins.py
+F: tests/functional/aarch64/test_tcg_plugins.py
 F: contrib/plugins/
 F: scripts/qemu-plugin-symbols.py
 
@@ -4286,7 +4296,8 @@ F: hw/remote/vfio-user-obj.c
 F: include/hw/remote/vfio-user-obj.h
 F: hw/remote/iommu.c
 F: include/hw/remote/iommu.h
-F: tests/functional/test_multiprocess.py
+F: tests/functional/multiprocess.py
+F: tests/functional/*/*multiprocess.py
 
 VFIO-USER:
 M: John Levon <john.levon@nutanix.com>
@@ -4325,7 +4336,7 @@ F: scripts/ci/
 F: tests/docker/
 F: tests/vm/
 F: tests/lcitool/
-F: tests/functional/test_*_tuxrun.py
+F: tests/functional/*/test_tuxrun.py
 F: scripts/archive-source.sh
 F: docs/devel/testing/ci*
 F: docs/devel/testing/main.rst
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index ef6be3660f..9326cfc895 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -3455,10 +3455,17 @@ static void machvirt_machine_init(void)
 }
 type_init(machvirt_machine_init);
 
+static void virt_machine_10_2_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(10, 2)
+
 static void virt_machine_10_1_options(MachineClass *mc)
 {
+    virt_machine_10_2_options(mc);
+    compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len);
 }
-DEFINE_VIRT_MACHINE_AS_LATEST(10, 1)
+DEFINE_VIRT_MACHINE(10, 1)
 
 static void virt_machine_10_0_options(MachineClass *mc)
 {
diff --git a/hw/core/machine.c b/hw/core/machine.c
index bd47527479..38c949c4f2 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -37,6 +37,9 @@
 #include "hw/virtio/virtio-iommu.h"
 #include "audio/audio.h"
 
+GlobalProperty hw_compat_10_1[] = {};
+const size_t hw_compat_10_1_len = G_N_ELEMENTS(hw_compat_10_1);
+
 GlobalProperty hw_compat_10_0[] = {
     { "scsi-hd", "dpofua", "off" },
     { "vfio-pci", "x-migration-load-config-after-iter", "off" },
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 2f58e73d33..bc048a6d13 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -81,6 +81,9 @@
     { "qemu64-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },\
     { "athlon-" TYPE_X86_CPU, "model-id", "QEMU Virtual CPU version " v, },
 
+GlobalProperty pc_compat_10_1[] = {};
+const size_t pc_compat_10_1_len = G_N_ELEMENTS(pc_compat_10_1);
+
 GlobalProperty pc_compat_10_0[] = {
     { TYPE_X86_CPU, "x-consistent-cache", "false" },
     { TYPE_X86_CPU, "x-vendor-cpuid-only-v2", "false" },
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index c03324281b..d165ac72ed 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -504,12 +504,21 @@ static void pc_i440fx_machine_options(MachineClass *m)
                      pc_piix_compat_defaults, pc_piix_compat_defaults_len);
 }
 
-static void pc_i440fx_machine_10_1_options(MachineClass *m)
+static void pc_i440fx_machine_10_2_options(MachineClass *m)
 {
     pc_i440fx_machine_options(m);
 }
 
-DEFINE_I440FX_MACHINE_AS_LATEST(10, 1);
+DEFINE_I440FX_MACHINE_AS_LATEST(10, 2);
+
+static void pc_i440fx_machine_10_1_options(MachineClass *m)
+{
+    pc_i440fx_machine_10_2_options(m);
+    compat_props_add(m->compat_props, hw_compat_10_1, hw_compat_10_1_len);
+    compat_props_add(m->compat_props, pc_compat_10_1, pc_compat_10_1_len);
+}
+
+DEFINE_I440FX_MACHINE(10, 1);
 
 static void pc_i440fx_machine_10_0_options(MachineClass *m)
 {
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index b309b2b378..e89951285e 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -374,12 +374,21 @@ static void pc_q35_machine_options(MachineClass *m)
                      pc_q35_compat_defaults, pc_q35_compat_defaults_len);
 }
 
-static void pc_q35_machine_10_1_options(MachineClass *m)
+static void pc_q35_machine_10_2_options(MachineClass *m)
 {
     pc_q35_machine_options(m);
 }
 
-DEFINE_Q35_MACHINE_AS_LATEST(10, 1);
+DEFINE_Q35_MACHINE_AS_LATEST(10, 2);
+
+static void pc_q35_machine_10_1_options(MachineClass *m)
+{
+    pc_q35_machine_10_2_options(m);
+    compat_props_add(m->compat_props, hw_compat_10_1, hw_compat_10_1_len);
+    compat_props_add(m->compat_props, pc_compat_10_1, pc_compat_10_1_len);
+}
+
+DEFINE_Q35_MACHINE(10, 1);
 
 static void pc_q35_machine_10_0_options(MachineClass *m)
 {
diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c
index 875fd00ef8..98cfe43c73 100644
--- a/hw/m68k/virt.c
+++ b/hw/m68k/virt.c
@@ -367,10 +367,17 @@ type_init(virt_machine_register_types)
 #define DEFINE_VIRT_MACHINE(major, minor) \
     DEFINE_VIRT_MACHINE_IMPL(false, major, minor)
 
+static void virt_machine_10_2_options(MachineClass *mc)
+{
+}
+DEFINE_VIRT_MACHINE_AS_LATEST(10, 2)
+
 static void virt_machine_10_1_options(MachineClass *mc)
 {
+    virt_machine_10_2_options(mc);
+    compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len);
 }
-DEFINE_VIRT_MACHINE_AS_LATEST(10, 1)
+DEFINE_VIRT_MACHINE(10, 1)
 
 static void virt_machine_10_0_options(MachineClass *mc)
 {
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1855a3cd8d..eb22333404 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4762,14 +4762,25 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
     DEFINE_SPAPR_MACHINE_IMPL(false, major, minor)
 
 /*
+ * pseries-10.2
+ */
+static void spapr_machine_10_2_class_options(MachineClass *mc)
+{
+    /* Defaults for the latest behaviour inherited from the base class */
+}
+
+DEFINE_SPAPR_MACHINE_AS_LATEST(10, 2);
+
+/*
  * pseries-10.1
  */
 static void spapr_machine_10_1_class_options(MachineClass *mc)
 {
-    /* Defaults for the latest behaviour inherited from the base class */
+    spapr_machine_10_2_class_options(mc);
+    compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len);
 }
 
-DEFINE_SPAPR_MACHINE_AS_LATEST(10, 1);
+DEFINE_SPAPR_MACHINE(10, 1);
 
 /*
  * pseries-10.0
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index a79bd13275..d0c6e80cb0 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -911,14 +911,26 @@ static const TypeInfo ccw_machine_info = {
     DEFINE_CCW_MACHINE_IMPL(false, major, minor)
 
 
+static void ccw_machine_10_2_instance_options(MachineState *machine)
+{
+}
+
+static void ccw_machine_10_2_class_options(MachineClass *mc)
+{
+}
+DEFINE_CCW_MACHINE_AS_LATEST(10, 2);
+
 static void ccw_machine_10_1_instance_options(MachineState *machine)
 {
+    ccw_machine_10_2_instance_options(machine);
 }
 
 static void ccw_machine_10_1_class_options(MachineClass *mc)
 {
+    ccw_machine_10_2_class_options(mc);
+    compat_props_add(mc->compat_props, hw_compat_10_1, hw_compat_10_1_len);
 }
-DEFINE_CCW_MACHINE_AS_LATEST(10, 1);
+DEFINE_CCW_MACHINE(10, 1);
 
 static void ccw_machine_10_0_instance_options(MachineState *machine)
 {
diff --git a/include/hw/boards.h b/include/hw/boards.h
index f94713e6e2..665b620121 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -779,6 +779,9 @@ struct MachineState {
     } \
     type_init(machine_initfn##_register_types)
 
+extern GlobalProperty hw_compat_10_1[];
+extern const size_t hw_compat_10_1_len;
+
 extern GlobalProperty hw_compat_10_0[];
 extern const size_t hw_compat_10_0_len;
 
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 79b72c54dd..e83157ab35 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -214,6 +214,9 @@ void pc_system_parse_ovmf_flash(uint8_t *flash_ptr, size_t flash_size);
 /* sgx.c */
 void pc_machine_init_sgx_epc(PCMachineState *pcms);
 
+extern GlobalProperty pc_compat_10_1[];
+extern const size_t pc_compat_10_1_len;
+
 extern GlobalProperty pc_compat_10_0[];
 extern const size_t pc_compat_10_0_len;
 
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
new file mode 100644
index 0000000000..04846c6eb1
--- /dev/null
+++ b/tests/functional/aarch64/meson.build
@@ -0,0 +1,48 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_aarch64_timeouts = {
+  'aspeed_ast2700' : 600,
+  'aspeed_ast2700fc' : 600,
+  'device_passthrough' : 720,
+  'imx8mp_evk' : 240,
+  'raspi4' : 480,
+  'reverse_debug' : 180,
+  'rme_virt' : 1200,
+  'rme_sbsaref' : 1200,
+  'sbsaref_alpine' : 1200,
+  'sbsaref_freebsd' : 720,
+  'smmu' : 720,
+  'tuxrun' : 240,
+  'virt' : 360,
+  'virt_gpu' : 480,
+}
+
+tests_aarch64_system_quick = [
+  'migration',
+]
+
+tests_aarch64_system_thorough = [
+  'aspeed_ast2700',
+  'aspeed_ast2700fc',
+  'device_passthrough',
+  'hotplug_pci',
+  'imx8mp_evk',
+  'kvm',
+  'multiprocess',
+  'raspi3',
+  'raspi4',
+  'replay',
+  'reverse_debug',
+  'rme_virt',
+  'rme_sbsaref',
+  'sbsaref',
+  'sbsaref_alpine',
+  'sbsaref_freebsd',
+  'smmu',
+  'tcg_plugins',
+  'tuxrun',
+  'virt',
+  'virt_gpu',
+  'xen',
+  'xlnx_versal',
+]
diff --git a/tests/functional/test_aarch64_aspeed_ast2700.py b/tests/functional/aarch64/test_aspeed_ast2700.py
index d02dc7991c..d02dc7991c 100755
--- a/tests/functional/test_aarch64_aspeed_ast2700.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700.py
diff --git a/tests/functional/test_aarch64_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py
index b85370e182..b85370e182 100755
--- a/tests/functional/test_aarch64_aspeed_ast2700fc.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py
diff --git a/tests/functional/test_aarch64_device_passthrough.py b/tests/functional/aarch64/test_device_passthrough.py
index 1f3f158a9f..1f3f158a9f 100755
--- a/tests/functional/test_aarch64_device_passthrough.py
+++ b/tests/functional/aarch64/test_device_passthrough.py
diff --git a/tests/functional/test_aarch64_hotplug_pci.py b/tests/functional/aarch64/test_hotplug_pci.py
index 0c67991b89..0c67991b89 100755
--- a/tests/functional/test_aarch64_hotplug_pci.py
+++ b/tests/functional/aarch64/test_hotplug_pci.py
diff --git a/tests/functional/test_aarch64_imx8mp_evk.py b/tests/functional/aarch64/test_imx8mp_evk.py
index 99ddcdef83..99ddcdef83 100755
--- a/tests/functional/test_aarch64_imx8mp_evk.py
+++ b/tests/functional/aarch64/test_imx8mp_evk.py
diff --git a/tests/functional/test_aarch64_kvm.py b/tests/functional/aarch64/test_kvm.py
index 9fb9286139..9fb9286139 100755
--- a/tests/functional/test_aarch64_kvm.py
+++ b/tests/functional/aarch64/test_kvm.py
diff --git a/tests/functional/aarch64/test_migration.py b/tests/functional/aarch64/test_migration.py
new file mode 100755
index 0000000000..70267e756d
--- /dev/null
+++ b/tests/functional/aarch64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# aarch64 migration test
+
+from migration import MigrationTest
+
+
+class Aarch64MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('quanta-gsj')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('quanta-gsj')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('quanta-gsj')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/aarch64/test_multiprocess.py b/tests/functional/aarch64/test_multiprocess.py
new file mode 100755
index 0000000000..1c6e45ecb6
--- /dev/null
+++ b/tests/functional/aarch64/test_multiprocess.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Test for multiprocess qemu on aarch64
+
+from multiprocess import Multiprocess
+from qemu_test import Asset
+
+
+class Aarch64Multiprocess(Multiprocess):
+
+    ASSET_KERNEL_AARCH64 = Asset(
+        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+         '/releases/31/Everything/aarch64/os/images/pxeboot/vmlinuz'),
+        '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
+
+    ASSET_INITRD_AARCH64 = Asset(
+        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+         '/releases/31/Everything/aarch64/os/images/pxeboot/initrd.img'),
+        '9fd230cab10b1dafea41cf00150e6669d37051fad133bd618d2130284e16d526')
+
+    def test_multiprocess(self):
+        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+                               'rdinit=/bin/bash console=ttyAMA0')
+        self.do_test(self.ASSET_KERNEL_AARCH64, self.ASSET_INITRD_AARCH64,
+                     kernel_command_line, 'virt,gic-version=3')
+
+
+if __name__ == '__main__':
+    Multiprocess.main()
diff --git a/tests/functional/test_aarch64_raspi3.py b/tests/functional/aarch64/test_raspi3.py
index 74f6630ed2..74f6630ed2 100755
--- a/tests/functional/test_aarch64_raspi3.py
+++ b/tests/functional/aarch64/test_raspi3.py
diff --git a/tests/functional/test_aarch64_raspi4.py b/tests/functional/aarch64/test_raspi4.py
index 7a4302b0c5..7a4302b0c5 100755
--- a/tests/functional/test_aarch64_raspi4.py
+++ b/tests/functional/aarch64/test_raspi4.py
diff --git a/tests/functional/test_aarch64_replay.py b/tests/functional/aarch64/test_replay.py
index db12e76603..db12e76603 100755
--- a/tests/functional/test_aarch64_replay.py
+++ b/tests/functional/aarch64/test_replay.py
diff --git a/tests/functional/test_aarch64_reverse_debug.py b/tests/functional/aarch64/test_reverse_debug.py
index 58d4532835..8bc91ccfde 100755
--- a/tests/functional/test_aarch64_reverse_debug.py
+++ b/tests/functional/aarch64/test_reverse_debug.py
@@ -21,7 +21,7 @@ class ReverseDebugging_AArch64(ReverseDebugging):
 
     REG_PC = 32
 
-    KERNEL_ASSET = Asset(
+    ASSET_KERNEL = Asset(
         ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
          'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
         '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
@@ -30,7 +30,7 @@ class ReverseDebugging_AArch64(ReverseDebugging):
     def test_aarch64_virt(self):
         self.set_machine('virt')
         self.cpu = 'cortex-a53'
-        kernel_path = self.KERNEL_ASSET.fetch()
+        kernel_path = self.ASSET_KERNEL.fetch()
         self.reverse_debugging(args=('-kernel', kernel_path))
 
 
diff --git a/tests/functional/test_aarch64_rme_sbsaref.py b/tests/functional/aarch64/test_rme_sbsaref.py
index 746770e776..100f1c7738 100755
--- a/tests/functional/test_aarch64_rme_sbsaref.py
+++ b/tests/functional/aarch64/test_rme_sbsaref.py
@@ -13,7 +13,7 @@ import os
 
 from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
 from qemu_test import exec_command_and_wait_for_pattern
-from test_aarch64_rme_virt import test_realms_guest
+from test_rme_virt import test_realms_guest
 
 
 class Aarch64RMESbsaRefMachine(QemuSystemTest):
diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/aarch64/test_rme_virt.py
index 8452d27928..8452d27928 100755
--- a/tests/functional/test_aarch64_rme_virt.py
+++ b/tests/functional/aarch64/test_rme_virt.py
diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/aarch64/test_sbsaref.py
index d3402f5080..d3402f5080 100755
--- a/tests/functional/test_aarch64_sbsaref.py
+++ b/tests/functional/aarch64/test_sbsaref.py
diff --git a/tests/functional/test_aarch64_sbsaref_alpine.py b/tests/functional/aarch64/test_sbsaref_alpine.py
index 8776999383..abb8f5114b 100755
--- a/tests/functional/test_aarch64_sbsaref_alpine.py
+++ b/tests/functional/aarch64/test_sbsaref_alpine.py
@@ -12,7 +12,7 @@
 
 from qemu_test import QemuSystemTest, Asset, skipSlowTest
 from qemu_test import wait_for_console_pattern
-from test_aarch64_sbsaref import fetch_firmware
+from test_sbsaref import fetch_firmware
 
 
 class Aarch64SbsarefAlpine(QemuSystemTest):
diff --git a/tests/functional/test_aarch64_sbsaref_freebsd.py b/tests/functional/aarch64/test_sbsaref_freebsd.py
index 7ef016fba6..3b942f7795 100755
--- a/tests/functional/test_aarch64_sbsaref_freebsd.py
+++ b/tests/functional/aarch64/test_sbsaref_freebsd.py
@@ -12,7 +12,7 @@
 
 from qemu_test import QemuSystemTest, Asset, skipSlowTest
 from qemu_test import wait_for_console_pattern
-from test_aarch64_sbsaref import fetch_firmware
+from test_sbsaref import fetch_firmware
 
 
 class Aarch64SbsarefFreeBSD(QemuSystemTest):
diff --git a/tests/functional/test_aarch64_smmu.py b/tests/functional/aarch64/test_smmu.py
index e0f4a92217..e0f4a92217 100755
--- a/tests/functional/test_aarch64_smmu.py
+++ b/tests/functional/aarch64/test_smmu.py
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/aarch64/test_tcg_plugins.py
index cb7e9298fb..cb7e9298fb 100755
--- a/tests/functional/test_aarch64_tcg_plugins.py
+++ b/tests/functional/aarch64/test_tcg_plugins.py
diff --git a/tests/functional/test_aarch64_tuxrun.py b/tests/functional/aarch64/test_tuxrun.py
index 75adc8acb8..75adc8acb8 100755
--- a/tests/functional/test_aarch64_tuxrun.py
+++ b/tests/functional/aarch64/test_tuxrun.py
diff --git a/tests/functional/test_aarch64_virt.py b/tests/functional/aarch64/test_virt.py
index 4d0ad90ff8..4d0ad90ff8 100755
--- a/tests/functional/test_aarch64_virt.py
+++ b/tests/functional/aarch64/test_virt.py
diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/aarch64/test_virt_gpu.py
index 3844727857..4e50887c3e 100755
--- a/tests/functional/test_aarch64_virt_gpu.py
+++ b/tests/functional/aarch64/test_virt_gpu.py
@@ -76,6 +76,8 @@ class Aarch64VirtGPUMachine(LinuxKernelTest):
                 self.skipTest("egl-headless support is not available")
             elif "'type' does not accept value 'dbus'" in excp.output:
                 self.skipTest("dbus display support is not available")
+            elif "eglInitialize failed: EGL_NOT_INITIALIZED" in excp.output:
+                self.skipTest("EGL failed to initialize on this host")
             else:
                 self.log.info("unhandled launch failure: %s", excp.output)
                 raise excp
diff --git a/tests/functional/test_aarch64_xen.py b/tests/functional/aarch64/test_xen.py
index 261d796540..261d796540 100755
--- a/tests/functional/test_aarch64_xen.py
+++ b/tests/functional/aarch64/test_xen.py
diff --git a/tests/functional/test_aarch64_xlnx_versal.py b/tests/functional/aarch64/test_xlnx_versal.py
index 4b9c49e5d6..4b9c49e5d6 100755
--- a/tests/functional/test_aarch64_xlnx_versal.py
+++ b/tests/functional/aarch64/test_xlnx_versal.py
diff --git a/tests/functional/alpha/meson.build b/tests/functional/alpha/meson.build
new file mode 100644
index 0000000000..26a5b3f2e4
--- /dev/null
+++ b/tests/functional/alpha/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_alpha_system_quick = [
+  'migration',
+]
+
+tests_alpha_system_thorough = [
+  'clipper',
+  'replay',
+]
diff --git a/tests/functional/test_alpha_clipper.py b/tests/functional/alpha/test_clipper.py
index c5d7181953..c5d7181953 100755
--- a/tests/functional/test_alpha_clipper.py
+++ b/tests/functional/alpha/test_clipper.py
diff --git a/tests/functional/alpha/test_migration.py b/tests/functional/alpha/test_migration.py
new file mode 100755
index 0000000000..f11b523ec9
--- /dev/null
+++ b/tests/functional/alpha/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Alpha migration test
+
+from migration import MigrationTest
+
+
+class AlphaMigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('clipper')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('clipper')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('clipper')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_alpha_replay.py b/tests/functional/alpha/test_replay.py
index 24a17ef590..24a17ef590 100755
--- a/tests/functional/test_alpha_replay.py
+++ b/tests/functional/alpha/test_replay.py
diff --git a/tests/functional/arm/meson.build b/tests/functional/arm/meson.build
new file mode 100644
index 0000000000..e4e7dba8d0
--- /dev/null
+++ b/tests/functional/arm/meson.build
@@ -0,0 +1,62 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_arm_timeouts = {
+  'aspeed_palmetto' : 120,
+  'aspeed_romulus' : 120,
+  'aspeed_witherspoon' : 120,
+  'aspeed_ast2500' : 720,
+  'aspeed_ast2600' : 1200,
+  'aspeed_bletchley' : 480,
+  'aspeed_catalina' : 480,
+  'aspeed_gb200nvl_bmc' : 480,
+  'aspeed_rainier' : 480,
+  'bpim2u' : 500,
+  'collie' : 180,
+  'cubieboard' : 360,
+  'orangepi' : 540,
+  'quanta_gsj' : 240,
+  'raspi2' : 120,
+  'replay' : 240,
+  'tuxrun' : 240,
+  'sx1' : 360,
+}
+
+tests_arm_system_quick = [
+  'migration',
+]
+
+tests_arm_system_thorough = [
+  'aspeed_ast1030',
+  'aspeed_palmetto',
+  'aspeed_romulus',
+  'aspeed_witherspoon',
+  'aspeed_ast2500',
+  'aspeed_ast2600',
+  'aspeed_bletchley',
+  'aspeed_catalina',
+  'aspeed_gb200nvl_bmc',
+  'aspeed_rainier',
+  'bpim2u',
+  'canona1100',
+  'collie',
+  'cubieboard',
+  'emcraft_sf2',
+  'integratorcp',
+  'max78000fthr',
+  'microbit',
+  'orangepi',
+  'quanta_gsj',
+  'raspi2',
+  'realview',
+  'replay',
+  'smdkc210',
+  'stellaris',
+  'sx1',
+  'vexpress',
+  'virt',
+  'tuxrun',
+]
+
+tests_arm_linuxuser_thorough = [
+  'bflt',
+]
diff --git a/tests/functional/test_arm_aspeed_ast1030.py b/tests/functional/arm/test_aspeed_ast1030.py
index 77037f0179..77037f0179 100755
--- a/tests/functional/test_arm_aspeed_ast1030.py
+++ b/tests/functional/arm/test_aspeed_ast1030.py
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/arm/test_aspeed_ast2500.py
index 6923fe8701..6923fe8701 100755
--- a/tests/functional/test_arm_aspeed_ast2500.py
+++ b/tests/functional/arm/test_aspeed_ast2500.py
diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/arm/test_aspeed_ast2600.py
index fdae4c939d..fdae4c939d 100755
--- a/tests/functional/test_arm_aspeed_ast2600.py
+++ b/tests/functional/arm/test_aspeed_ast2600.py
diff --git a/tests/functional/test_arm_aspeed_bletchley.py b/tests/functional/arm/test_aspeed_bletchley.py
index 5a60b24b3d..5a60b24b3d 100644..100755
--- a/tests/functional/test_arm_aspeed_bletchley.py
+++ b/tests/functional/arm/test_aspeed_bletchley.py
diff --git a/tests/functional/test_arm_aspeed_catalina.py b/tests/functional/arm/test_aspeed_catalina.py
index dc2f24e7b4..dc2f24e7b4 100755
--- a/tests/functional/test_arm_aspeed_catalina.py
+++ b/tests/functional/arm/test_aspeed_catalina.py
diff --git a/tests/functional/test_arm_aspeed_gb200nvl_bmc.py b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
index 8e8e3f05c1..8e8e3f05c1 100644..100755
--- a/tests/functional/test_arm_aspeed_gb200nvl_bmc.py
+++ b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/arm/test_aspeed_palmetto.py
index ff0b821be6..ff0b821be6 100755
--- a/tests/functional/test_arm_aspeed_palmetto.py
+++ b/tests/functional/arm/test_aspeed_palmetto.py
diff --git a/tests/functional/test_arm_aspeed_rainier.py b/tests/functional/arm/test_aspeed_rainier.py
index 602d6194ac..602d6194ac 100755
--- a/tests/functional/test_arm_aspeed_rainier.py
+++ b/tests/functional/arm/test_aspeed_rainier.py
diff --git a/tests/functional/test_arm_aspeed_romulus.py b/tests/functional/arm/test_aspeed_romulus.py
index 0447212bbf..0447212bbf 100755
--- a/tests/functional/test_arm_aspeed_romulus.py
+++ b/tests/functional/arm/test_aspeed_romulus.py
diff --git a/tests/functional/test_arm_aspeed_witherspoon.py b/tests/functional/arm/test_aspeed_witherspoon.py
index 51a2d47af2..51a2d47af2 100644..100755
--- a/tests/functional/test_arm_aspeed_witherspoon.py
+++ b/tests/functional/arm/test_aspeed_witherspoon.py
diff --git a/tests/functional/test_arm_bflt.py b/tests/functional/arm/test_bflt.py
index f273fc8354..f273fc8354 100755
--- a/tests/functional/test_arm_bflt.py
+++ b/tests/functional/arm/test_bflt.py
diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/arm/test_bpim2u.py
index 8bed64b702..8bed64b702 100755
--- a/tests/functional/test_arm_bpim2u.py
+++ b/tests/functional/arm/test_bpim2u.py
diff --git a/tests/functional/test_arm_canona1100.py b/tests/functional/arm/test_canona1100.py
index 21a1a596a0..21a1a596a0 100755
--- a/tests/functional/test_arm_canona1100.py
+++ b/tests/functional/arm/test_canona1100.py
diff --git a/tests/functional/test_arm_collie.py b/tests/functional/arm/test_collie.py
index fe1be3d079..fe1be3d079 100755
--- a/tests/functional/test_arm_collie.py
+++ b/tests/functional/arm/test_collie.py
diff --git a/tests/functional/test_arm_cubieboard.py b/tests/functional/arm/test_cubieboard.py
index b536c2f77a..b536c2f77a 100755
--- a/tests/functional/test_arm_cubieboard.py
+++ b/tests/functional/arm/test_cubieboard.py
diff --git a/tests/functional/test_arm_emcraft_sf2.py b/tests/functional/arm/test_emcraft_sf2.py
index f9f3f069e2..f9f3f069e2 100755
--- a/tests/functional/test_arm_emcraft_sf2.py
+++ b/tests/functional/arm/test_emcraft_sf2.py
diff --git a/tests/functional/test_arm_integratorcp.py b/tests/functional/arm/test_integratorcp.py
index 4f00924aa0..4f00924aa0 100755
--- a/tests/functional/test_arm_integratorcp.py
+++ b/tests/functional/arm/test_integratorcp.py
diff --git a/tests/functional/test_arm_max78000fthr.py b/tests/functional/arm/test_max78000fthr.py
index a82980b0f7..a82980b0f7 100755
--- a/tests/functional/test_arm_max78000fthr.py
+++ b/tests/functional/arm/test_max78000fthr.py
diff --git a/tests/functional/test_arm_microbit.py b/tests/functional/arm/test_microbit.py
index 68ea4e73d6..68ea4e73d6 100755
--- a/tests/functional/test_arm_microbit.py
+++ b/tests/functional/arm/test_microbit.py
diff --git a/tests/functional/arm/test_migration.py b/tests/functional/arm/test_migration.py
new file mode 100755
index 0000000000..0aa89f4f61
--- /dev/null
+++ b/tests/functional/arm/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# arm migration test
+
+from migration import MigrationTest
+
+
+class ArmMigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('npcm750-evb')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('npcm750-evb')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('npcm750-evb')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_arm_orangepi.py b/tests/functional/arm/test_orangepi.py
index f9bfa8c78d..f9bfa8c78d 100755
--- a/tests/functional/test_arm_orangepi.py
+++ b/tests/functional/arm/test_orangepi.py
diff --git a/tests/functional/test_arm_quanta_gsj.py b/tests/functional/arm/test_quanta_gsj.py
index cb0545f7bf..cb0545f7bf 100755
--- a/tests/functional/test_arm_quanta_gsj.py
+++ b/tests/functional/arm/test_quanta_gsj.py
diff --git a/tests/functional/test_arm_raspi2.py b/tests/functional/arm/test_raspi2.py
index d3c7aaa39b..d3c7aaa39b 100755
--- a/tests/functional/test_arm_raspi2.py
+++ b/tests/functional/arm/test_raspi2.py
diff --git a/tests/functional/test_arm_realview.py b/tests/functional/arm/test_realview.py
index 82cc964333..82cc964333 100755
--- a/tests/functional/test_arm_realview.py
+++ b/tests/functional/arm/test_realview.py
diff --git a/tests/functional/test_arm_replay.py b/tests/functional/arm/test_replay.py
index e002e6a264..e002e6a264 100755
--- a/tests/functional/test_arm_replay.py
+++ b/tests/functional/arm/test_replay.py
diff --git a/tests/functional/test_arm_smdkc210.py b/tests/functional/arm/test_smdkc210.py
index 3154e7f732..3154e7f732 100755
--- a/tests/functional/test_arm_smdkc210.py
+++ b/tests/functional/arm/test_smdkc210.py
diff --git a/tests/functional/test_arm_stellaris.py b/tests/functional/arm/test_stellaris.py
index cbd21cb1a0..cbd21cb1a0 100755
--- a/tests/functional/test_arm_stellaris.py
+++ b/tests/functional/arm/test_stellaris.py
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/arm/test_sx1.py
index 25800b388c..25800b388c 100755
--- a/tests/functional/test_arm_sx1.py
+++ b/tests/functional/arm/test_sx1.py
diff --git a/tests/functional/test_arm_tuxrun.py b/tests/functional/arm/test_tuxrun.py
index 4ac85f48ac..4ac85f48ac 100755
--- a/tests/functional/test_arm_tuxrun.py
+++ b/tests/functional/arm/test_tuxrun.py
diff --git a/tests/functional/test_arm_vexpress.py b/tests/functional/arm/test_vexpress.py
index 6b11552894..6b11552894 100755
--- a/tests/functional/test_arm_vexpress.py
+++ b/tests/functional/arm/test_vexpress.py
diff --git a/tests/functional/test_arm_virt.py b/tests/functional/arm/test_virt.py
index 7b6549176f..7b6549176f 100755
--- a/tests/functional/test_arm_virt.py
+++ b/tests/functional/arm/test_virt.py
diff --git a/tests/functional/avr/meson.build b/tests/functional/avr/meson.build
new file mode 100644
index 0000000000..7a2cb7099e
--- /dev/null
+++ b/tests/functional/avr/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_avr_system_thorough = [
+  'mega2560',
+  'uno',
+]
diff --git a/tests/functional/test_avr_mega2560.py b/tests/functional/avr/test_mega2560.py
index 6359b72af3..6359b72af3 100755
--- a/tests/functional/test_avr_mega2560.py
+++ b/tests/functional/avr/test_mega2560.py
diff --git a/tests/functional/test_avr_uno.py b/tests/functional/avr/test_uno.py
index adb3b73da4..adb3b73da4 100755
--- a/tests/functional/test_avr_uno.py
+++ b/tests/functional/avr/test_uno.py
diff --git a/tests/functional/generic/meson.build b/tests/functional/generic/meson.build
new file mode 100644
index 0000000000..013cc96fbf
--- /dev/null
+++ b/tests/functional/generic/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_generic_system = [
+  'empty_cpu_model',
+  'info_usernet',
+  'version',
+  'vnc',
+]
+
+tests_generic_linuxuser = [
+]
+
+tests_generic_bsduser = [
+]
diff --git a/tests/functional/test_empty_cpu_model.py b/tests/functional/generic/test_empty_cpu_model.py
index 0081b06d85..0081b06d85 100755
--- a/tests/functional/test_empty_cpu_model.py
+++ b/tests/functional/generic/test_empty_cpu_model.py
diff --git a/tests/functional/test_info_usernet.py b/tests/functional/generic/test_info_usernet.py
index e8cbc37eed..e8cbc37eed 100755
--- a/tests/functional/test_info_usernet.py
+++ b/tests/functional/generic/test_info_usernet.py
diff --git a/tests/functional/test_version.py b/tests/functional/generic/test_version.py
index 3ab3b67f7e..3ab3b67f7e 100755
--- a/tests/functional/test_version.py
+++ b/tests/functional/generic/test_version.py
diff --git a/tests/functional/test_vnc.py b/tests/functional/generic/test_vnc.py
index f1dd1597cf..f1dd1597cf 100755
--- a/tests/functional/test_vnc.py
+++ b/tests/functional/generic/test_vnc.py
diff --git a/tests/functional/hppa/meson.build b/tests/functional/hppa/meson.build
new file mode 100644
index 0000000000..a334837088
--- /dev/null
+++ b/tests/functional/hppa/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_hppa_system_quick = [
+  'seabios',
+]
diff --git a/tests/functional/test_hppa_seabios.py b/tests/functional/hppa/test_seabios.py
index 661b2464e1..661b2464e1 100755
--- a/tests/functional/test_hppa_seabios.py
+++ b/tests/functional/hppa/test_seabios.py
diff --git a/tests/functional/i386/meson.build b/tests/functional/i386/meson.build
new file mode 100644
index 0000000000..23d8c216be
--- /dev/null
+++ b/tests/functional/i386/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_i386_system_quick = [
+  'migration',
+]
+
+tests_i386_system_thorough = [
+  'replay',
+  'tuxrun',
+]
diff --git a/tests/functional/i386/test_migration.py b/tests/functional/i386/test_migration.py
new file mode 100755
index 0000000000..a57f316404
--- /dev/null
+++ b/tests/functional/i386/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# i386 migration test
+
+from migration import MigrationTest
+
+
+class I386MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('isapc')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('isapc')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('isapc')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_i386_replay.py b/tests/functional/i386/test_replay.py
index 7c4c2602da..7c4c2602da 100755
--- a/tests/functional/test_i386_replay.py
+++ b/tests/functional/i386/test_replay.py
diff --git a/tests/functional/test_i386_tuxrun.py b/tests/functional/i386/test_tuxrun.py
index f3ccf11ae8..f3ccf11ae8 100755
--- a/tests/functional/test_i386_tuxrun.py
+++ b/tests/functional/i386/test_tuxrun.py
diff --git a/tests/functional/loongarch64/meson.build b/tests/functional/loongarch64/meson.build
new file mode 100644
index 0000000000..d1687176a3
--- /dev/null
+++ b/tests/functional/loongarch64/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_loongarch64_system_thorough = [
+  'virt',
+]
diff --git a/tests/functional/test_loongarch64_virt.py b/tests/functional/loongarch64/test_virt.py
index b7d9abf933..b7d9abf933 100755
--- a/tests/functional/test_loongarch64_virt.py
+++ b/tests/functional/loongarch64/test_virt.py
diff --git a/tests/functional/m68k/meson.build b/tests/functional/m68k/meson.build
new file mode 100644
index 0000000000..e29044a6d7
--- /dev/null
+++ b/tests/functional/m68k/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_m68k_system_thorough = [
+  'mcf5208evb',
+  'nextcube',
+  'replay',
+  'q800',
+  'tuxrun',
+]
diff --git a/tests/functional/test_m68k_mcf5208evb.py b/tests/functional/m68k/test_mcf5208evb.py
index c7d1998933..c7d1998933 100755
--- a/tests/functional/test_m68k_mcf5208evb.py
+++ b/tests/functional/m68k/test_mcf5208evb.py
diff --git a/tests/functional/test_m68k_nextcube.py b/tests/functional/m68k/test_nextcube.py
index 13c72bd136..13c72bd136 100755
--- a/tests/functional/test_m68k_nextcube.py
+++ b/tests/functional/m68k/test_nextcube.py
diff --git a/tests/functional/test_m68k_q800.py b/tests/functional/m68k/test_q800.py
index b3e655346c..b3e655346c 100755
--- a/tests/functional/test_m68k_q800.py
+++ b/tests/functional/m68k/test_q800.py
diff --git a/tests/functional/test_m68k_replay.py b/tests/functional/m68k/test_replay.py
index 213d6ae07e..213d6ae07e 100755
--- a/tests/functional/test_m68k_replay.py
+++ b/tests/functional/m68k/test_replay.py
diff --git a/tests/functional/test_m68k_tuxrun.py b/tests/functional/m68k/test_tuxrun.py
index 7eacba135f..7eacba135f 100755
--- a/tests/functional/test_m68k_tuxrun.py
+++ b/tests/functional/m68k/test_tuxrun.py
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 311c6f1806..2a0c5aa141 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -9,345 +9,34 @@ if get_option('tcg_interpreter')
   subdir_done()
 endif
 
-# Timeouts for individual tests that can be slow e.g. with debugging enabled
-test_timeouts = {
-  'aarch64_aspeed_ast2700' : 600,
-  'aarch64_aspeed_ast2700fc' : 600,
-  'aarch64_device_passthrough' : 720,
-  'aarch64_imx8mp_evk' : 240,
-  'aarch64_raspi4' : 480,
-  'aarch64_reverse_debug' : 180,
-  'aarch64_rme_virt' : 1200,
-  'aarch64_rme_sbsaref' : 1200,
-  'aarch64_sbsaref_alpine' : 1200,
-  'aarch64_sbsaref_freebsd' : 720,
-  'aarch64_smmu' : 720,
-  'aarch64_tuxrun' : 240,
-  'aarch64_virt' : 360,
-  'aarch64_virt_gpu' : 480,
-  'acpi_bits' : 420,
-  'arm_aspeed_palmetto' : 120,
-  'arm_aspeed_romulus' : 120,
-  'arm_aspeed_witherspoon' : 120,
-  'arm_aspeed_ast2500' : 720,
-  'arm_aspeed_ast2600' : 1200,
-  'arm_aspeed_bletchley' : 480,
-  'arm_aspeed_catalina' : 480,
-  'arm_aspeed_gb200nvl_bmc' : 480,
-  'arm_aspeed_rainier' : 480,
-  'arm_bpim2u' : 500,
-  'arm_collie' : 180,
-  'arm_cubieboard' : 360,
-  'arm_orangepi' : 540,
-  'arm_quanta_gsj' : 240,
-  'arm_raspi2' : 120,
-  'arm_replay' : 240,
-  'arm_tuxrun' : 240,
-  'arm_sx1' : 360,
-  'intel_iommu': 300,
-  'mips_malta' : 480,
-  'mipsel_malta' : 420,
-  'mipsel_replay' : 480,
-  'mips64_malta' : 240,
-  'mips64el_malta' : 420,
-  'mips64el_replay' : 180,
-  'netdev_ethtool' : 180,
-  'ppc_40p' : 240,
-  'ppc64_hv' : 1000,
-  'ppc64_powernv' : 480,
-  'ppc64_pseries' : 480,
-  'ppc64_replay' : 210,
-  'ppc64_tuxrun' : 420,
-  'ppc64_mac99' : 120,
-  'riscv64_tuxrun' : 120,
-  's390x_ccw_virtio' : 420,
-  'sh4_tuxrun' : 240,
-  'virtio_balloon': 120,
-  'x86_64_kvm_xen' : 180,
-  'x86_64_replay' : 480,
-}
-
-tests_generic_system = [
-  'empty_cpu_model',
-  'info_usernet',
-  'version',
-]
-
-tests_generic_linuxuser = [
-]
-
-tests_generic_bsduser = [
-]
-
-tests_aarch64_system_quick = [
-  'migration',
-]
-
-tests_aarch64_system_thorough = [
-  'aarch64_aspeed_ast2700',
-  'aarch64_aspeed_ast2700fc',
-  'aarch64_device_passthrough',
-  'aarch64_hotplug_pci',
-  'aarch64_imx8mp_evk',
-  'aarch64_kvm',
-  'aarch64_raspi3',
-  'aarch64_raspi4',
-  'aarch64_replay',
-  'aarch64_reverse_debug',
-  'aarch64_rme_virt',
-  'aarch64_rme_sbsaref',
-  'aarch64_sbsaref',
-  'aarch64_sbsaref_alpine',
-  'aarch64_sbsaref_freebsd',
-  'aarch64_smmu',
-  'aarch64_tcg_plugins',
-  'aarch64_tuxrun',
-  'aarch64_virt',
-  'aarch64_virt_gpu',
-  'aarch64_xen',
-  'aarch64_xlnx_versal',
-  'multiprocess',
-]
-
-tests_alpha_system_quick = [
-  'migration',
-]
-
-tests_alpha_system_thorough = [
-  'alpha_clipper',
-  'alpha_replay',
-]
-
-tests_arm_system_quick = [
-  'migration',
-]
-
-tests_arm_system_thorough = [
-  'arm_aspeed_ast1030',
-  'arm_aspeed_palmetto',
-  'arm_aspeed_romulus',
-  'arm_aspeed_witherspoon',
-  'arm_aspeed_ast2500',
-  'arm_aspeed_ast2600',
-  'arm_aspeed_bletchley',
-  'arm_aspeed_catalina',
-  'arm_aspeed_gb200nvl_bmc',
-  'arm_aspeed_rainier',
-  'arm_bpim2u',
-  'arm_canona1100',
-  'arm_collie',
-  'arm_cubieboard',
-  'arm_emcraft_sf2',
-  'arm_integratorcp',
-  'arm_max78000fthr',
-  'arm_microbit',
-  'arm_orangepi',
-  'arm_quanta_gsj',
-  'arm_raspi2',
-  'arm_realview',
-  'arm_replay',
-  'arm_smdkc210',
-  'arm_stellaris',
-  'arm_sx1',
-  'arm_vexpress',
-  'arm_virt',
-  'arm_tuxrun',
-]
-
-tests_arm_linuxuser_thorough = [
-  'arm_bflt',
-]
-
-tests_avr_system_thorough = [
-  'avr_mega2560',
-  'avr_uno',
-]
-
-tests_hppa_system_quick = [
-  'hppa_seabios',
-]
-
-tests_i386_system_quick = [
-  'migration',
-]
-
-tests_i386_system_thorough = [
-  'i386_replay',
-  'i386_tuxrun',
-]
-
-tests_loongarch64_system_thorough = [
-  'loongarch64_virt',
-]
-
-tests_m68k_system_thorough = [
-  'm68k_mcf5208evb',
-  'm68k_nextcube',
-  'm68k_replay',
-  'm68k_q800',
-  'm68k_tuxrun',
-]
-
-tests_microblaze_system_thorough = [
-  'microblaze_replay',
-  'microblaze_s3adsp1800'
-]
-
-tests_microblazeel_system_thorough = [
-  'microblazeel_s3adsp1800'
-]
-
-tests_mips_system_thorough = [
-  'mips_malta',
-  'mips_replay',
-  'mips_tuxrun',
-]
-
-tests_mipsel_system_thorough = [
-  'mipsel_malta',
-  'mipsel_replay',
-  'mipsel_tuxrun',
-]
-
-tests_mips64_system_thorough = [
-  'mips64_malta',
-  'mips64_tuxrun',
-]
-
-tests_mips64el_system_thorough = [
-  'mips64el_fuloong2e',
-  'mips64el_loongson3v',
-  'mips64el_malta',
-  'mips64el_replay',
-  'mips64el_tuxrun',
-]
-
-tests_or1k_system_thorough = [
-  'or1k_replay',
-  'or1k_sim',
-]
-
-tests_ppc_system_quick = [
-  'migration',
-  'ppc_74xx',
-]
-
-tests_ppc_system_thorough = [
-  'ppc_40p',
-  'ppc_amiga',
-  'ppc_bamboo',
-  'ppc_mac',
-  'ppc_mpc8544ds',
-  'ppc_replay',
-  'ppc_sam460ex',
-  'ppc_tuxrun',
-  'ppc_virtex_ml507',
-]
-
-tests_ppc64_system_quick = [
-  'migration',
-]
-
-tests_ppc64_system_thorough = [
-  'ppc64_e500',
-  'ppc64_hv',
-  'ppc64_powernv',
-  'ppc64_pseries',
-  'ppc64_replay',
-  'ppc64_reverse_debug',
-  'ppc64_tuxrun',
-  'ppc64_mac99',
-]
-
-tests_riscv32_system_quick = [
-  'migration',
-  'riscv_opensbi',
-]
-
-tests_riscv32_system_thorough = [
-  'riscv32_tuxrun',
-]
-
-tests_riscv64_system_quick = [
-  'migration',
-  'riscv_opensbi',
-]
-
-tests_riscv64_system_thorough = [
-  'riscv64_sifive_u',
-  'riscv64_tuxrun',
-]
-
-tests_rx_system_thorough = [
-  'rx_gdbsim',
-]
-
-tests_s390x_system_thorough = [
-  's390x_ccw_virtio',
-  's390x_pxelinux',
-  's390x_replay',
-  's390x_topology',
-  's390x_tuxrun',
-]
-
-tests_sh4_system_thorough = [
-  'sh4_r2d',
-  'sh4_tuxrun',
-]
-
-tests_sh4eb_system_thorough = [
-  'sh4eb_r2d',
-]
-
-tests_sparc_system_quick = [
-  'migration',
-]
-
-tests_sparc_system_thorough = [
-  'sparc_replay',
-  'sparc_sun4m',
-]
-
-tests_sparc64_system_quick = [
-  'migration',
-]
-
-tests_sparc64_system_thorough = [
-  'sparc64_sun4u',
-  'sparc64_tuxrun',
-]
-
-tests_x86_64_system_quick = [
-  'cpu_queries',
-  'mem_addr_space',
-  'migration',
-  'pc_cpu_hotplug_props',
-  'virtio_version',
-  'x86_cpu_model_versions',
-  'vnc',
-  'memlock',
-]
-
-tests_x86_64_system_thorough = [
-  'acpi_bits',
-  'intel_iommu',
-  'linux_initrd',
-  'multiprocess',
-  'netdev_ethtool',
-  'virtio_balloon',
-  'virtio_gpu',
-  'x86_64_hotplug_blk',
-  'x86_64_hotplug_cpu',
-  'x86_64_kvm_xen',
-  'x86_64_replay',
-  'x86_64_reverse_debug',
-  'x86_64_tuxrun',
-]
-
-tests_xtensa_system_thorough = [
-  'xtensa_lx60',
-  'xtensa_replay',
-]
+subdir('aarch64')
+subdir('alpha')
+subdir('arm')
+subdir('avr')
+subdir('hppa')
+subdir('i386')
+subdir('loongarch64')
+subdir('m68k')
+subdir('microblaze')
+subdir('microblazeel')
+subdir('mips')
+subdir('mipsel')
+subdir('mips64')
+subdir('mips64el')
+subdir('or1k')
+subdir('ppc')
+subdir('ppc64')
+subdir('riscv32')
+subdir('riscv64')
+subdir('rx')
+subdir('s390x')
+subdir('sh4')
+subdir('sh4eb')
+subdir('sparc')
+subdir('sparc64')
+subdir('x86_64')
+subdir('xtensa')
+subdir('generic')
 
 precache_all = []
 foreach speed : ['quick', 'thorough']
@@ -390,7 +79,11 @@ foreach speed : ['quick', 'thorough']
 
     foreach test : target_tests
       testname = '@0@-@1@'.format(target_base, test)
-      testfile = 'test_' + test + '.py'
+      if fs.exists('generic' / 'test_' + test + '.py')
+        testfile = 'generic' / 'test_' + test + '.py'
+      else
+        testfile = target_base / 'test_' + test + '.py'
+      endif
       testpath = meson.current_source_dir() / testfile
       teststamp = testname + '.tstamp'
       test_precache_env = environment()
@@ -404,6 +97,11 @@ foreach speed : ['quick', 'thorough']
                                build_by_default: false,
                                env: test_precache_env)
       precache_all += precache
+      if is_variable('test_' + target_base + '_timeouts')
+        time_out = get_variable('test_' + target_base + '_timeouts').get(test, 90)
+      else
+        time_out = 90
+      endif
 
       # Ideally we would add 'precache' to 'depends' here, such that
       # 'build_by_default: false' lets the pre-caching automatically
@@ -419,8 +117,8 @@ foreach speed : ['quick', 'thorough']
            env: test_env,
            args: [testpath],
            protocol: 'tap',
-           timeout: test_timeouts.get(test, 90),
-           priority: test_timeouts.get(test, 90),
+           timeout: time_out,
+           priority: time_out,
            suite: suites)
     endforeach
   endforeach
diff --git a/tests/functional/microblaze/meson.build b/tests/functional/microblaze/meson.build
new file mode 100644
index 0000000000..8069ca9be6
--- /dev/null
+++ b/tests/functional/microblaze/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_microblaze_system_thorough = [
+  'replay',
+  's3adsp1800'
+]
diff --git a/tests/functional/test_microblaze_replay.py b/tests/functional/microblaze/test_replay.py
index 7484c4186f..7484c4186f 100755
--- a/tests/functional/test_microblaze_replay.py
+++ b/tests/functional/microblaze/test_replay.py
diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/microblaze/test_s3adsp1800.py
index f093b162c0..f093b162c0 100755
--- a/tests/functional/test_microblaze_s3adsp1800.py
+++ b/tests/functional/microblaze/test_s3adsp1800.py
diff --git a/tests/functional/microblazeel/meson.build b/tests/functional/microblazeel/meson.build
new file mode 100644
index 0000000000..27619dc5a9
--- /dev/null
+++ b/tests/functional/microblazeel/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_microblazeel_system_thorough = [
+  's3adsp1800'
+]
diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/microblazeel/test_s3adsp1800.py
index 915902d48b..75ce8856ed 100755
--- a/tests/functional/test_microblazeel_s3adsp1800.py
+++ b/tests/functional/microblazeel/test_s3adsp1800.py
@@ -7,7 +7,7 @@
 # This work is licensed under the terms of the GNU GPL, version 2 or
 # later. See the COPYING file in the top-level directory.
 
-from test_microblaze_s3adsp1800 import MicroblazeMachine
+from microblaze.test_s3adsp1800 import MicroblazeMachine
 
 
 class MicroblazeLittleEndianMachine(MicroblazeMachine):
diff --git a/tests/functional/test_migration.py b/tests/functional/migration.py
index c4393c3543..0739554483 100755..100644
--- a/tests/functional/test_migration.py
+++ b/tests/functional/migration.py
@@ -1,6 +1,6 @@
-#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
 #
-# Migration test
+# Migration test base class
 #
 # Copyright (c) 2019 Red Hat, Inc.
 #
@@ -14,7 +14,7 @@
 import tempfile
 import time
 
-from qemu_test import QemuSystemTest, skipIfMissingCommands
+from qemu_test import QemuSystemTest, which
 from qemu_test.ports import Ports
 
 
@@ -41,24 +41,7 @@ class MigrationTest(QemuSystemTest):
         self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
         self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
 
-    def select_machine(self):
-        target_machine = {
-            'aarch64': 'quanta-gsj',
-            'alpha': 'clipper',
-            'arm': 'npcm750-evb',
-            'i386': 'isapc',
-            'ppc': 'sam460ex',
-            'ppc64': 'mac99',
-            'riscv32': 'spike',
-            'riscv64': 'virt',
-            'sparc': 'SS-4',
-            'sparc64': 'sun4u',
-            'x86_64': 'microvm',
-        }
-        self.set_machine(target_machine[self.arch])
-
     def do_migrate(self, dest_uri, src_uri=None):
-        self.select_machine()
         dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu")
         dest_vm.add_args('-nodefaults')
         dest_vm.launch()
@@ -76,23 +59,21 @@ class MigrationTest(QemuSystemTest):
             self.skipTest('Failed to find a free port')
         return port
 
-    def test_migration_with_tcp_localhost(self):
+    def migration_with_tcp_localhost(self):
         with Ports() as ports:
             dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
             self.do_migrate(dest_uri)
 
-    def test_migration_with_unix(self):
+    def migration_with_unix(self):
         with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
             dest_uri = 'unix:%s/qemu-test.sock' % socket_path
             self.do_migrate(dest_uri)
 
-    @skipIfMissingCommands('ncat')
-    def test_migration_with_exec(self):
+    def migration_with_exec(self):
+        if not which('ncat'):
+            self.skipTest('ncat is not available')
         with Ports() as ports:
             free_port = self._get_free_port(ports)
             dest_uri = 'exec:ncat -l localhost %u' % free_port
             src_uri = 'exec:ncat localhost %u' % free_port
             self.do_migrate(dest_uri, src_uri)
-
-if __name__ == '__main__':
-    QemuSystemTest.main()
diff --git a/tests/functional/mips/meson.build b/tests/functional/mips/meson.build
new file mode 100644
index 0000000000..49aaf53b02
--- /dev/null
+++ b/tests/functional/mips/meson.build
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips_timeouts = {
+  'malta' : 480,
+}
+
+tests_mips_system_thorough = [
+  'malta',
+  'replay',
+  'tuxrun',
+]
diff --git a/tests/functional/test_mips_malta.py b/tests/functional/mips/test_malta.py
index 30279f0ff2..30279f0ff2 100755
--- a/tests/functional/test_mips_malta.py
+++ b/tests/functional/mips/test_malta.py
diff --git a/tests/functional/test_mips_replay.py b/tests/functional/mips/test_replay.py
index 4327481e35..4327481e35 100755
--- a/tests/functional/test_mips_replay.py
+++ b/tests/functional/mips/test_replay.py
diff --git a/tests/functional/test_mips_tuxrun.py b/tests/functional/mips/test_tuxrun.py
index 6771dbd57e..6771dbd57e 100755
--- a/tests/functional/test_mips_tuxrun.py
+++ b/tests/functional/mips/test_tuxrun.py
diff --git a/tests/functional/mips64/meson.build b/tests/functional/mips64/meson.build
new file mode 100644
index 0000000000..3ff2118987
--- /dev/null
+++ b/tests/functional/mips64/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips64_timeouts = {
+  'malta' : 240,
+}
+
+tests_mips64_system_thorough = [
+  'malta',
+  'tuxrun',
+]
diff --git a/tests/functional/test_mips64_malta.py b/tests/functional/mips64/test_malta.py
index 53c3e0c122..a553d3c5bc 100755
--- a/tests/functional/test_mips64_malta.py
+++ b/tests/functional/mips64/test_malta.py
@@ -5,7 +5,7 @@
 # SPDX-License-Identifier: GPL-2.0-or-later
 
 from qemu_test import LinuxKernelTest, Asset
-from test_mips_malta import mips_check_wheezy
+from mips.test_malta import mips_check_wheezy
 
 
 class MaltaMachineConsole(LinuxKernelTest):
diff --git a/tests/functional/test_mips64_tuxrun.py b/tests/functional/mips64/test_tuxrun.py
index 0e4c65961d..0e4c65961d 100755
--- a/tests/functional/test_mips64_tuxrun.py
+++ b/tests/functional/mips64/test_tuxrun.py
diff --git a/tests/functional/mips64el/meson.build b/tests/functional/mips64el/meson.build
new file mode 100644
index 0000000000..69ec50174c
--- /dev/null
+++ b/tests/functional/mips64el/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips64el_timeouts = {
+  'malta' : 420,
+  'replay' : 180,
+}
+
+tests_mips64el_system_thorough = [
+  'fuloong2e',
+  'loongson3v',
+  'malta',
+  'replay',
+  'tuxrun',
+]
diff --git a/tests/functional/test_mips64el_fuloong2e.py b/tests/functional/mips64el/test_fuloong2e.py
index 35e500b022..35e500b022 100755
--- a/tests/functional/test_mips64el_fuloong2e.py
+++ b/tests/functional/mips64el/test_fuloong2e.py
diff --git a/tests/functional/test_mips64el_loongson3v.py b/tests/functional/mips64el/test_loongson3v.py
index f85371e50c..f85371e50c 100755
--- a/tests/functional/test_mips64el_loongson3v.py
+++ b/tests/functional/mips64el/test_loongson3v.py
diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/mips64el/test_malta.py
index 3cc79b74c1..8fdc49b300 100755
--- a/tests/functional/test_mips64el_malta.py
+++ b/tests/functional/mips64el/test_malta.py
@@ -16,7 +16,7 @@ from qemu_test import LinuxKernelTest, Asset
 from qemu_test import exec_command_and_wait_for_pattern
 from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
 
-from test_mips_malta import mips_check_wheezy
+from mips.test_malta import mips_check_wheezy
 
 
 class MaltaMachineConsole(LinuxKernelTest):
@@ -191,7 +191,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
         self.do_test_i6400_framebuffer_logo(8)
 
 
-from test_mipsel_malta import MaltaMachineYAMON
+from mipsel.test_malta import MaltaMachineYAMON
 
 if __name__ == '__main__':
     LinuxKernelTest.main()
diff --git a/tests/functional/test_mips64el_replay.py b/tests/functional/mips64el/test_replay.py
index 26a6ccff3f..26a6ccff3f 100755
--- a/tests/functional/test_mips64el_replay.py
+++ b/tests/functional/mips64el/test_replay.py
diff --git a/tests/functional/test_mips64el_tuxrun.py b/tests/functional/mips64el/test_tuxrun.py
index 0a24757c51..0a24757c51 100755
--- a/tests/functional/test_mips64el_tuxrun.py
+++ b/tests/functional/mips64el/test_tuxrun.py
diff --git a/tests/functional/mipsel/meson.build b/tests/functional/mipsel/meson.build
new file mode 100644
index 0000000000..8bfdf0649b
--- /dev/null
+++ b/tests/functional/mipsel/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mipsel_timeouts = {
+  'malta' : 420,
+  'replay' : 480,
+}
+
+tests_mipsel_system_thorough = [
+  'malta',
+  'replay',
+  'tuxrun',
+]
diff --git a/tests/functional/test_mipsel_malta.py b/tests/functional/mipsel/test_malta.py
index 9ee2884da8..427e163d19 100755
--- a/tests/functional/test_mipsel_malta.py
+++ b/tests/functional/mipsel/test_malta.py
@@ -13,7 +13,7 @@ from qemu_test import QemuSystemTest, LinuxKernelTest, Asset
 from qemu_test import interrupt_interactive_console_until_pattern
 from qemu_test import wait_for_console_pattern
 
-from test_mips_malta import mips_check_wheezy
+from mips.test_malta import mips_check_wheezy
 
 
 class MaltaMachineConsole(LinuxKernelTest):
diff --git a/tests/functional/test_mipsel_replay.py b/tests/functional/mipsel/test_replay.py
index 5f4796cf89..5f4796cf89 100644..100755
--- a/tests/functional/test_mipsel_replay.py
+++ b/tests/functional/mipsel/test_replay.py
diff --git a/tests/functional/test_mipsel_tuxrun.py b/tests/functional/mipsel/test_tuxrun.py
index d4b39baab5..d4b39baab5 100755
--- a/tests/functional/test_mipsel_tuxrun.py
+++ b/tests/functional/mipsel/test_tuxrun.py
diff --git a/tests/functional/test_multiprocess.py b/tests/functional/multiprocess.py
index 92d5207b0e..6a06c1eda1 100755..100644
--- a/tests/functional/test_multiprocess.py
+++ b/tests/functional/multiprocess.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
 #
 # Test for multiprocess qemu
 #
@@ -9,33 +9,13 @@
 import os
 import socket
 
-from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+from qemu_test import QemuSystemTest, wait_for_console_pattern
 from qemu_test import exec_command, exec_command_and_wait_for_pattern
 
 class Multiprocess(QemuSystemTest):
 
     KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
 
-    ASSET_KERNEL_X86 = Asset(
-        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
-         '/releases/31/Everything/x86_64/os/images/pxeboot/vmlinuz'),
-        'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
-
-    ASSET_INITRD_X86 = Asset(
-        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
-         '/releases/31/Everything/x86_64/os/images/pxeboot/initrd.img'),
-        '3b6cb5c91a14c42e2f61520f1689264d865e772a1f0069e660a800d31dd61fb9')
-
-    ASSET_KERNEL_AARCH64 = Asset(
-        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
-         '/releases/31/Everything/aarch64/os/images/pxeboot/vmlinuz'),
-        '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
-
-    ASSET_INITRD_AARCH64 = Asset(
-        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
-         '/releases/31/Everything/aarch64/os/images/pxeboot/initrd.img'),
-        '9fd230cab10b1dafea41cf00150e6669d37051fad133bd618d2130284e16d526')
-
     def do_test(self, kernel_asset, initrd_asset,
                 kernel_command_line, machine_type):
         """Main test method"""
@@ -85,19 +65,3 @@ class Multiprocess(QemuSystemTest):
 
         proxy_sock.close()
         remote_sock.close()
-
-    def test_multiprocess(self):
-        kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE
-        if self.arch == 'x86_64':
-            kernel_command_line += 'console=ttyS0 rdinit=/bin/bash'
-            self.do_test(self.ASSET_KERNEL_X86, self.ASSET_INITRD_X86,
-                         kernel_command_line, 'pc')
-        elif self.arch == 'aarch64':
-            kernel_command_line += 'rdinit=/bin/bash console=ttyAMA0'
-            self.do_test(self.ASSET_KERNEL_AARCH64, self.ASSET_INITRD_AARCH64,
-                         kernel_command_line, 'virt,gic-version=3')
-        else:
-            assert False
-
-if __name__ == '__main__':
-    QemuSystemTest.main()
diff --git a/tests/functional/or1k/meson.build b/tests/functional/or1k/meson.build
new file mode 100644
index 0000000000..e246e2ab08
--- /dev/null
+++ b/tests/functional/or1k/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_or1k_system_thorough = [
+  'replay',
+  'sim',
+]
diff --git a/tests/functional/test_or1k_replay.py b/tests/functional/or1k/test_replay.py
index 2b60a9372c..2b60a9372c 100755
--- a/tests/functional/test_or1k_replay.py
+++ b/tests/functional/or1k/test_replay.py
diff --git a/tests/functional/test_or1k_sim.py b/tests/functional/or1k/test_sim.py
index f9f0b690a0..f9f0b690a0 100755
--- a/tests/functional/test_or1k_sim.py
+++ b/tests/functional/or1k/test_sim.py
diff --git a/tests/functional/ppc/meson.build b/tests/functional/ppc/meson.build
new file mode 100644
index 0000000000..3d562010d8
--- /dev/null
+++ b/tests/functional/ppc/meson.build
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_ppc_timeouts = {
+  '40p' : 240,
+}
+
+tests_ppc_system_quick = [
+  'migration',
+  '74xx',
+]
+
+tests_ppc_system_thorough = [
+  '40p',
+  'amiga',
+  'bamboo',
+  'mac',
+  'mpc8544ds',
+  'replay',
+  'sam460ex',
+  'tuxrun',
+  'virtex_ml507',
+]
diff --git a/tests/functional/test_ppc_40p.py b/tests/functional/ppc/test_40p.py
index 614972a7eb..614972a7eb 100755
--- a/tests/functional/test_ppc_40p.py
+++ b/tests/functional/ppc/test_40p.py
diff --git a/tests/functional/test_ppc_74xx.py b/tests/functional/ppc/test_74xx.py
index 5386016f26..5386016f26 100755
--- a/tests/functional/test_ppc_74xx.py
+++ b/tests/functional/ppc/test_74xx.py
diff --git a/tests/functional/test_ppc_amiga.py b/tests/functional/ppc/test_amiga.py
index 8600e2e963..8600e2e963 100755
--- a/tests/functional/test_ppc_amiga.py
+++ b/tests/functional/ppc/test_amiga.py
diff --git a/tests/functional/test_ppc_bamboo.py b/tests/functional/ppc/test_bamboo.py
index c634ae7b4a..c634ae7b4a 100755
--- a/tests/functional/test_ppc_bamboo.py
+++ b/tests/functional/ppc/test_bamboo.py
diff --git a/tests/functional/test_ppc_mac.py b/tests/functional/ppc/test_mac.py
index 9e4bc1a52c..9e4bc1a52c 100755
--- a/tests/functional/test_ppc_mac.py
+++ b/tests/functional/ppc/test_mac.py
diff --git a/tests/functional/ppc/test_migration.py b/tests/functional/ppc/test_migration.py
new file mode 100755
index 0000000000..a8692826d3
--- /dev/null
+++ b/tests/functional/ppc/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# ppc migration test
+
+from migration import MigrationTest
+
+
+class PpcMigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('sam460ex')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('sam460ex')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('sam460ex')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_ppc_mpc8544ds.py b/tests/functional/ppc/test_mpc8544ds.py
index 0715410d7a..0715410d7a 100755
--- a/tests/functional/test_ppc_mpc8544ds.py
+++ b/tests/functional/ppc/test_mpc8544ds.py
diff --git a/tests/functional/test_ppc_replay.py b/tests/functional/ppc/test_replay.py
index 8382070abd..8382070abd 100755
--- a/tests/functional/test_ppc_replay.py
+++ b/tests/functional/ppc/test_replay.py
diff --git a/tests/functional/test_ppc_sam460ex.py b/tests/functional/ppc/test_sam460ex.py
index 31cf9dd6de..31cf9dd6de 100644..100755
--- a/tests/functional/test_ppc_sam460ex.py
+++ b/tests/functional/ppc/test_sam460ex.py
diff --git a/tests/functional/test_ppc_tuxrun.py b/tests/functional/ppc/test_tuxrun.py
index 5458a7fb71..5458a7fb71 100755
--- a/tests/functional/test_ppc_tuxrun.py
+++ b/tests/functional/ppc/test_tuxrun.py
diff --git a/tests/functional/test_ppc_virtex_ml507.py b/tests/functional/ppc/test_virtex_ml507.py
index 8fe43549b7..8fe43549b7 100755
--- a/tests/functional/test_ppc_virtex_ml507.py
+++ b/tests/functional/ppc/test_virtex_ml507.py
diff --git a/tests/functional/ppc64/meson.build b/tests/functional/ppc64/meson.build
new file mode 100644
index 0000000000..842fe0fc71
--- /dev/null
+++ b/tests/functional/ppc64/meson.build
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_ppc64_timeouts = {
+  'hv' : 1000,
+  'mac99' : 120,
+  'powernv' : 480,
+  'pseries' : 480,
+  'replay' : 210,
+  'tuxrun' : 420,
+}
+
+tests_ppc64_system_quick = [
+  'migration',
+]
+
+tests_ppc64_system_thorough = [
+  'e500',
+  'hv',
+  'mac99',
+  'powernv',
+  'pseries',
+  'replay',
+  'reverse_debug',
+  'tuxrun',
+]
diff --git a/tests/functional/test_ppc64_e500.py b/tests/functional/ppc64/test_e500.py
index f5fcad9f6b..f5fcad9f6b 100755
--- a/tests/functional/test_ppc64_e500.py
+++ b/tests/functional/ppc64/test_e500.py
diff --git a/tests/functional/test_ppc64_hv.py b/tests/functional/ppc64/test_hv.py
index d87f440fa7..d87f440fa7 100755
--- a/tests/functional/test_ppc64_hv.py
+++ b/tests/functional/ppc64/test_hv.py
diff --git a/tests/functional/test_ppc64_mac99.py b/tests/functional/ppc64/test_mac99.py
index dfd9c01371..dfd9c01371 100755
--- a/tests/functional/test_ppc64_mac99.py
+++ b/tests/functional/ppc64/test_mac99.py
diff --git a/tests/functional/ppc64/test_migration.py b/tests/functional/ppc64/test_migration.py
new file mode 100755
index 0000000000..5dfdaaf709
--- /dev/null
+++ b/tests/functional/ppc64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# ppc migration test
+
+from migration import MigrationTest
+
+
+class PpcMigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('mac99')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('mac99')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('mac99')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_ppc64_powernv.py b/tests/functional/ppc64/test_powernv.py
index 685e2178ed..685e2178ed 100755
--- a/tests/functional/test_ppc64_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
diff --git a/tests/functional/test_ppc64_pseries.py b/tests/functional/ppc64/test_pseries.py
index 67057934e8..67057934e8 100755
--- a/tests/functional/test_ppc64_pseries.py
+++ b/tests/functional/ppc64/test_pseries.py
diff --git a/tests/functional/test_ppc64_replay.py b/tests/functional/ppc64/test_replay.py
index e8c9c4bcbf..e8c9c4bcbf 100755
--- a/tests/functional/test_ppc64_replay.py
+++ b/tests/functional/ppc64/test_replay.py
diff --git a/tests/functional/test_ppc64_reverse_debug.py b/tests/functional/ppc64/test_reverse_debug.py
index 5931adef5a..5931adef5a 100755
--- a/tests/functional/test_ppc64_reverse_debug.py
+++ b/tests/functional/ppc64/test_reverse_debug.py
diff --git a/tests/functional/test_ppc64_tuxrun.py b/tests/functional/ppc64/test_tuxrun.py
index e8f79c676e..e8f79c676e 100755
--- a/tests/functional/test_ppc64_tuxrun.py
+++ b/tests/functional/ppc64/test_tuxrun.py
diff --git a/tests/functional/qemu_test/ports.py b/tests/functional/qemu_test/ports.py
index 631b77abf6..81174a6153 100644
--- a/tests/functional/qemu_test/ports.py
+++ b/tests/functional/qemu_test/ports.py
@@ -23,8 +23,9 @@ class Ports():
     PORTS_END = PORTS_START + PORTS_RANGE_SIZE
 
     def __enter__(self):
-        lock_file = os.path.join(BUILD_DIR, "tests", "functional", "port_lock")
-        self.lock_fh = os.open(lock_file, os.O_CREAT)
+        lock_file = os.path.join(BUILD_DIR, "tests", "functional",
+                                 f".port_lock.{self.PORTS_START}")
+        self.lock_fh = os.open(lock_file, os.O_CREAT, mode=0o666)
         fcntl.flock(self.lock_fh, fcntl.LOCK_EX)
         return self
 
diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py
index 5caf7b13fe..fbeb171058 100644
--- a/tests/functional/qemu_test/testcase.py
+++ b/tests/functional/qemu_test/testcase.py
@@ -235,6 +235,7 @@ class QemuBaseTest(unittest.TestCase):
         self.log.removeHandler(self._log_fh)
         self._log_fh.close()
 
+    @staticmethod
     def main():
         warnings.simplefilter("default")
         os.environ["PYTHONWARNINGS"] = "default"
diff --git a/tests/functional/riscv32/meson.build b/tests/functional/riscv32/meson.build
new file mode 100644
index 0000000000..f3ebbb8db5
--- /dev/null
+++ b/tests/functional/riscv32/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_riscv32_system_quick = [
+  'migration',
+  'opensbi',
+]
+
+tests_riscv32_system_thorough = [
+  'tuxrun',
+]
diff --git a/tests/functional/riscv32/test_migration.py b/tests/functional/riscv32/test_migration.py
new file mode 100755
index 0000000000..30acbbe69f
--- /dev/null
+++ b/tests/functional/riscv32/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# riscv32 migration test
+
+from migration import MigrationTest
+
+
+class Rv32MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('spike')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('virt')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('spike')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/riscv32/test_opensbi.py b/tests/functional/riscv32/test_opensbi.py
new file mode 100755
index 0000000000..d1ac706f0b
--- /dev/null
+++ b/tests/functional/riscv32/test_opensbi.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reuse the 64-bit OpenSBI test for RISC-V 32-bit machines
+
+from riscv64.test_opensbi import RiscvOpenSBI
+
+if __name__ == '__main__':
+    RiscvOpenSBI.main()
diff --git a/tests/functional/test_riscv32_tuxrun.py b/tests/functional/riscv32/test_tuxrun.py
index 3c570208d0..3c570208d0 100755
--- a/tests/functional/test_riscv32_tuxrun.py
+++ b/tests/functional/riscv32/test_tuxrun.py
diff --git a/tests/functional/riscv64/meson.build b/tests/functional/riscv64/meson.build
new file mode 100644
index 0000000000..c1704d9275
--- /dev/null
+++ b/tests/functional/riscv64/meson.build
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_riscv64_timeouts = {
+  'tuxrun' : 120,
+}
+
+tests_riscv64_system_quick = [
+  'migration',
+  'opensbi',
+]
+
+tests_riscv64_system_thorough = [
+  'sifive_u',
+  'tuxrun',
+]
diff --git a/tests/functional/riscv64/test_migration.py b/tests/functional/riscv64/test_migration.py
new file mode 100755
index 0000000000..2d613a29ec
--- /dev/null
+++ b/tests/functional/riscv64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# riscv64 migration test
+
+from migration import MigrationTest
+
+
+class Rv64MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('virt')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('spike')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('virt')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_riscv_opensbi.py b/tests/functional/riscv64/test_opensbi.py
index d077e40f42..d077e40f42 100755
--- a/tests/functional/test_riscv_opensbi.py
+++ b/tests/functional/riscv64/test_opensbi.py
diff --git a/tests/functional/test_riscv64_sifive_u.py b/tests/functional/riscv64/test_sifive_u.py
index 358ff0d1f6..358ff0d1f6 100755
--- a/tests/functional/test_riscv64_sifive_u.py
+++ b/tests/functional/riscv64/test_sifive_u.py
diff --git a/tests/functional/test_riscv64_tuxrun.py b/tests/functional/riscv64/test_tuxrun.py
index 0d8de36204..0d8de36204 100755
--- a/tests/functional/test_riscv64_tuxrun.py
+++ b/tests/functional/riscv64/test_tuxrun.py
diff --git a/tests/functional/rx/meson.build b/tests/functional/rx/meson.build
new file mode 100644
index 0000000000..6af83a9f23
--- /dev/null
+++ b/tests/functional/rx/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_rx_system_thorough = [
+  'gdbsim',
+]
diff --git a/tests/functional/test_rx_gdbsim.py b/tests/functional/rx/test_gdbsim.py
index 49245793e1..49245793e1 100755
--- a/tests/functional/test_rx_gdbsim.py
+++ b/tests/functional/rx/test_gdbsim.py
diff --git a/tests/functional/s390x/meson.build b/tests/functional/s390x/meson.build
new file mode 100644
index 0000000000..030b116039
--- /dev/null
+++ b/tests/functional/s390x/meson.build
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_s390x_timeouts = {
+  'ccw_virtio' : 420,
+}
+
+tests_s390x_system_thorough = [
+  'ccw_virtio',
+  'pxelinux',
+  'replay',
+  'topology',
+  'tuxrun',
+]
diff --git a/tests/functional/test_s390x_ccw_virtio.py b/tests/functional/s390x/test_ccw_virtio.py
index 453711aa0f..453711aa0f 100755
--- a/tests/functional/test_s390x_ccw_virtio.py
+++ b/tests/functional/s390x/test_ccw_virtio.py
diff --git a/tests/functional/test_s390x_pxelinux.py b/tests/functional/s390x/test_pxelinux.py
index 4fc33b8c46..4fc33b8c46 100755
--- a/tests/functional/test_s390x_pxelinux.py
+++ b/tests/functional/s390x/test_pxelinux.py
diff --git a/tests/functional/test_s390x_replay.py b/tests/functional/s390x/test_replay.py
index 33b5843ada..33b5843ada 100755
--- a/tests/functional/test_s390x_replay.py
+++ b/tests/functional/s390x/test_replay.py
diff --git a/tests/functional/test_s390x_topology.py b/tests/functional/s390x/test_topology.py
index 1b5dc65135..1b5dc65135 100755
--- a/tests/functional/test_s390x_topology.py
+++ b/tests/functional/s390x/test_topology.py
diff --git a/tests/functional/test_s390x_tuxrun.py b/tests/functional/s390x/test_tuxrun.py
index 8df3c6893b..8df3c6893b 100755
--- a/tests/functional/test_s390x_tuxrun.py
+++ b/tests/functional/s390x/test_tuxrun.py
diff --git a/tests/functional/sh4/meson.build b/tests/functional/sh4/meson.build
new file mode 100644
index 0000000000..56f824e1e7
--- /dev/null
+++ b/tests/functional/sh4/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_sh4_timeouts = {
+  'tuxrun' : 240,
+}
+
+tests_sh4_system_thorough = [
+  'r2d',
+  'tuxrun',
+]
diff --git a/tests/functional/test_sh4_r2d.py b/tests/functional/sh4/test_r2d.py
index 03a648374c..03a648374c 100755
--- a/tests/functional/test_sh4_r2d.py
+++ b/tests/functional/sh4/test_r2d.py
diff --git a/tests/functional/test_sh4_tuxrun.py b/tests/functional/sh4/test_tuxrun.py
index 1748f8c7ef..1748f8c7ef 100755
--- a/tests/functional/test_sh4_tuxrun.py
+++ b/tests/functional/sh4/test_tuxrun.py
diff --git a/tests/functional/sh4eb/meson.build b/tests/functional/sh4eb/meson.build
new file mode 100644
index 0000000000..25e9a6e404
--- /dev/null
+++ b/tests/functional/sh4eb/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sh4eb_system_thorough = [
+  'r2d',
+]
diff --git a/tests/functional/test_sh4eb_r2d.py b/tests/functional/sh4eb/test_r2d.py
index 473093bbe1..473093bbe1 100755
--- a/tests/functional/test_sh4eb_r2d.py
+++ b/tests/functional/sh4eb/test_r2d.py
diff --git a/tests/functional/sparc/meson.build b/tests/functional/sparc/meson.build
new file mode 100644
index 0000000000..88732becd8
--- /dev/null
+++ b/tests/functional/sparc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sparc_system_quick = [
+  'migration',
+]
+
+tests_sparc_system_thorough = [
+  'replay',
+  'sun4m',
+]
diff --git a/tests/functional/sparc/test_migration.py b/tests/functional/sparc/test_migration.py
new file mode 100755
index 0000000000..dd6d5783b1
--- /dev/null
+++ b/tests/functional/sparc/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Sparc migration test
+
+from migration import MigrationTest
+
+
+class SparcMigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('SS-4')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('SS-5')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('SS-4')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_sparc_replay.py b/tests/functional/sparc/test_replay.py
index 865d6486f9..865d6486f9 100755
--- a/tests/functional/test_sparc_replay.py
+++ b/tests/functional/sparc/test_replay.py
diff --git a/tests/functional/test_sparc_sun4m.py b/tests/functional/sparc/test_sun4m.py
index 7cd28ebdd1..7cd28ebdd1 100755
--- a/tests/functional/test_sparc_sun4m.py
+++ b/tests/functional/sparc/test_sun4m.py
diff --git a/tests/functional/sparc64/meson.build b/tests/functional/sparc64/meson.build
new file mode 100644
index 0000000000..2e04e7d4f3
--- /dev/null
+++ b/tests/functional/sparc64/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sparc64_system_quick = [
+  'migration',
+]
+
+tests_sparc64_system_thorough = [
+  'sun4u',
+  'tuxrun',
+]
diff --git a/tests/functional/sparc64/test_migration.py b/tests/functional/sparc64/test_migration.py
new file mode 100755
index 0000000000..a8a6c73c35
--- /dev/null
+++ b/tests/functional/sparc64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Sparc64 migration test
+
+from migration import MigrationTest
+
+
+class Sparc64MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('sun4u')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('sun4u')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('sun4u')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/test_sparc64_sun4u.py b/tests/functional/sparc64/test_sun4u.py
index 27ac289659..27ac289659 100755
--- a/tests/functional/test_sparc64_sun4u.py
+++ b/tests/functional/sparc64/test_sun4u.py
diff --git a/tests/functional/test_sparc64_tuxrun.py b/tests/functional/sparc64/test_tuxrun.py
index 0d7b43dd74..0d7b43dd74 100755
--- a/tests/functional/test_sparc64_tuxrun.py
+++ b/tests/functional/sparc64/test_tuxrun.py
diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
new file mode 100644
index 0000000000..d0b4667bb8
--- /dev/null
+++ b/tests/functional/x86_64/meson.build
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_x86_64_timeouts = {
+  'acpi_bits' : 420,
+  'intel_iommu': 300,
+  'kvm_xen' : 180,
+  'netdev_ethtool' : 180,
+  'replay' : 480,
+  'virtio_balloon': 120,
+}
+
+tests_x86_64_system_quick = [
+  'cpu_model_versions',
+  'cpu_queries',
+  'mem_addr_space',
+  'migration',
+  'pc_cpu_hotplug_props',
+  'virtio_version',
+  'memlock',
+]
+
+tests_x86_64_system_thorough = [
+  'acpi_bits',
+  'hotplug_blk',
+  'hotplug_cpu',
+  'intel_iommu',
+  'kvm_xen',
+  'linux_initrd',
+  'multiprocess',
+  'netdev_ethtool',
+  'replay',
+  'reverse_debug',
+  'tuxrun',
+  'virtio_balloon',
+  'virtio_gpu',
+]
diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/x86_64/test_acpi_bits.py
index 8e0563a97b..8e0563a97b 100755
--- a/tests/functional/test_acpi_bits.py
+++ b/tests/functional/x86_64/test_acpi_bits.py
diff --git a/tests/functional/test_x86_cpu_model_versions.py b/tests/functional/x86_64/test_cpu_model_versions.py
index 36c968f1c0..36c968f1c0 100755
--- a/tests/functional/test_x86_cpu_model_versions.py
+++ b/tests/functional/x86_64/test_cpu_model_versions.py
diff --git a/tests/functional/test_cpu_queries.py b/tests/functional/x86_64/test_cpu_queries.py
index b1122a0e8f..b1122a0e8f 100755
--- a/tests/functional/test_cpu_queries.py
+++ b/tests/functional/x86_64/test_cpu_queries.py
diff --git a/tests/functional/test_x86_64_hotplug_blk.py b/tests/functional/x86_64/test_hotplug_blk.py
index 7ddbfefc21..7ddbfefc21 100755
--- a/tests/functional/test_x86_64_hotplug_blk.py
+++ b/tests/functional/x86_64/test_hotplug_blk.py
diff --git a/tests/functional/test_x86_64_hotplug_cpu.py b/tests/functional/x86_64/test_hotplug_cpu.py
index 7b9200ac2e..7b9200ac2e 100755
--- a/tests/functional/test_x86_64_hotplug_cpu.py
+++ b/tests/functional/x86_64/test_hotplug_cpu.py
diff --git a/tests/functional/test_intel_iommu.py b/tests/functional/x86_64/test_intel_iommu.py
index 62268d6f27..62268d6f27 100755
--- a/tests/functional/test_intel_iommu.py
+++ b/tests/functional/x86_64/test_intel_iommu.py
diff --git a/tests/functional/test_x86_64_kvm_xen.py b/tests/functional/x86_64/test_kvm_xen.py
index a5d445023c..a5d445023c 100755
--- a/tests/functional/test_x86_64_kvm_xen.py
+++ b/tests/functional/x86_64/test_kvm_xen.py
diff --git a/tests/functional/test_linux_initrd.py b/tests/functional/x86_64/test_linux_initrd.py
index 2207f83fbf..2207f83fbf 100755
--- a/tests/functional/test_linux_initrd.py
+++ b/tests/functional/x86_64/test_linux_initrd.py
diff --git a/tests/functional/test_mem_addr_space.py b/tests/functional/x86_64/test_mem_addr_space.py
index 61b4a190b4..61b4a190b4 100755
--- a/tests/functional/test_mem_addr_space.py
+++ b/tests/functional/x86_64/test_mem_addr_space.py
diff --git a/tests/functional/test_memlock.py b/tests/functional/x86_64/test_memlock.py
index 2b515ff979..2b515ff979 100755
--- a/tests/functional/test_memlock.py
+++ b/tests/functional/x86_64/test_memlock.py
diff --git a/tests/functional/x86_64/test_migration.py b/tests/functional/x86_64/test_migration.py
new file mode 100755
index 0000000000..f3a517ae1f
--- /dev/null
+++ b/tests/functional/x86_64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# x86_64 migration test
+
+from migration import MigrationTest
+
+
+class X8664MigrationTest(MigrationTest):
+
+    def test_migration_with_tcp_localhost(self):
+        self.set_machine('microvm')
+        self.migration_with_tcp_localhost()
+
+    def test_migration_with_unix(self):
+        self.set_machine('microvm')
+        self.migration_with_unix()
+
+    def test_migration_with_exec(self):
+        self.set_machine('microvm')
+        self.migration_with_exec()
+
+
+if __name__ == '__main__':
+    MigrationTest.main()
diff --git a/tests/functional/x86_64/test_multiprocess.py b/tests/functional/x86_64/test_multiprocess.py
new file mode 100755
index 0000000000..756629dd44
--- /dev/null
+++ b/tests/functional/x86_64/test_multiprocess.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Test for multiprocess qemu on x86
+
+from multiprocess import Multiprocess
+from qemu_test import Asset
+
+
+class X86Multiprocess(Multiprocess):
+
+    ASSET_KERNEL_X86 = Asset(
+        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+         '/releases/31/Everything/x86_64/os/images/pxeboot/vmlinuz'),
+        'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
+
+    ASSET_INITRD_X86 = Asset(
+        ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+         '/releases/31/Everything/x86_64/os/images/pxeboot/initrd.img'),
+        '3b6cb5c91a14c42e2f61520f1689264d865e772a1f0069e660a800d31dd61fb9')
+
+    def test_multiprocess(self):
+        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+                               'console=ttyS0 rdinit=/bin/bash')
+        self.do_test(self.ASSET_KERNEL_X86, self.ASSET_INITRD_X86,
+                     kernel_command_line, 'pc')
+
+
+if __name__ == '__main__':
+    Multiprocess.main()
diff --git a/tests/functional/test_netdev_ethtool.py b/tests/functional/x86_64/test_netdev_ethtool.py
index ee1a397bd2..ee1a397bd2 100755
--- a/tests/functional/test_netdev_ethtool.py
+++ b/tests/functional/x86_64/test_netdev_ethtool.py
diff --git a/tests/functional/test_pc_cpu_hotplug_props.py b/tests/functional/x86_64/test_pc_cpu_hotplug_props.py
index 2bed8ada02..2bed8ada02 100755
--- a/tests/functional/test_pc_cpu_hotplug_props.py
+++ b/tests/functional/x86_64/test_pc_cpu_hotplug_props.py
diff --git a/tests/functional/test_x86_64_replay.py b/tests/functional/x86_64/test_replay.py
index 27287d452d..27287d452d 100755
--- a/tests/functional/test_x86_64_replay.py
+++ b/tests/functional/x86_64/test_replay.py
diff --git a/tests/functional/test_x86_64_reverse_debug.py b/tests/functional/x86_64/test_reverse_debug.py
index d713e91e14..d713e91e14 100755
--- a/tests/functional/test_x86_64_reverse_debug.py
+++ b/tests/functional/x86_64/test_reverse_debug.py
diff --git a/tests/functional/test_x86_64_tuxrun.py b/tests/functional/x86_64/test_tuxrun.py
index fcbc62b1b0..fcbc62b1b0 100755
--- a/tests/functional/test_x86_64_tuxrun.py
+++ b/tests/functional/x86_64/test_tuxrun.py
diff --git a/tests/functional/test_virtio_balloon.py b/tests/functional/x86_64/test_virtio_balloon.py
index 5877b6c408..5877b6c408 100755
--- a/tests/functional/test_virtio_balloon.py
+++ b/tests/functional/x86_64/test_virtio_balloon.py
diff --git a/tests/functional/test_virtio_gpu.py b/tests/functional/x86_64/test_virtio_gpu.py
index be96de24da..be96de24da 100755
--- a/tests/functional/test_virtio_gpu.py
+++ b/tests/functional/x86_64/test_virtio_gpu.py
diff --git a/tests/functional/test_virtio_version.py b/tests/functional/x86_64/test_virtio_version.py
index a5ea73237f..a5ea73237f 100755
--- a/tests/functional/test_virtio_version.py
+++ b/tests/functional/x86_64/test_virtio_version.py
diff --git a/tests/functional/xtensa/meson.build b/tests/functional/xtensa/meson.build
new file mode 100644
index 0000000000..d61d82a135
--- /dev/null
+++ b/tests/functional/xtensa/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_xtensa_system_thorough = [
+  'lx60',
+  'replay',
+]
diff --git a/tests/functional/test_xtensa_lx60.py b/tests/functional/xtensa/test_lx60.py
index 147c920899..147c920899 100755
--- a/tests/functional/test_xtensa_lx60.py
+++ b/tests/functional/xtensa/test_lx60.py
diff --git a/tests/functional/test_xtensa_replay.py b/tests/functional/xtensa/test_replay.py
index eb00a3b004..eb00a3b004 100755
--- a/tests/functional/test_xtensa_replay.py
+++ b/tests/functional/xtensa/test_replay.py