aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include8
-rw-r--r--tests/data/acpi/aarch64/virt/APIC.its_offbin0 -> 164 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDTbin5196 -> 5337 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.acpihmatvirtbin5282 -> 5423 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.acpipcihpbin0 -> 6246 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.hpoffacpiindexbin0 -> 5391 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.memhpbin6557 -> 6698 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.pxbbin7679 -> 7812 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.smmuv3-devbin0 -> 10274 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacybin0 -> 10274 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.topologybin5398 -> 5539 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/DSDT.viotbin0 -> 5354 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/HESTbin0 -> 224 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/IORT.its_offbin0 -> 172 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/IORT.smmuv3-devbin0 -> 364 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/IORT.smmuv3-legacybin0 -> 276 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/PPTTbin76 -> 96 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/PPTT.acpihmatvirtbin156 -> 176 bytes
-rw-r--r--tests/data/acpi/aarch64/virt/PPTT.topologybin336 -> 356 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/APICbin0 -> 108 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/APIC.topologybin0 -> 153 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/DSDTbin0 -> 4603 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/DSDT.memhpbin0 -> 5824 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/DSDT.numamembin0 -> 4609 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/DSDT.topologybin0 -> 4905 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/FACPbin0 -> 268 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/MCFGbin0 -> 60 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/PPTTbin0 -> 96 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/PPTT.topologybin0 -> 196 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SLIT (renamed from tests/qapi-schema/doc-bad-section.out)0
-rw-r--r--tests/data/acpi/loongarch64/virt/SLIT.numamembin0 -> 48 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SPCRbin0 -> 80 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SRATbin0 -> 104 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SRAT.memhpbin0 -> 144 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SRAT.numamembin0 -> 144 bytes
-rw-r--r--tests/data/acpi/loongarch64/virt/SRAT.topologybin0 -> 152 bytes
-rwxr-xr-xtests/data/acpi/rebuild-expected-aml.sh4
-rw-r--r--tests/data/acpi/riscv64/virt/APICbin116 -> 116 bytes
-rw-r--r--tests/data/acpi/riscv64/virt/DSDTbin3576 -> 3538 bytes
-rw-r--r--tests/data/acpi/riscv64/virt/FACPbin276 -> 276 bytes
-rw-r--r--tests/data/acpi/riscv64/virt/RHCTbin400 -> 416 bytes
-rw-r--r--tests/data/acpi/x86/microvm/DSDT.pciebin3023 -> 2985 bytes
-rw-r--r--tests/data/uefi-boot-images/bios-tables-test.loongarch64.iso.qcow2bin0 -> 12800 bytes
-rw-r--r--tests/data/vmstate-static-checker/aarch64/virt-7.2.json2571
-rw-r--r--tests/data/vmstate-static-checker/dump1.json (renamed from tests/vmstate-static-checker-data/dump1.json)0
-rw-r--r--tests/data/vmstate-static-checker/dump2.json (renamed from tests/vmstate-static-checker-data/dump2.json)0
-rw-r--r--tests/data/vmstate-static-checker/m68k/virt-7.2.json2936
-rw-r--r--tests/data/vmstate-static-checker/ppc64/pseries-7.2.json1068
-rw-r--r--tests/data/vmstate-static-checker/s390x/s390-ccw-virtio-7.2.json475
-rw-r--r--tests/data/vmstate-static-checker/x86_64/pc-q35-7.2.json3297
-rw-r--r--tests/decode/meson.build1
-rw-r--r--tests/decode/succ_infer1.decode4
-rw-r--r--tests/docker/Makefile.include10
-rwxr-xr-xtests/docker/common.rc13
-rw-r--r--tests/docker/dockerfiles/alpine.docker6
-rw-r--r--tests/docker/dockerfiles/centos9.docker4
-rw-r--r--tests/docker/dockerfiles/debian-all-test-cross.docker32
-rw-r--r--tests/docker/dockerfiles/debian-amd64-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-arm64-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-armhf-cross.docker21
-rw-r--r--tests/docker/dockerfiles/debian-i686-cross.docker22
-rw-r--r--tests/docker/dockerfiles/debian-mips64el-cross.docker9
-rw-r--r--tests/docker/dockerfiles/debian-mipsel-cross.docker9
-rw-r--r--tests/docker/dockerfiles/debian-ppc64el-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian-riscv64-cross.docker116
-rw-r--r--tests/docker/dockerfiles/debian-s390x-cross.docker18
-rw-r--r--tests/docker/dockerfiles/debian.docker18
-rw-r--r--tests/docker/dockerfiles/emsdk-wasm32-cross.docker2
-rw-r--r--tests/docker/dockerfiles/fedora-rust-nightly.docker20
-rw-r--r--tests/docker/dockerfiles/fedora-win64-cross.docker15
-rw-r--r--tests/docker/dockerfiles/fedora.docker18
-rw-r--r--tests/docker/dockerfiles/opensuse-leap.docker7
-rw-r--r--tests/docker/dockerfiles/ubuntu2204.docker8
-rw-r--r--tests/functional/aarch64/meson.build49
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700.py (renamed from tests/functional/test_aarch64_aspeed_ast2700.py)12
-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.py143
-rwxr-xr-xtests/functional/aarch64/test_hotplug_pci.py72
-rwxr-xr-xtests/functional/aarch64/test_imx8mp_evk.py (renamed from tests/functional/test_aarch64_imx8mp_evk.py)1
-rwxr-xr-xtests/functional/aarch64/test_kvm.py71
-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)16
-rwxr-xr-xtests/functional/aarch64/test_rme_sbsaref.py77
-rwxr-xr-xtests/functional/aarch64/test_rme_virt.py76
-rwxr-xr-xtests/functional/aarch64/test_sbsaref.py (renamed from tests/functional/test_aarch64_sbsaref.py)5
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_alpine.py (renamed from tests/functional/test_aarch64_sbsaref_alpine.py)5
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_freebsd.py (renamed from tests/functional/test_aarch64_sbsaref_freebsd.py)13
-rwxr-xr-xtests/functional/aarch64/test_smmu.py (renamed from tests/functional/test_aarch64_smmu.py)12
-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)4
-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)1
-rwxr-xr-xtests/functional/aarch64/test_xlnx_versal.py (renamed from tests/functional/test_aarch64_xlnx_versal.py)12
-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)34
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2500.py (renamed from tests/functional/test_arm_aspeed_ast2500.py)8
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2600.py (renamed from tests/functional/test_arm_aspeed_ast2600.py)44
-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.py25
-rwxr-xr-xtests/functional/arm/test_aspeed_gb200nvl_bmc.py26
-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)3
-rwxr-xr-xtests/functional/arm/test_max78000fthr.py48
-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.py47
-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.py48
-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/aspeed.py17
-rw-r--r--tests/functional/avr/meson.build6
-rwxr-xr-xtests/functional/avr/test_mega2560.py (renamed from tests/functional/test_avr_mega2560.py)11
-rwxr-xr-xtests/functional/avr/test_uno.py32
-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_vmstate.py67
-rwxr-xr-xtests/functional/generic/test_vnc.py (renamed from tests/functional/test_vnc.py)4
-rw-r--r--tests/functional/hppa/meson.build9
-rwxr-xr-xtests/functional/hppa/test_cdboot.py38
-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.build13
-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)20
-rwxr-xr-xtests/functional/m68k/test_q800.py (renamed from tests/functional/test_m68k_q800.py)3
-rwxr-xr-xtests/functional/m68k/test_replay.py (renamed from tests/functional/test_m68k_replay.py)3
-rwxr-xr-xtests/functional/m68k/test_tuxrun.py (renamed from tests/functional/test_m68k_tuxrun.py)0
-rw-r--r--tests/functional/meson.build377
-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)18
-rw-r--r--tests/functional/microblazeel/meson.build5
-rwxr-xr-xtests/functional/microblazeel/test_s3adsp1800.py (renamed from tests/functional/test_microblazeel_s3adsp1800.py)8
-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)6
-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)7
-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)41
-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.build23
-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.py48
-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
-rw-r--r--tests/functional/ppc/test_ppe42.py79
-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.build26
-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)34
-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)15
-rwxr-xr-xtests/functional/ppc64/test_tuxrun.py (renamed from tests/functional/test_ppc64_tuxrun.py)0
-rw-r--r--tests/functional/qemu_test/__init__.py4
-rw-r--r--tests/functional/qemu_test/asset.py25
-rw-r--r--tests/functional/qemu_test/cmd.py67
-rw-r--r--tests/functional/qemu_test/decorators.py36
-rw-r--r--tests/functional/qemu_test/gdb.py86
-rw-r--r--tests/functional/qemu_test/ports.py5
-rw-r--r--tests/functional/qemu_test/testcase.py29
-rw-r--r--tests/functional/replay_kernel.py16
-rw-r--r--tests/functional/reverse_debugging.py152
-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.py63
-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.build17
-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.py130
-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)1
-rwxr-xr-xtests/functional/test_aarch64_rme_sbsaref.py69
-rwxr-xr-xtests/functional/test_aarch64_rme_virt.py101
-rwxr-xr-xtests/functional/test_ppc_bamboo.py44
-rw-r--r--tests/functional/x86_64/meson.build39
-rwxr-xr-xtests/functional/x86_64/test_acpi_bits.py (renamed from tests/functional/test_acpi_bits.py)31
-rwxr-xr-xtests/functional/x86_64/test_bad_vmstate.py58
-rwxr-xr-xtests/functional/x86_64/test_cpu_model_versions.py (renamed from tests/functional/test_x86_cpu_model_versions.py)110
-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)63
-rwxr-xr-xtests/functional/x86_64/test_memlock.py80
-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)1
-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)15
-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_vfio_user_client.py201
-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)2
-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
-rw-r--r--tests/guest-debug/test_gdbstub.py1
-rw-r--r--tests/include/meson.build2
m---------tests/lcitool/libvirt-ci0
-rw-r--r--tests/lcitool/mappings.yml6
-rw-r--r--tests/lcitool/projects/qemu.yml3
-rwxr-xr-xtests/lcitool/refresh58
-rw-r--r--tests/meson.build1
-rw-r--r--tests/qapi-schema/doc-bad-section.err1
-rw-r--r--tests/qapi-schema/doc-bad-section.json10
-rw-r--r--tests/qapi-schema/doc-good.json10
-rw-r--r--tests/qapi-schema/doc-good.out10
-rw-r--r--tests/qapi-schema/doc-good.txt274
-rw-r--r--tests/qapi-schema/doc-non-first-section.err1
-rw-r--r--tests/qapi-schema/doc-non-first-section.json6
-rw-r--r--tests/qapi-schema/doc-non-first-section.out0
-rw-r--r--tests/qapi-schema/meson.build1
-rwxr-xr-xtests/qapi-schema/test-qapi.py7
-rw-r--r--tests/qemu-iotests/039.out10
-rw-r--r--tests/qemu-iotests/049.out9
-rw-r--r--tests/qemu-iotests/061.out4
-rwxr-xr-xtests/qemu-iotests/1061
-rwxr-xr-xtests/qemu-iotests/1252
-rw-r--r--tests/qemu-iotests/137.out2
-rwxr-xr-xtests/qemu-iotests/1471
-rwxr-xr-xtests/qemu-iotests/1515
-rwxr-xr-xtests/qemu-iotests/1532
-rw-r--r--tests/qemu-iotests/153.out36
-rwxr-xr-xtests/qemu-iotests/1751
-rwxr-xr-xtests/qemu-iotests/1782
-rw-r--r--tests/qemu-iotests/178.out.qcow23
-rw-r--r--tests/qemu-iotests/178.out.raw3
-rw-r--r--tests/qemu-iotests/184.out8
-rwxr-xr-xtests/qemu-iotests/2211
-rwxr-xr-xtests/qemu-iotests/2402
-rw-r--r--tests/qemu-iotests/240.out4
-rwxr-xr-xtests/qemu-iotests/2531
-rwxr-xr-xtests/qemu-iotests/3085
-rwxr-xr-xtests/qemu-iotests/check4
-rw-r--r--tests/qemu-iotests/common.filter8
-rw-r--r--tests/qemu-iotests/common.rc30
-rw-r--r--tests/qemu-iotests/testenv.py7
-rw-r--r--tests/qemu-iotests/testrunner.py9
-rwxr-xr-xtests/qemu-iotests/tests/graph-changes-while-io102
-rw-r--r--tests/qemu-iotests/tests/graph-changes-while-io.out4
-rwxr-xr-xtests/qemu-iotests/tests/mirror-sparse10
-rwxr-xr-xtests/qemu-iotests/tests/qom-set-drive75
-rw-r--r--tests/qemu-iotests/tests/qom-set-drive.out11
-rwxr-xr-xtests/qemu-iotests/tests/write-zeroes-unmap1
-rw-r--r--tests/qtest/aspeed-hace-utils.c646
-rw-r--r--tests/qtest/aspeed-hace-utils.h84
-rw-r--r--tests/qtest/aspeed_hace-test.c577
-rw-r--r--tests/qtest/aspeed_scu-test.c231
-rw-r--r--tests/qtest/aspeed_smc-test.c5
-rw-r--r--tests/qtest/ast2700-hace-test.c98
-rw-r--r--tests/qtest/ast2700-smc-test.c1
-rw-r--r--tests/qtest/bios-tables-test.c303
-rw-r--r--tests/qtest/cpu-plug-test.c2
-rw-r--r--tests/qtest/cxl-test.c58
-rw-r--r--tests/qtest/fuzz/virtio_net_fuzz.c2
-rw-r--r--tests/qtest/libqos/igb.c4
-rw-r--r--tests/qtest/libqos/virtio.c16
-rw-r--r--tests/qtest/libqos/virtio.h2
-rw-r--r--tests/qtest/libqtest.c120
-rw-r--r--tests/qtest/libqtest.h27
-rw-r--r--tests/qtest/meson.build22
-rw-r--r--tests/qtest/migration-helpers.c530
-rw-r--r--tests/qtest/migration/bootfile.c5
-rw-r--r--tests/qtest/migration/bootfile.h1
-rw-r--r--tests/qtest/migration/compression-tests.c18
-rw-r--r--tests/qtest/migration/cpr-tests.c152
-rw-r--r--tests/qtest/migration/framework.c107
-rw-r--r--tests/qtest/migration/framework.h7
-rw-r--r--tests/qtest/migration/migration-qmp.c21
-rw-r--r--tests/qtest/migration/migration-qmp.h2
-rw-r--r--tests/qtest/migration/postcopy-tests.c27
-rw-r--r--tests/qtest/migration/precopy-tests.c83
-rw-r--r--tests/qtest/migration/tls-tests.c51
-rw-r--r--tests/qtest/npcm_gmac-test.c85
-rw-r--r--tests/qtest/qmp-cmd-test.c2
-rw-r--r--tests/qtest/qom-test.c120
-rw-r--r--tests/qtest/qos-test.c5
-rw-r--r--tests/qtest/riscv-csr-test.c4
-rw-r--r--tests/qtest/test-x86-cpuid-compat.c14
-rw-r--r--tests/qtest/vhost-user-test.c31
-rw-r--r--tests/qtest/virtio-scsi-test.c32
-rw-r--r--tests/qtest/vmgenid-test.c2
-rw-r--r--tests/tcg/Makefile.target63
-rw-r--r--tests/tcg/aarch64/Makefile.softmmu-target3
-rw-r--r--tests/tcg/aarch64/Makefile.target34
-rw-r--r--tests/tcg/aarch64/gcs.h80
-rw-r--r--tests/tcg/aarch64/gcspushm.c71
-rw-r--r--tests/tcg/aarch64/gcsss.c74
-rw-r--r--tests/tcg/aarch64/gcsstr.c48
-rw-r--r--tests/tcg/aarch64/gdbstub/test-mte.py1
-rw-r--r--tests/tcg/aarch64/gdbstub/test-sme.py117
-rw-r--r--tests/tcg/aarch64/gdbstub/test-sve-ioctl.py1
-rw-r--r--tests/tcg/aarch64/gdbstub/test-sve.py1
-rw-r--r--tests/tcg/aarch64/system/boot.S172
-rw-r--r--tests/tcg/mips/include/wrappers_mips64r6.h32
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/Makefile40
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32b.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cb.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cd.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32ch.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cw.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32d.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32h.c142
-rw-r--r--tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32w.c142
-rw-r--r--tests/tcg/multiarch/Makefile.target11
-rw-r--r--tests/tcg/multiarch/fnmsub.c37
-rw-r--r--tests/tcg/multiarch/gdbstub/interrupt.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/memory.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/sha1.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/test-proc-mappings.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/test-qxfer-siginfo-read.py1
-rw-r--r--tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py1
-rw-r--r--tests/tcg/multiarch/system/Makefile.softmmu-target16
-rw-r--r--tests/tcg/multiarch/tb-link.c67
-rw-r--r--tests/tcg/plugins/mem.c1
-rw-r--r--tests/tcg/plugins/meson.build4
-rw-r--r--tests/tcg/plugins/patch.c251
-rw-r--r--tests/tcg/riscv64/Makefile.softmmu-target4
-rw-r--r--tests/tcg/riscv64/test-mepc-masking.S73
-rw-r--r--tests/tcg/s390x/gdbstub/test-signals-s390x.py1
-rw-r--r--tests/tcg/s390x/gdbstub/test-svc.py1
-rw-r--r--tests/tcg/x86_64/Makefile.softmmu-target21
-rw-r--r--tests/tcg/x86_64/fma.c17
-rw-r--r--tests/tcg/x86_64/system/patch-target.c22
-rwxr-xr-xtests/tcg/x86_64/system/validate-patch.py39
-rw-r--r--tests/tracetool/dtrace.c32
-rw-r--r--tests/tracetool/dtrace.d10
-rw-r--r--tests/tracetool/dtrace.h45
-rw-r--r--tests/tracetool/dtrace.log-stap15
-rw-r--r--tests/tracetool/dtrace.simpletrace-stap16
-rw-r--r--tests/tracetool/dtrace.stap14
-rw-r--r--tests/tracetool/ftrace.c32
-rw-r--r--tests/tracetool/ftrace.h43
-rw-r--r--tests/tracetool/ftrace.rs40
-rw-r--r--tests/tracetool/log.c32
-rw-r--r--tests/tracetool/log.h47
-rw-r--r--tests/tracetool/log.rs44
-rw-r--r--tests/tracetool/meson.build28
-rw-r--r--tests/tracetool/simple.c61
-rw-r--r--tests/tracetool/simple.h40
-rw-r--r--tests/tracetool/simple.rs40
-rw-r--r--tests/tracetool/syslog.c32
-rw-r--r--tests/tracetool/syslog.h43
-rw-r--r--tests/tracetool/syslog.rs40
-rw-r--r--tests/tracetool/trace-events5
-rwxr-xr-xtests/tracetool/tracetool-test.py109
-rw-r--r--tests/tracetool/ust.c32
-rw-r--r--tests/tracetool/ust.h41
-rw-r--r--tests/tracetool/ust.ust-events-c14
-rw-r--r--tests/tracetool/ust.ust-events-h56
-rw-r--r--tests/tsan/ignore.tsan4
-rw-r--r--tests/uefi-test-tools/Makefile5
-rw-r--r--tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc6
-rw-r--r--tests/uefi-test-tools/uefi-test-build.config10
-rw-r--r--tests/unit/io-channel-helpers.c5
-rw-r--r--tests/unit/socket-helpers.c4
-rw-r--r--tests/unit/test-aio-multithread.c6
-rw-r--r--tests/unit/test-bdrv-drain.c34
-rw-r--r--tests/unit/test-bdrv-graph-mod.c10
-rw-r--r--tests/unit/test-char.c3
-rw-r--r--tests/unit/test-crypto-block.c7
-rw-r--r--tests/unit/test-crypto-cipher.c13
-rw-r--r--tests/unit/test-crypto-secret.c28
-rw-r--r--tests/unit/test-crypto-tlssession.c8
-rw-r--r--tests/unit/test-error-report.c17
-rw-r--r--tests/unit/test-io-channel-tls.c4
-rw-r--r--tests/unit/test-iov.c5
-rw-r--r--tests/unit/test-qga.c17
-rw-r--r--tests/unit/test-util-sockets.c239
-rw-r--r--tests/unit/test-vmstate.c83
-rw-r--r--tests/vm/README2
-rwxr-xr-xtests/vm/freebsd8
-rwxr-xr-xtests/vm/openbsd4
456 files changed, 20035 insertions, 2697 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 23fb722..e47ef4d 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -13,6 +13,7 @@ check-help:
@echo " $(MAKE) check-functional-TARGET Run functional tests for a given target"
@echo " $(MAKE) check-unit Run qobject tests"
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
+ @echo " $(MAKE) check-tracetool Run tracetool generator tests"
@echo " $(MAKE) check-block Run block tests"
ifneq ($(filter $(all-check-targets), check-softfloat),)
@echo " $(MAKE) check-tcg Run TCG tests"
@@ -104,14 +105,17 @@ check-venv: $(TESTS_VENV_TOKEN)
FUNCTIONAL_TARGETS=$(patsubst %-softmmu,check-functional-%, $(filter %-softmmu,$(TARGETS)))
.PHONY: $(FUNCTIONAL_TARGETS)
-$(FUNCTIONAL_TARGETS):
+$(FUNCTIONAL_TARGETS): check-venv
@$(MAKE) SPEED=thorough $(subst -functional,-func,$@)
.PHONY: check-functional
-check-functional:
+check-functional: check-venv
@$(NINJA) precache-functional
@QEMU_TEST_NO_DOWNLOAD=1 $(MAKE) SPEED=thorough check-func check-func-quick
+.PHONY: check-func check-func-quick
+check-func check-func-quick:
+
# Consolidated targets
.PHONY: check check-clean
diff --git a/tests/data/acpi/aarch64/virt/APIC.its_off b/tests/data/acpi/aarch64/virt/APIC.its_off
new file mode 100644
index 0000000..6130cb7
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/APIC.its_off
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT b/tests/data/acpi/aarch64/virt/DSDT
index 36d3e5d..38f01ad 100644
--- a/tests/data/acpi/aarch64/virt/DSDT
+++ b/tests/data/acpi/aarch64/virt/DSDT
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt b/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt
index e6154d0..37a9af7 100644
--- a/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt
+++ b/tests/data/acpi/aarch64/virt/DSDT.acpihmatvirt
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.acpipcihp b/tests/data/acpi/aarch64/virt/DSDT.acpipcihp
new file mode 100644
index 0000000..04427e2
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/DSDT.acpipcihp
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.hpoffacpiindex b/tests/data/acpi/aarch64/virt/DSDT.hpoffacpiindex
new file mode 100644
index 0000000..43ab604
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/DSDT.hpoffacpiindex
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.memhp b/tests/data/acpi/aarch64/virt/DSDT.memhp
index 33f011d..3c39167 100644
--- a/tests/data/acpi/aarch64/virt/DSDT.memhp
+++ b/tests/data/acpi/aarch64/virt/DSDT.memhp
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.pxb b/tests/data/acpi/aarch64/virt/DSDT.pxb
index c0fdc6e..71c632c 100644
--- a/tests/data/acpi/aarch64/virt/DSDT.pxb
+++ b/tests/data/acpi/aarch64/virt/DSDT.pxb
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev
new file mode 100644
index 0000000..e8c2b37
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-dev
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy
new file mode 100644
index 0000000..e8c2b37
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/DSDT.smmuv3-legacy
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.topology b/tests/data/acpi/aarch64/virt/DSDT.topology
index 029d03e..9f22cd3 100644
--- a/tests/data/acpi/aarch64/virt/DSDT.topology
+++ b/tests/data/acpi/aarch64/virt/DSDT.topology
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/DSDT.viot b/tests/data/acpi/aarch64/virt/DSDT.viot
new file mode 100644
index 0000000..dd3775a
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/DSDT.viot
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/HEST b/tests/data/acpi/aarch64/virt/HEST
new file mode 100644
index 0000000..6742729
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/HEST
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/IORT.its_off b/tests/data/acpi/aarch64/virt/IORT.its_off
new file mode 100644
index 0000000..c10da4e
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/IORT.its_off
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev b/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev
new file mode 100644
index 0000000..67be268
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/IORT.smmuv3-dev
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy b/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy
new file mode 100644
index 0000000..41981a4
--- /dev/null
+++ b/tests/data/acpi/aarch64/virt/IORT.smmuv3-legacy
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/PPTT b/tests/data/acpi/aarch64/virt/PPTT
index 7a1258e..15598a9 100644
--- a/tests/data/acpi/aarch64/virt/PPTT
+++ b/tests/data/acpi/aarch64/virt/PPTT
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt b/tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt
index 4eef303..7b613dd 100644
--- a/tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt
+++ b/tests/data/acpi/aarch64/virt/PPTT.acpihmatvirt
Binary files differ
diff --git a/tests/data/acpi/aarch64/virt/PPTT.topology b/tests/data/acpi/aarch64/virt/PPTT.topology
index 3fbcae5..6b864f0 100644
--- a/tests/data/acpi/aarch64/virt/PPTT.topology
+++ b/tests/data/acpi/aarch64/virt/PPTT.topology
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/APIC b/tests/data/acpi/loongarch64/virt/APIC
new file mode 100644
index 0000000..3477789
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/APIC
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/APIC.topology b/tests/data/acpi/loongarch64/virt/APIC.topology
new file mode 100644
index 0000000..da0089d
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/APIC.topology
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/DSDT b/tests/data/acpi/loongarch64/virt/DSDT
new file mode 100644
index 0000000..55aa34f
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/DSDT
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/DSDT.memhp b/tests/data/acpi/loongarch64/virt/DSDT.memhp
new file mode 100644
index 0000000..c0955eb
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/DSDT.memhp
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/DSDT.numamem b/tests/data/acpi/loongarch64/virt/DSDT.numamem
new file mode 100644
index 0000000..61e47e7
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/DSDT.numamem
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/DSDT.topology b/tests/data/acpi/loongarch64/virt/DSDT.topology
new file mode 100644
index 0000000..b2afebc
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/DSDT.topology
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/FACP b/tests/data/acpi/loongarch64/virt/FACP
new file mode 100644
index 0000000..04d8d4c
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/FACP
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/MCFG b/tests/data/acpi/loongarch64/virt/MCFG
new file mode 100644
index 0000000..5f93b05
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/MCFG
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/PPTT b/tests/data/acpi/loongarch64/virt/PPTT
new file mode 100644
index 0000000..15598a9
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/PPTT
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/PPTT.topology b/tests/data/acpi/loongarch64/virt/PPTT.topology
new file mode 100644
index 0000000..7fc9298
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/PPTT.topology
Binary files differ
diff --git a/tests/qapi-schema/doc-bad-section.out b/tests/data/acpi/loongarch64/virt/SLIT
index e69de29..e69de29 100644
--- a/tests/qapi-schema/doc-bad-section.out
+++ b/tests/data/acpi/loongarch64/virt/SLIT
diff --git a/tests/data/acpi/loongarch64/virt/SLIT.numamem b/tests/data/acpi/loongarch64/virt/SLIT.numamem
new file mode 100644
index 0000000..67f0081
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SLIT.numamem
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/SPCR b/tests/data/acpi/loongarch64/virt/SPCR
new file mode 100644
index 0000000..3cc9bbc
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SPCR
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/SRAT b/tests/data/acpi/loongarch64/virt/SRAT
new file mode 100644
index 0000000..ff234ce
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SRAT
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/SRAT.memhp b/tests/data/acpi/loongarch64/virt/SRAT.memhp
new file mode 100644
index 0000000..5253218
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SRAT.memhp
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/SRAT.numamem b/tests/data/acpi/loongarch64/virt/SRAT.numamem
new file mode 100644
index 0000000..2972a9a
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SRAT.numamem
Binary files differ
diff --git a/tests/data/acpi/loongarch64/virt/SRAT.topology b/tests/data/acpi/loongarch64/virt/SRAT.topology
new file mode 100644
index 0000000..4a44831
--- /dev/null
+++ b/tests/data/acpi/loongarch64/virt/SRAT.topology
Binary files differ
diff --git a/tests/data/acpi/rebuild-expected-aml.sh b/tests/data/acpi/rebuild-expected-aml.sh
index c1092fb..cbf9ffe 100755
--- a/tests/data/acpi/rebuild-expected-aml.sh
+++ b/tests/data/acpi/rebuild-expected-aml.sh
@@ -12,7 +12,7 @@
# This work is licensed under the terms of the GNU GPLv2.
# See the COPYING.LIB file in the top-level directory.
-qemu_arches="x86_64 aarch64 riscv64"
+qemu_arches="x86_64 aarch64 riscv64 loongarch64"
if [ ! -e "tests/qtest/bios-tables-test" ]; then
echo "Test: bios-tables-test is required! Run make check before this script."
@@ -37,7 +37,7 @@ if [ -z "$qemu_bins" ]; then
echo "Only the following architectures are currently supported: $qemu_arches"
echo "None of these configured!"
echo "To fix, run configure \
- --target-list=x86_64-softmmu,aarch64-softmmu,riscv64-softmmu"
+ --target-list=x86_64-softmmu,aarch64-softmmu,riscv64-softmmu,loongarch64-softmmu"
exit 1;
fi
diff --git a/tests/data/acpi/riscv64/virt/APIC b/tests/data/acpi/riscv64/virt/APIC
index 66a25df..3fb5b75 100644
--- a/tests/data/acpi/riscv64/virt/APIC
+++ b/tests/data/acpi/riscv64/virt/APIC
Binary files differ
diff --git a/tests/data/acpi/riscv64/virt/DSDT b/tests/data/acpi/riscv64/virt/DSDT
index 6a33f56..527f239 100644
--- a/tests/data/acpi/riscv64/virt/DSDT
+++ b/tests/data/acpi/riscv64/virt/DSDT
Binary files differ
diff --git a/tests/data/acpi/riscv64/virt/FACP b/tests/data/acpi/riscv64/virt/FACP
index a5276b6..78e1b14 100644
--- a/tests/data/acpi/riscv64/virt/FACP
+++ b/tests/data/acpi/riscv64/virt/FACP
Binary files differ
diff --git a/tests/data/acpi/riscv64/virt/RHCT b/tests/data/acpi/riscv64/virt/RHCT
index 13c8025..52a4cc4 100644
--- a/tests/data/acpi/riscv64/virt/RHCT
+++ b/tests/data/acpi/riscv64/virt/RHCT
Binary files differ
diff --git a/tests/data/acpi/x86/microvm/DSDT.pcie b/tests/data/acpi/x86/microvm/DSDT.pcie
index 8eacd21..ba258f4 100644
--- a/tests/data/acpi/x86/microvm/DSDT.pcie
+++ b/tests/data/acpi/x86/microvm/DSDT.pcie
Binary files differ
diff --git a/tests/data/uefi-boot-images/bios-tables-test.loongarch64.iso.qcow2 b/tests/data/uefi-boot-images/bios-tables-test.loongarch64.iso.qcow2
new file mode 100644
index 0000000..18daee0
--- /dev/null
+++ b/tests/data/uefi-boot-images/bios-tables-test.loongarch64.iso.qcow2
Binary files differ
diff --git a/tests/data/vmstate-static-checker/aarch64/virt-7.2.json b/tests/data/vmstate-static-checker/aarch64/virt-7.2.json
new file mode 100644
index 0000000..d7491be
--- /dev/null
+++ b/tests/data/vmstate-static-checker/aarch64/virt-7.2.json
@@ -0,0 +1,2571 @@
+{
+ "vmschkmachine": {
+ "Name": "virt-7.2"
+ },
+ "gpex-pcihost": {
+ "Name": "gpex-pcihost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "arm_gic": {
+ "Name": "arm_gic",
+ "version_id": 12,
+ "minimum_version_id": 12,
+ "Description": {
+ "name": "arm_gic",
+ "version_id": 12,
+ "minimum_version_id": 12,
+ "Fields": [
+ {
+ "field": "ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cpu_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 7,
+ "Description": {
+ "name": "arm_gic_irq_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "active",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "model",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "edge_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "group",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "irq_target",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sgi_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "running_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "current_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "bpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "abpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "nsapr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "arm_gic_virt_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "h_hcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_misr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_lr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cpu_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "priority_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "running_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "current_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "bpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "abpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "arm-gicv3-its-common": {
+ "Name": "arm-gicv3-its-common",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "arm_gicv3_its",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iidr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cbaser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "cwriter",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "creadr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "baser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "arm-gicv3-common": {
+ "Name": "arm-gicv3-common",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "arm_gicv3",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "gicd_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicd_statusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "group",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "grpmod",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "active",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "edge_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicd_ipriority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "gicd_irouter",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "gicd_nsacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cpu",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 664,
+ "Description": {
+ "name": "arm_gicv3_cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_statusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_waker",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_propbaser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "gicr_pendbaser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "gicr_igroupr0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_ienabler0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_ipendr0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_iactiver0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "edge_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_igrpmodr0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_nsacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gicr_ipriorityr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "icc_ctlr_el1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "icc_pmr_el1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "icc_bpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "icc_apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "icc_igrpen",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "icc_ctlr_el3",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "arm_gicv3_cpu/virt",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ich_apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "ich_hcr_el2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "ich_lr_el2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "ich_vmcr_el2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "arm_gicv3_cpu/sre_el1",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "icc_sre_el1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "arm_gicv3_cpu/gicv4",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "gicr_vpropbaser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "gicr_vpendbaser",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "arm_gicv3/gicd_no_migration_shift_bug",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "gicd_no_migration_shift_bug",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg": {
+ "Name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "cfi.pflash01": {
+ "Name": "cfi.pflash01",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "pflash_cfi01",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "wcycle",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "counter",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pflash_cfi01_blk_write",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "blk_bytes",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ },
+ {
+ "field": "blk_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pl061_luminary": {
+ "Name": "pl061_luminary",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Description": {
+ "name": "pl061",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Fields": [
+ {
+ "field": "locked",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "old_out_data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "old_in_data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dir",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "isense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ibe",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "im",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "istate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "afsel",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr2r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr4r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr8r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "odr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "pur",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "pdr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "slr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "den",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "amsel",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "pl011_luminary": {
+ "Name": "pl011_luminary",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "pl011",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "readbuff",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "lcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dmacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "int_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "int_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_fifo",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ilpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ibrd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "fbrd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ifl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_pos",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pl011/clock",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "clk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pl061": {
+ "Name": "pl061",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Description": {
+ "name": "pl061",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Fields": [
+ {
+ "field": "locked",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "old_out_data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "old_in_data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dir",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "isense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ibe",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "im",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "istate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "afsel",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr2r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr4r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dr8r",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "odr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "pur",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "pdr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "slr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "den",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "amsel",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "vmcoreinfo": {
+ "Name": "vmcoreinfo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "vmcoreinfo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "has_vmcoreinfo",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "vmcoreinfo.host_format",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "vmcoreinfo.guest_format",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "vmcoreinfo.size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vmcoreinfo.paddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "arm_gic_common": {
+ "Name": "arm_gic_common",
+ "version_id": 12,
+ "minimum_version_id": 12,
+ "Description": {
+ "name": "arm_gic",
+ "version_id": 12,
+ "minimum_version_id": 12,
+ "Fields": [
+ {
+ "field": "ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cpu_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 7,
+ "Description": {
+ "name": "arm_gic_irq_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "active",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "model",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "edge_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "group",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "irq_target",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sgi_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "running_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "current_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "bpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "abpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "nsapr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "arm_gic_virt_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "h_hcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_misr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_lr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "h_apr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cpu_ctlr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "priority_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "running_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "current_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "bpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "abpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "arm-smmuv3": {
+ "Name": "arm-smmuv3",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "smmuv3",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "features",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "sid_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sid_split",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr0ack",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "statusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq_ctrl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gerror",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gerrorn",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gerror_irq_cfg0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "gerror_irq_cfg1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "gerror_irq_cfg2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "strtab_base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "strtab_base_cfg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "eventq_irq_cfg0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "eventq_irq_cfg1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "eventq_irq_cfg2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cmdq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "smmuv3_queue",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "prod",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cons",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "log2size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "eventq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "smmuv3_queue",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "prod",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cons",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "log2size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "pl011": {
+ "Name": "pl011",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "pl011",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "readbuff",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "lcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "dmacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "int_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "int_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_fifo",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ilpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ibrd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "fbrd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ifl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_pos",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "read_trigger",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pl011/clock",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "clk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "armv7m": {
+ "Name": "armv7m",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "armv7m",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "refclk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "cpuclk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "fw_cfg_mem": {
+ "Name": "fw_cfg_mem",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pl031": {
+ "Name": "pl031",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "pl031",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tick_offset_vmstate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "mr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "lr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "im",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "is",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pl031/tick-offset",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tick_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg_io": {
+ "Name": "fw_cfg_io",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "virtio-serial-device": {
+ "Name": "virtio-serial-device",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Description": {
+ "name": "virtio-console",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "virtio",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ }
+ ]
+ }
+ },
+ "acpi-ged": {
+ "Name": "acpi-ged",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "acpi-ged",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ged_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 560,
+ "Description": {
+ "name": "acpi-ged-state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sel",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "acpi-ged/memhp",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "memhp_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 304,
+ "Description": {
+ "name": "memory hotplug state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "selector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "devs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "memory hotplug device state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "is_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "is_inserting",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ost_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ost_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "acpi-ged/ghes",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ghes_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "acpi-ghes",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ghes_addr_le",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pcie-host-bridge": {
+ "Name": "pcie-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "gpio-key": {
+ "Name": "gpio-key",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "gpio-key",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "armv7m_nvic": {
+ "Name": "armv7m_nvic",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Description": {
+ "name": "armv7m_nvic",
+ "version_id": 4,
+ "minimum_version_id": 4,
+ "Fields": [
+ {
+ "field": "vectors",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 6,
+ "Description": {
+ "name": "armv7m_nvic_info",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "prio",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "active",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "prigroup[M_REG_NS]",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "armv7m_nvic/m-security",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sec_vectors",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 6,
+ "Description": {
+ "name": "armv7m_nvic_info",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "prio",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "active",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "prigroup[M_REG_S]",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "itns",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pci-host-bridge": {
+ "Name": "pci-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "gpex-root": {
+ "Name": "gpex-root",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "gpex_root",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "parent_obj",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2608,
+ "Description": {
+ "name": "PCIDevice",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "version_id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 256
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4096
+ },
+ {
+ "field": "irq_state",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "armv7m_systick": {
+ "Name": "armv7m_systick",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Description": {
+ "name": "armv7m_systick",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "refclk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "cpuclk",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "clock",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "clock/muldiv",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "multiplier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "divider",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "control",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "tick",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "ptimer",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "ptimer",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "limit",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "delta",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "period_frac",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "period",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "last_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "next_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/vmstate-static-checker-data/dump1.json b/tests/data/vmstate-static-checker/dump1.json
index 334ec07..334ec07 100644
--- a/tests/vmstate-static-checker-data/dump1.json
+++ b/tests/data/vmstate-static-checker/dump1.json
diff --git a/tests/vmstate-static-checker-data/dump2.json b/tests/data/vmstate-static-checker/dump2.json
index 7184e9c..7184e9c 100644
--- a/tests/vmstate-static-checker-data/dump2.json
+++ b/tests/data/vmstate-static-checker/dump2.json
diff --git a/tests/data/vmstate-static-checker/m68k/virt-7.2.json b/tests/data/vmstate-static-checker/m68k/virt-7.2.json
new file mode 100644
index 0000000..16bee8c
--- /dev/null
+++ b/tests/data/vmstate-static-checker/m68k/virt-7.2.json
@@ -0,0 +1,2936 @@
+{
+ "vmschkmachine": {
+ "Name": "virt-7.2"
+ },
+ "m68020-m68k-cpu": {
+ "Name": "m68020-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "m68030-m68k-cpu": {
+ "Name": "m68030-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg": {
+ "Name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "m68k-irq-controller": {
+ "Name": "m68k-irq-controller",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "m68k-irqc",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ipr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "virt-ctrl": {
+ "Name": "virt-ctrl",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "virt-ctrl",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "irq_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "m68040-m68k-cpu": {
+ "Name": "m68040-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "goldfish_pic": {
+ "Name": "goldfish_pic",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "goldfish_pic",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "goldfish_tty": {
+ "Name": "goldfish_tty",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "goldfish_tty",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "data_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "data_ptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "int_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "rx_fifo",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "Fifo8",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "data",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 0
+ },
+ {
+ "field": "head",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "num",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "m68000-m68k-cpu": {
+ "Name": "m68000-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "m68010-m68k-cpu": {
+ "Name": "m68010-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "m68060-m68k-cpu": {
+ "Name": "m68060-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg_mem": {
+ "Name": "fw_cfg_mem",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "any-m68k-cpu": {
+ "Name": "any-m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg_io": {
+ "Name": "fw_cfg_io",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "virtio-serial-device": {
+ "Name": "virtio-serial-device",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Description": {
+ "name": "virtio-console",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "virtio",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ }
+ ]
+ }
+ },
+ "goldfish_rtc": {
+ "Name": "goldfish_rtc",
+ "version_id": 3,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "goldfish_rtc",
+ "version_id": 3,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tick_offset_vmstate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "alarm_next",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "alarm_running",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "time_high",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "tick_offset",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "m68k-cpu": {
+ "Name": "m68k-cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "cpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.dregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.aregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.current_sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_op",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_x",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_n",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_v",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cc_z",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_vector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.pending_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "cpu/fpu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.fpcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fpsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.fregs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "env.fp_result",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16,
+ "Description": {
+ "name": "freg",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "freg_tmp",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "tmp_mant",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tmp_exp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "cpu/cf_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.macc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "env.macsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mac_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.rambar0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mbar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_mmu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.mmu.ar",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.ssw",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.tcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "env.mmu.urp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.srp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.fault",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "env.mmu.ttr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.mmu.mmusr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "cpu/68040_spregs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "env.vbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.cacr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.sfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "env.dfc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/data/vmstate-static-checker/ppc64/pseries-7.2.json b/tests/data/vmstate-static-checker/ppc64/pseries-7.2.json
new file mode 100644
index 0000000..330bbbe
--- /dev/null
+++ b/tests/data/vmstate-static-checker/ppc64/pseries-7.2.json
@@ -0,0 +1,1068 @@
+{
+ "vmschkmachine": {
+ "Name": "pseries-7.2"
+ },
+ "spapr-nvram": {
+ "Name": "spapr-nvram",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr_nvram",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "buf",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 0
+ }
+ ]
+ }
+ },
+ "xive-source": {
+ "Name": "xive-source",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "xive-source",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "nr_irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "status",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 0
+ }
+ ]
+ }
+ },
+ "xive-tctx": {
+ "Name": "xive-tctx",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "xive-tctx",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "regs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 64
+ }
+ ]
+ }
+ },
+ "pci-host-bridge": {
+ "Name": "pci-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "ics-spapr": {
+ "Name": "ics-spapr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ics",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "nr_irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "ics/irq",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "server",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "saved_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "scsi-cd": {
+ "Name": "scsi-cd",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "scsi-disk",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "qdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 608,
+ "Description": {
+ "name": "SCSIDevice",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "unit_attention.key",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unit_attention.asc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unit_attention.ascq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense_is_ua",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "requests",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "SCSIDevice/sense",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "media_changed",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "media_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "eject_request",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tray_open",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tray_locked",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "spapr-xive": {
+ "Name": "spapr-xive",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr-xive",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "nr_irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "eat",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "spapr-xive/eas",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "w",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ {
+ "field": "endt",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 32,
+ "Description": {
+ "name": "spapr-xive/end",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "w0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w3",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w4",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w5",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w6",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "w7",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "scsi-hd": {
+ "Name": "scsi-hd",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "scsi-disk",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "qdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 608,
+ "Description": {
+ "name": "SCSIDevice",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "unit_attention.key",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unit_attention.asc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unit_attention.ascq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense_is_ua",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "requests",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "SCSIDevice/sense",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sense",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "media_changed",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "media_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "eject_request",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tray_open",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tray_locked",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "fw_cfg_mem": {
+ "Name": "fw_cfg_mem",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "spapr-vty": {
+ "Name": "spapr-vty",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr_vty",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 848,
+ "Description": {
+ "name": "spapr_vio",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "signal_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qladdr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qsize",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "crq.qnext",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ {
+ "field": "in",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "out",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "buf",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ },
+ "spapr-wdt": {
+ "Name": "spapr-wdt",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr_watchdog",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 48
+ },
+ {
+ "field": "action",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "leave_others",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "fw_cfg_io": {
+ "Name": "fw_cfg_io",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "spapr-vscsi": {
+ "Name": "spapr-vscsi",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr_vscsi",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "vdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 848,
+ "Description": {
+ "name": "spapr_vio",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "signal_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qladdr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qsize",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "crq.qnext",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "spapr-rtc": {
+ "Name": "spapr-rtc",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr/rtc",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "ns_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "spapr-vlan": {
+ "Name": "spapr-vlan",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "spapr_llan",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "sdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 848,
+ "Description": {
+ "name": "spapr_vio",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "signal_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qladdr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "crq.qsize",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "crq.qnext",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ {
+ "field": "isopen",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "buf_list",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "add_buf_ptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "use_buf_ptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rx_bufs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rxq_ptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "spapr_llan/rx_pools",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "rx_pool",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "spapr_llan/rx_buffer_pool",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "bufsize",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "bds",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "fw_cfg": {
+ "Name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "ics": {
+ "Name": "ics",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ics",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "nr_irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "irqs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8,
+ "Description": {
+ "name": "ics/irq",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "server",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "saved_priority",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/data/vmstate-static-checker/s390x/s390-ccw-virtio-7.2.json b/tests/data/vmstate-static-checker/s390x/s390-ccw-virtio-7.2.json
new file mode 100644
index 0000000..9698852
--- /dev/null
+++ b/tests/data/vmstate-static-checker/s390x/s390-ccw-virtio-7.2.json
@@ -0,0 +1,475 @@
+{
+ "vmschkmachine": {
+ "Name": "s390-ccw-virtio-7.2"
+ },
+ "sclpquiesce": {
+ "Name": "sclpquiesce",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "sclpquiesce",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "event_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "s390-sclp-event-facility": {
+ "Name": "s390-sclp-event-facility",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "vmstate-event-facility",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "receive_mask_pieces[1]",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "vmstate-event-facility/mask64",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "receive_mask_pieces[0]",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "vmstate-event-facility/mask_length",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "mask_length",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "zpci": {
+ "Name": "zpci",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "zpci",
+ "version_id": 0,
+ "minimum_version_id": 0
+ }
+ },
+ "sclpconsole": {
+ "Name": "sclpconsole",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "sclpconsole",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "event.event_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "iov",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "iov_sclp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iov_bs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iov_data_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "iov_sclp_rest",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "virtio-serial-device": {
+ "Name": "virtio-serial-device",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Description": {
+ "name": "virtio-console",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "virtio",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ }
+ ]
+ }
+ },
+ "sclplmconsole": {
+ "Name": "sclplmconsole",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "sclplmconsole",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "event.event_pending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "write_errors",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "length",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "buf",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "s390-pcihost": {
+ "Name": "s390-pcihost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "s390-flic-qemu": {
+ "Name": "s390-flic-qemu",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "qemu-s390-flic",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "simm",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "nimm",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "fw_cfg_io": {
+ "Name": "fw_cfg_io",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "s390-ipl": {
+ "Name": "s390-ipl",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "ipl",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "compat_start_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "compat_bios_start_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "iplb",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4096,
+ "Description": {
+ "name": "ipl/iplb",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "reserved1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "devno",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "reserved2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ipl/iplb_extended",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "reserved_ext",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "iplb_valid",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cssid",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ssid",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "devno",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ }
+ ]
+ }
+ },
+ "pci-host-bridge": {
+ "Name": "pci-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "fw_cfg_mem": {
+ "Name": "fw_cfg_mem",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/data/vmstate-static-checker/x86_64/pc-q35-7.2.json b/tests/data/vmstate-static-checker/x86_64/pc-q35-7.2.json
new file mode 100644
index 0000000..e527dff
--- /dev/null
+++ b/tests/data/vmstate-static-checker/x86_64/pc-q35-7.2.json
@@ -0,0 +1,3297 @@
+{
+ "vmschkmachine": {
+ "Name": "pc-q35-7.2"
+ },
+ "fw_cfg": {
+ "Name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pcie-host-bridge": {
+ "Name": "pcie-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "isa-pit": {
+ "Name": "isa-pit",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "i8254",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "channels[0].irq_disabled",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "channels",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 56,
+ "Description": {
+ "name": "pit channel",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "latched_count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "count_latched",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status_latched",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "read_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "write_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "write_latch",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "rw_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "bcd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "gate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "count_load_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "next_transition_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ {
+ "field": "channels[0].next_transition_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "mch": {
+ "Name": "mch",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "mch",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "parent_obj",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2608,
+ "Description": {
+ "name": "PCIDevice",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "version_id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 256
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4096
+ },
+ {
+ "field": "irq_state",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ },
+ {
+ "field": "unused",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "pic-common": {
+ "Name": "pic-common",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "i8259",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "last_irr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "irr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "imr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "isr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority_add",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "irq_base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "read_reg_select",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "poll",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "special_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "init_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "auto_eoi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "rotate_on_auto_eoi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "special_fully_nested_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "init4",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "single_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "elcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "ICH9-LPC": {
+ "Name": "ICH9-LPC",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ICH9LPC",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "d",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2608,
+ "Description": {
+ "name": "PCIDevice",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "version_id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 256
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4096
+ },
+ {
+ "field": "irq_state",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ },
+ {
+ "field": "apm",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 304,
+ "Description": {
+ "name": "APM State",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "apmc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "apms",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "pm",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 6480,
+ "Description": {
+ "name": "ich9_pm",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "acpi_regs.pm1.evt.sts",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "acpi_regs.pm1.evt.en",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "acpi_regs.pm1.cnt.cnt",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "acpi_regs.tmr.timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "acpi_regs.tmr.overflow_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "acpi_regs.gpe.sts",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "acpi_regs.gpe.en",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smi_en",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "smi_sts",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ich9_pm/memhp",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "acpi_memory_hotplug",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 304,
+ "Description": {
+ "name": "memory hotplug state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "selector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "devs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "memory hotplug device state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "is_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "is_inserting",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ost_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ost_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "ich9_pm/tco",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tco_regs",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 320,
+ "Description": {
+ "name": "tco io device status",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tco.rld",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "tco.din",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco.dout",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco.sts1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "tco.sts2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "tco.cnt1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "tco.cnt2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "tco.msg1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco.msg2",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco.wdcnt",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco.tmr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "sw_irq_gen",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tco_timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "expire_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "timeouts_no",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "ich9_pm/cpuhp",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cpuhp_state",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 304,
+ "Description": {
+ "name": "CPU hotplug state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "selector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "command",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "devs",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 32,
+ "Description": {
+ "name": "CPU hotplug device state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "is_inserting",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "is_removing",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ost_event",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ost_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "ich9_pm/pcihp",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "acpi_pci_hotplug.hotplug_select",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "acpi_pci_hotplug.acpi_pcihp_pci_status",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 12,
+ "Description": {
+ "name": "acpi_pcihp_pci_status",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "up",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "down",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ {
+ "field": "acpi_pci_hotplug.acpi_index",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "chip_config",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sci_level",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ICH9LPC/rst_cnt",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "rst_cnt",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "ICH9LPC/smi_feat",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "smi_guest_features_le",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smi_features_ok",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smi_negotiated_features",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "pit-common": {
+ "Name": "pit-common",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "i8254",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "channels[0].irq_disabled",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "channels",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 56,
+ "Description": {
+ "name": "pit channel",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "latched_count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "count_latched",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status_latched",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "read_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "write_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "write_latch",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "rw_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "bcd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "gate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "count_load_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "next_transition_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ {
+ "field": "channels[0].next_transition_time",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "vmgenid": {
+ "Name": "vmgenid",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "vmgenid",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "vmgenid_addr_le",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "ioapic-common": {
+ "Name": "ioapic-common",
+ "version_id": 3,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ioapic",
+ "version_id": 3,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ioregsel",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unused",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "irr",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ioredtbl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "isa-i8259": {
+ "Name": "isa-i8259",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "i8259",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "last_irr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "irr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "imr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "isr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "priority_add",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "irq_base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "read_reg_select",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "poll",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "special_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "init_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "auto_eoi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "rotate_on_auto_eoi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "special_fully_nested_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "init4",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "single_mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "elcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "cfi.pflash01": {
+ "Name": "cfi.pflash01",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "pflash_cfi01",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "wcycle",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "counter",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pflash_cfi01_blk_write",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "blk_bytes",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 0
+ },
+ {
+ "field": "blk_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "i8042-mmio": {
+ "Name": "i8042-mmio",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "pckbd-mmio",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "kbd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2328,
+ "Description": {
+ "name": "pckbd",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "write_cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending_tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pckbd_outport",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "outport",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "pckbd/extended_state",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "migration_flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "obsrc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "obdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cbdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "isa-serial": {
+ "Name": "isa-serial",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "serial",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 656,
+ "Description": {
+ "name": "serial",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "divider",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "rbr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "iir",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "lcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mcr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "lsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "msr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "scr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "fcr_vmstate",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "serial/thr_ipending",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "thr_ipending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "serial/tsr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tsr_retry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "thr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tsr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "serial/recv_fifo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "recv_fifo",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "Fifo8",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "data",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 0
+ },
+ {
+ "field": "head",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "num",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "serial/xmit_fifo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "xmit_fifo",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 24,
+ "Description": {
+ "name": "Fifo8",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "data",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 0
+ },
+ {
+ "field": "head",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "num",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ },
+ {
+ "name": "serial/fifo_timeout_timer",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "fifo_timeout_timer",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "serial/timeout_ipending",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "timeout_ipending",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "serial/poll",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "poll_msl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "modem_status_poll",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "ps2-mouse": {
+ "Name": "ps2-mouse",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "ps2mouse",
+ "version_id": 2,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "parent_obj",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1104,
+ "Description": {
+ "name": "PS2 Common State",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "write_cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.rptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.wptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 256
+ }
+ ]
+ }
+ },
+ {
+ "field": "mouse_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_resolution",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_sample_rate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_wrap",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_type",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_detect_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mouse_dx",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "mouse_dy",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "mouse_dz",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "mouse_buttons",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "kvmvapic": {
+ "Name": "kvmvapic",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "kvm-tpr-opt",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "rom_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 124,
+ "Description": {
+ "name": "kvmvapic-guest-rom",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "unused",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "vaddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "fixup_start",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "fixup_end",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vapic_vaddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vapic_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vcpu_shift",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "real_tpr_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "up",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 44,
+ "Description": {
+ "name": "kvmvapic-handlers",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "set_tpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "set_tpr_eax",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "get_tpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "get_tpr_stack",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ {
+ "field": "mp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 44,
+ "Description": {
+ "name": "kvmvapic-handlers",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "set_tpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "set_tpr_eax",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "get_tpr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "get_tpr_stack",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "real_tpr_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rom_state_vaddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vapic_paddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "rom_state_paddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "ich9-ahci": {
+ "Name": "ich9-ahci",
+ "version_id": 1,
+ "minimum_version_id": 0,
+ "Description": {
+ "name": "ich9_ahci",
+ "version_id": 1,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "parent_obj",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2608,
+ "Description": {
+ "name": "PCIDevice",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "version_id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 256
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4096
+ },
+ {
+ "field": "irq_state",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ },
+ {
+ "field": "ahci",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 624,
+ "Description": {
+ "name": "ahci",
+ "version_id": 1,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 6088,
+ "Description": {
+ "name": "ahci port",
+ "version_id": 1,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "port",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 2304,
+ "Description": {
+ "name": "ide_bus",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unit",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ide_bus/error",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "error_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "retry_sector_num",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "retry_nsector",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "retry_unit",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "port.ifs[0]",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 984,
+ "Description": {
+ "name": "ide_drive",
+ "version_id": 3,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "mult_sectors",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "identify_set",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "identify_data",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 512
+ },
+ {
+ "field": "feature",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "error",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "nsector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "sector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "lcyl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hcyl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hob_feature",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hob_sector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hob_nsector",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hob_lcyl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "hob_hcyl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "select",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "lba48",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "sense_key",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "asc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cdrom_changed",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ide_drive/pio_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "req_nb_sectors",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "io_buffer",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cur_io_buffer_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "cur_io_buffer_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "end_transfer_fn_idx",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "elementary_transfer_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "packet_transfer_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "ide_drive/tray_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "tray_open",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "tray_locked",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "ide_drive/atapi/gesn_state",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "events.new_media",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "events.eject_request",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ },
+ {
+ "field": "port_state",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "finished",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.lst_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.lst_addr_hi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.fis_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.fis_addr_hi",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.irq_stat",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.irq_mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.tfdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.sig",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.scr_stat",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.scr_ctl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.scr_err",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.scr_act",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "port_regs.cmd_issue",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "done_first_drq",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "busy_slot",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "init_d2h_sent",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ncq_tfs",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 112,
+ "Description": {
+ "name": "ncq state",
+ "version_id": 1,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "sector_count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "lba",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "tag",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "slot",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "used",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "halt",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ {
+ "field": "control_regs.cap",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "control_regs.ghc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "control_regs.irqstatus",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "control_regs.impl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "control_regs.version",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "idp_index",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ports",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "i8042": {
+ "Name": "i8042",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Description": {
+ "name": "pckbd",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "kbd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2328,
+ "Description": {
+ "name": "pckbd",
+ "version_id": 3,
+ "minimum_version_id": 3,
+ "Fields": [
+ {
+ "field": "write_cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pending_tmp",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "pckbd_outport",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "outport",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "pckbd/extended_state",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "migration_flags",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "obsrc",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "obdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "cbdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "fw_cfg_io": {
+ "Name": "fw_cfg_io",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "vmcoreinfo": {
+ "Name": "vmcoreinfo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "vmcoreinfo",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "has_vmcoreinfo",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "vmcoreinfo.host_format",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "vmcoreinfo.guest_format",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "vmcoreinfo.size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "vmcoreinfo.paddr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "ps2-kbd": {
+ "Name": "ps2-kbd",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Description": {
+ "name": "ps2kbd",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "parent_obj",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1104,
+ "Description": {
+ "name": "PS2 Common State",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "write_cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.rptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.wptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.count",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "queue.data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 256
+ }
+ ]
+ }
+ },
+ {
+ "field": "scan_enabled",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "translate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "scancode_set",
+ "version_id": 3,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "ps2kbd/ledstate",
+ "version_id": 3,
+ "minimum_version_id": 2,
+ "Fields": [
+ {
+ "field": "ledstate",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ },
+ {
+ "name": "ps2kbd/need_high_bit",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "need_high_bit",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ },
+ {
+ "name": "ps2kbd/command_reply_queue",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "parent_obj.queue.cwptr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ ]
+ }
+ },
+ "ICH9-SMB": {
+ "Name": "ICH9-SMB",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ich9_smb",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "dev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2608,
+ "Description": {
+ "name": "PCIDevice",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "version_id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 256
+ },
+ {
+ "field": "config",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4096
+ },
+ {
+ "field": "irq_state",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 16
+ }
+ ]
+ }
+ },
+ {
+ "field": "irq_enabled",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 1
+ },
+ {
+ "field": "smb",
+ "version_id": 1,
+ "field_exists": true,
+ "size": 384,
+ "Description": {
+ "name": "pmsmb",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "smb_stat",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_ctl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_cmd",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_data0",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_data1",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_index",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "smb_data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_auxctl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "smb_blkdata",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "i2c_enable",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "op_done",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "in_i2c_block_read",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "start_transaction_on_status_read",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "isa-pcspk": {
+ "Name": "isa-pcspk",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "pcspk",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "data_on",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "dummy_refresh_clock",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "acpi-erst": {
+ "Name": "acpi-erst",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "acpi-erst",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "operation",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "busy_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "command_status",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "record_offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "reg_action",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "reg_value",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "record_identifier",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "next_record_index",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "i8257": {
+ "Name": "i8257",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "dma",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "command",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "mask",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "flip_flop",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "dshift",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "regs",
+ "version_id": 1,
+ "field_exists": false,
+ "size": 40,
+ "Description": {
+ "name": "dma_regs",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "now",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "base",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "page",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "pageh",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "dack",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "eop",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ }
+ ]
+ }
+ },
+ "port92": {
+ "Name": "port92",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "port92",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "outport",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "q35-pcihost": {
+ "Name": "q35-pcihost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "ioapic": {
+ "Name": "ioapic",
+ "version_id": 3,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "ioapic",
+ "version_id": 3,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "id",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "ioregsel",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "unused",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "irr",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "ioredtbl",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ },
+ "smbus-eeprom": {
+ "Name": "smbus-eeprom",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "smbus-eeprom",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "smbusdev",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 216,
+ "Description": {
+ "name": "smbus-device",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "i2c",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 168,
+ "Description": {
+ "name": "I2CSlave",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "address",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "mode",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "data_len",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ },
+ {
+ "field": "data_buf",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ {
+ "field": "data",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "offset",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ },
+ {
+ "field": "accessed",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 1
+ }
+ ]
+ }
+ },
+ "pci-host-bridge": {
+ "Name": "pci-host-bridge",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "PCIHost",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "config_reg",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 4
+ }
+ ]
+ }
+ },
+ "fw_cfg_mem": {
+ "Name": "fw_cfg_mem",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Description": {
+ "name": "fw_cfg",
+ "version_id": 2,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "cur_entry",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 2
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 0,
+ "field_exists": true,
+ "size": 4
+ },
+ {
+ "field": "cur_offset",
+ "version_id": 2,
+ "field_exists": false,
+ "size": 4
+ }
+ ],
+ "Subsections": [
+ {
+ "name": "fw_cfg/dma",
+ "version_id": 0,
+ "minimum_version_id": 0,
+ "Fields": [
+ {
+ "field": "dma_addr",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ },
+ {
+ "name": "fw_cfg/acpi_mr",
+ "version_id": 1,
+ "minimum_version_id": 1,
+ "Fields": [
+ {
+ "field": "table_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "linker_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ },
+ {
+ "field": "rsdp_mr_size",
+ "version_id": 0,
+ "field_exists": false,
+ "size": 8
+ }
+ ]
+ }
+ ]
+ }
+ }
+}
diff --git a/tests/decode/meson.build b/tests/decode/meson.build
index b13fada..63405ca 100644
--- a/tests/decode/meson.build
+++ b/tests/decode/meson.build
@@ -41,6 +41,7 @@ succ_tests = [
'succ_argset_type1.decode',
'succ_function.decode',
'succ_ident1.decode',
+ 'succ_infer1.decode',
'succ_named_field.decode',
'succ_pattern_group_nest1.decode',
'succ_pattern_group_nest2.decode',
diff --git a/tests/decode/succ_infer1.decode b/tests/decode/succ_infer1.decode
new file mode 100644
index 0000000..6fa40ba
--- /dev/null
+++ b/tests/decode/succ_infer1.decode
@@ -0,0 +1,4 @@
+&rprr_load rd pg rn rm dtype nreg
+@rprr_load .... .... ... rm:5 ... pg:3 rn:5 rd:5 &rprr_load
+
+LD1Q 1100 0100 000 rm:5 101 pg:3 rn:5 rd:5
diff --git a/tests/docker/Makefile.include b/tests/docker/Makefile.include
index fa1cbb6..3959d8a 100644
--- a/tests/docker/Makefile.include
+++ b/tests/docker/Makefile.include
@@ -185,8 +185,10 @@ docker:
docker-help: docker
+# Where QEMU caches build artefacts
+DOCKER_QEMU_CACHE_DIR := $$HOME/.cache/qemu
# Use a global constant ccache directory to speed up repetitive builds
-DOCKER_CCACHE_DIR := $$HOME/.cache/qemu-docker-ccache
+DOCKER_QEMU_CCACHE_DIR := DOCKER_QEMU_CACHE_DIR/docker-ccache
# This rule if for directly running against an arbitrary docker target.
# It is called by the expanded docker targets (e.g. make
@@ -195,7 +197,7 @@ DOCKER_CCACHE_DIR := $$HOME/.cache/qemu-docker-ccache
# For example: make docker-run TEST="test-quick" IMAGE="debian:arm64" EXECUTABLE=./aarch64-linux-user/qemu-aarch64
#
docker-run: docker-qemu-src
- @mkdir -p "$(DOCKER_CCACHE_DIR)"
+ @mkdir -p "$(DOCKER_QEMU_CCACHE_DIR)"
@if test -z "$(IMAGE)" || test -z "$(TEST)"; \
then echo "Invalid target $(IMAGE)/$(TEST)"; exit 1; \
fi
@@ -222,8 +224,8 @@ docker-run: docker-qemu-src
-e V=$V -e J=$J -e DEBUG=$(DEBUG) \
-e SHOW_ENV=$(SHOW_ENV) \
$(if $(NOUSER),, \
- -e CCACHE_DIR=/var/tmp/ccache \
- -v $(DOCKER_CCACHE_DIR):/var/tmp/ccache:z \
+ -v $(DOCKER_QEMU_CACHE_DIR):$(DOCKER_QEMU_CACHE_DIR) \
+ -e CCACHE_DIR=$(DOCKER_QEMU_CCACHE_DIR) \
) \
-v $$(readlink -e $(DOCKER_SRC_COPY)):/var/tmp/qemu:z$(COMMA)ro \
$(IMAGE) \
diff --git a/tests/docker/common.rc b/tests/docker/common.rc
index a611e6a..79d533a 100755
--- a/tests/docker/common.rc
+++ b/tests/docker/common.rc
@@ -21,6 +21,14 @@ else
DEF_TARGET_LIST=${DEF_TARGET_LIST:-"x86_64-softmmu,aarch64-softmmu"}
fi
+enable_rust=""
+if [ "$ENABLE_RUST" = "1" ]; then
+ enable_rust="--enable-rust"
+ if [ -n "$RUST_TARGET" ]; then
+ enable_rust="$enable_rust --rust-target-triple=$RUST_TARGET"
+ fi
+fi
+
requires_binary()
{
found=0
@@ -45,12 +53,13 @@ configure_qemu()
config_opts="--enable-werror \
${TARGET_LIST:+--target-list=${TARGET_LIST}} \
--prefix=$INSTALL_DIR \
+ $enable_rust \
$QEMU_CONFIGURE_OPTS $EXTRA_CONFIGURE_OPTS \
$@"
echo "Configure options:"
echo $config_opts
$QEMU_SRC/configure $config_opts || \
- { cat config.log && test_fail "Failed to run 'configure'"; }
+ { cat config.log >&2 ; cat meson-logs/meson-log.txt >&2 ; test_fail "Failed to run 'configure'"; }
}
build_qemu()
@@ -73,7 +82,7 @@ check_qemu()
test_fail()
{
- echo "$@"
+ echo "$@" >&2
exit 1
}
diff --git a/tests/docker/dockerfiles/alpine.docker b/tests/docker/dockerfiles/alpine.docker
index bf3bd5a..52adf9c 100644
--- a/tests/docker/dockerfiles/alpine.docker
+++ b/tests/docker/dockerfiles/alpine.docker
@@ -78,7 +78,7 @@ RUN apk update && \
nmap-ncat \
numactl-dev \
openssh-client \
- pcre-dev \
+ pcre2-dev \
pipewire-dev \
pixman-dev \
pkgconf \
@@ -131,8 +131,12 @@ ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
ENV NINJA "/usr/bin/ninja"
ENV PYTHON "/usr/bin/python3"
+# https://gitlab.alpinelinux.org/alpine/aports/-/issues/17463
+RUN apk add clang19-libclang
# As a final step configure the user (if env is defined)
ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/centos9.docker b/tests/docker/dockerfiles/centos9.docker
index a942835..0674d77 100644
--- a/tests/docker/dockerfiles/centos9.docker
+++ b/tests/docker/dockerfiles/centos9.docker
@@ -25,6 +25,7 @@ RUN dnf distro-sync -y && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -104,6 +105,7 @@ RUN dnf distro-sync -y && \
python3-tomli \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -140,3 +142,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-all-test-cross.docker b/tests/docker/dockerfiles/debian-all-test-cross.docker
index 8ab244e..420a4e3 100644
--- a/tests/docker/dockerfiles/debian-all-test-cross.docker
+++ b/tests/docker/dockerfiles/debian-all-test-cross.docker
@@ -15,7 +15,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y eatmydata && \
eatmydata apt-get dist-upgrade -y && \
- apt build-dep -yy qemu
+ apt build-dep -yy --arch-only qemu
# Add extra build tools and as many cross compilers as we can for testing
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
@@ -23,7 +23,9 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
bison \
ccache \
clang \
+ dpkg-dev \
flex \
+ gcc \
git \
libclang-rt-dev \
ninja-build \
@@ -33,16 +35,11 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
python3-venv \
python3-wheel
-RUN DEBIAN_FRONTEND=noninteractive eatmydata \
- apt install -y --no-install-recommends \
- gcc-aarch64-linux-gnu \
+# All the generally available compilers
+ENV AVAILABLE_COMPILERS gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
gcc-arm-linux-gnueabihf \
libc6-dev-armhf-cross \
- gcc-hppa-linux-gnu \
- libc6-dev-hppa-cross \
- gcc-m68k-linux-gnu \
- libc6-dev-m68k-cross \
gcc-mips-linux-gnu \
libc6-dev-mips-cross \
gcc-mips64-linux-gnuabi64 \
@@ -51,18 +48,23 @@ RUN DEBIAN_FRONTEND=noninteractive eatmydata \
libc6-dev-mips64el-cross \
gcc-mipsel-linux-gnu \
libc6-dev-mipsel-cross \
- gcc-powerpc-linux-gnu \
- libc6-dev-powerpc-cross \
- gcc-powerpc64-linux-gnu \
- libc6-dev-ppc64-cross \
gcc-powerpc64le-linux-gnu \
libc6-dev-ppc64el-cross \
gcc-riscv64-linux-gnu \
libc6-dev-riscv64-cross \
gcc-s390x-linux-gnu \
- libc6-dev-s390x-cross \
- gcc-sparc64-linux-gnu \
- libc6-dev-sparc64-cross && \
+ libc6-dev-s390x-cross
+
+RUN if dpkg-architecture -e amd64; then \
+ export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-hppa-linux-gnu libc6-dev-hppa-cross"; \
+ export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-m68k-linux-gnu libc6-dev-m68k-cross"; \
+ export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc-linux-gnu libc6-dev-powerpc-cross"; \
+ export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-powerpc64-linux-gnu libc6-dev-ppc64-cross"; \
+ export AVAILABLE_COMPILERS="${AVAILABLE_COMPILERS} gcc-sparc64-linux-gnu libc6-dev-sparc64-cross"; \
+ fi && \
+ DEBIAN_FRONTEND=noninteractive eatmydata \
+ apt install -y --no-install-recommends \
+ ${AVAILABLE_COMPILERS} && \
dpkg-query --showformat '${Package}_${Version}_${Architecture}\n' --show > /packages.txt
diff --git a/tests/docker/dockerfiles/debian-amd64-cross.docker b/tests/docker/dockerfiles/debian-amd64-cross.docker
index 081f3e0..7f46744 100644
--- a/tests/docker/dockerfiles/debian-amd64-cross.docker
+++ b/tests/docker/dockerfiles/debian-amd64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch x86_64 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch x86_64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-x86-64-linux-gnu \
libaio-dev:amd64 \
- libasan6:amd64 \
+ libasan8:amd64 \
libasound2-dev:amd64 \
libattr1-dev:amd64 \
libbpf-dev:amd64 \
@@ -137,6 +142,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:amd64 \
libspice-server-dev:amd64 \
libssh-dev:amd64 \
+ libstd-rust-dev:amd64 \
libsystemd-dev:amd64 \
libtasn1-6-dev:amd64 \
libubsan1:amd64 \
@@ -182,3 +188,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-arm64-cross.docker b/tests/docker/dockerfiles/debian-arm64-cross.docker
index 91c555a..c7cd54e 100644
--- a/tests/docker/dockerfiles/debian-arm64-cross.docker
+++ b/tests/docker/dockerfiles/debian-arm64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch aarch64 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch aarch64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-aarch64-linux-gnu \
libaio-dev:arm64 \
- libasan6:arm64 \
+ libasan8:arm64 \
libasound2-dev:arm64 \
libattr1-dev:arm64 \
libbpf-dev:arm64 \
@@ -136,6 +141,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:arm64 \
libspice-server-dev:arm64 \
libssh-dev:arm64 \
+ libstd-rust-dev:arm64 \
libsystemd-dev:arm64 \
libtasn1-6-dev:arm64 \
libubsan1:arm64 \
@@ -181,3 +187,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-armhf-cross.docker b/tests/docker/dockerfiles/debian-armhf-cross.docker
index f0e2efc..627d41c 100644
--- a/tests/docker/dockerfiles/debian-armhf-cross.docker
+++ b/tests/docker/dockerfiles/debian-armhf-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch armv7l debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch armv7l debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-arm-linux-gnueabihf \
libaio-dev:armhf \
- libasan6:armhf \
+ libasan8:armhf \
libasound2-dev:armhf \
libattr1-dev:armhf \
libbpf-dev:armhf \
@@ -103,7 +108,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libgbm-dev:armhf \
libgcrypt20-dev:armhf \
libglib2.0-dev:armhf \
- libglusterfs-dev:armhf \
libgnutls28-dev:armhf \
libgtk-3-dev:armhf \
libgtk-vnc-2.0-dev:armhf \
@@ -123,7 +127,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libpixman-1-dev:armhf \
libpng-dev:armhf \
libpulse-dev:armhf \
- librbd-dev:armhf \
librdmacm-dev:armhf \
libsasl2-dev:armhf \
libsdl2-dev:armhf \
@@ -136,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:armhf \
libspice-server-dev:armhf \
libssh-dev:armhf \
+ libstd-rust-dev:armhf \
libsystemd-dev:armhf \
libtasn1-6-dev:armhf \
libubsan1:armhf \
@@ -147,7 +151,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libvirglrenderer-dev:armhf \
libvte-2.91-dev:armhf \
libxdp-dev:armhf \
- libxen-dev:armhf \
libzstd-dev:armhf \
nettle-dev:armhf \
systemtap-sdt-dev:armhf \
@@ -181,3 +184,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-i686-cross.docker b/tests/docker/dockerfiles/debian-i686-cross.docker
index 025beb1..2998764 100644
--- a/tests/docker/dockerfiles/debian-i686-cross.docker
+++ b/tests/docker/dockerfiles/debian-i686-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch i686 debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch i686 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-i686-linux-gnu \
libaio-dev:i386 \
- libasan6:i386 \
+ libasan8:i386 \
libasound2-dev:i386 \
libattr1-dev:i386 \
libbpf-dev:i386 \
@@ -103,7 +108,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libgbm-dev:i386 \
libgcrypt20-dev:i386 \
libglib2.0-dev:i386 \
- libglusterfs-dev:i386 \
libgnutls28-dev:i386 \
libgtk-3-dev:i386 \
libgtk-vnc-2.0-dev:i386 \
@@ -123,7 +127,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libpixman-1-dev:i386 \
libpng-dev:i386 \
libpulse-dev:i386 \
- librbd-dev:i386 \
librdmacm-dev:i386 \
libsasl2-dev:i386 \
libsdl2-dev:i386 \
@@ -136,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:i386 \
libspice-server-dev:i386 \
libssh-dev:i386 \
+ libstd-rust-dev:i386 \
libsystemd-dev:i386 \
libtasn1-6-dev:i386 \
libubsan1:i386 \
@@ -174,9 +178,11 @@ ENV ABI "i686-linux-gnu"
ENV MESON_OPTS "--cross-file=i686-linux-gnu"
ENV RUST_TARGET "i686-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=i686-linux-gnu-
-ENV DEF_TARGET_LIST x86_64-softmmu,x86_64-linux-user,i386-softmmu,i386-linux-user
+ENV DEF_TARGET_LIST i386-softmmu,i386-linux-user
# As a final step configure the user (if env is defined)
ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-mips64el-cross.docker b/tests/docker/dockerfiles/debian-mips64el-cross.docker
index 4a941dd..6e88777 100644
--- a/tests/docker/dockerfiles/debian-mips64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-mips64el-cross.docker
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,9 +45,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-web \
@@ -67,6 +69,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -135,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:mips64el \
libspice-server-dev:mips64el \
libssh-dev:mips64el \
+ libstd-rust-dev:mips64el \
libsystemd-dev:mips64el \
libtasn1-6-dev:mips64el \
libudev-dev:mips64el \
@@ -178,3 +183,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-mipsel-cross.docker b/tests/docker/dockerfiles/debian-mipsel-cross.docker
index 4d3e5d7..5f4e3fa 100644
--- a/tests/docker/dockerfiles/debian-mipsel-cross.docker
+++ b/tests/docker/dockerfiles/debian-mipsel-cross.docker
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,9 +45,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-web \
@@ -67,6 +69,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -135,6 +139,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:mipsel \
libspice-server-dev:mipsel \
libssh-dev:mipsel \
+ libstd-rust-dev:mipsel \
libsystemd-dev:mipsel \
libtasn1-6-dev:mipsel \
libudev-dev:mipsel \
@@ -178,3 +183,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-ppc64el-cross.docker b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
index 22b4457..dfa6906 100644
--- a/tests/docker/dockerfiles/debian-ppc64el-cross.docker
+++ b/tests/docker/dockerfiles/debian-ppc64el-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch ppc64le debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch ppc64le debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-powerpc64le-linux-gnu \
libaio-dev:ppc64el \
- libasan6:ppc64el \
+ libasan8:ppc64el \
libasound2-dev:ppc64el \
libattr1-dev:ppc64el \
libbpf-dev:ppc64el \
@@ -136,6 +141,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev:ppc64el \
libspice-server-dev:ppc64el \
libssh-dev:ppc64el \
+ libstd-rust-dev:ppc64el \
libsystemd-dev:ppc64el \
libtasn1-6-dev:ppc64el \
libubsan1:ppc64el \
@@ -180,3 +186,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-riscv64-cross.docker b/tests/docker/dockerfiles/debian-riscv64-cross.docker
index b0386cd..09b2953 100644
--- a/tests/docker/dockerfiles/debian-riscv64-cross.docker
+++ b/tests/docker/dockerfiles/debian-riscv64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch riscv64 debian-13 qemu-minimal
+# $ lcitool dockerfile --layers all --cross-arch riscv64 debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:trixie-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -13,29 +13,65 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
bash \
bc \
+ bindgen \
bison \
+ bsdextrautils \
+ bzip2 \
ca-certificates \
ccache \
+ dbus \
+ debianutils \
+ diffutils \
+ exuberant-ctags \
findutils \
flex \
gcc \
+ gcovr \
+ gettext \
git \
+ hostname \
+ libclang-rt-dev \
libglib2.0-dev \
+ llvm \
locales \
make \
- meson \
+ mtools \
+ ncat \
ninja-build \
+ openssh-client \
pkgconf \
python3 \
+ python3-numpy \
+ python3-opencv \
+ python3-pillow \
+ python3-pip \
+ python3-setuptools \
+ python3-sphinx \
+ python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
+ python3-yaml \
+ rpm2cpio \
+ rustc \
sed \
- tar && \
+ socat \
+ sparse \
+ swtpm \
+ tar \
+ tesseract-ocr \
+ tesseract-ocr-eng \
+ vulkan-tools \
+ xorriso \
+ zstd && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
sed -Ei 's,^# (en_US\.UTF-8 .*)$,\1,' /etc/locale.gen && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -52,11 +88,78 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y dpkg-dev && \
eatmydata apt-get install --no-install-recommends -y \
gcc-riscv64-linux-gnu \
+ libaio-dev:riscv64 \
+ libasan8:riscv64 \
+ libasound2-dev:riscv64 \
+ libattr1-dev:riscv64 \
+ libbpf-dev:riscv64 \
+ libbrlapi-dev:riscv64 \
+ libbz2-dev:riscv64 \
libc6-dev:riscv64 \
+ libcacard-dev:riscv64 \
+ libcap-ng-dev:riscv64 \
+ libcapstone-dev:riscv64 \
+ libcbor-dev:riscv64 \
+ libcmocka-dev:riscv64 \
+ libcurl4-gnutls-dev:riscv64 \
+ libdaxctl-dev:riscv64 \
+ libdrm-dev:riscv64 \
+ libepoxy-dev:riscv64 \
libfdt-dev:riscv64 \
libffi-dev:riscv64 \
+ libfuse3-dev:riscv64 \
+ libgbm-dev:riscv64 \
+ libgcrypt20-dev:riscv64 \
libglib2.0-dev:riscv64 \
- libpixman-1-dev:riscv64 && \
+ libglusterfs-dev:riscv64 \
+ libgnutls28-dev:riscv64 \
+ libgtk-3-dev:riscv64 \
+ libgtk-vnc-2.0-dev:riscv64 \
+ libibverbs-dev:riscv64 \
+ libiscsi-dev:riscv64 \
+ libjemalloc-dev:riscv64 \
+ libjpeg62-turbo-dev:riscv64 \
+ libjson-c-dev:riscv64 \
+ liblttng-ust-dev:riscv64 \
+ liblzo2-dev:riscv64 \
+ libncursesw5-dev:riscv64 \
+ libnfs-dev:riscv64 \
+ libnuma-dev:riscv64 \
+ libpam0g-dev:riscv64 \
+ libpcre2-dev:riscv64 \
+ libpipewire-0.3-dev:riscv64 \
+ libpixman-1-dev:riscv64 \
+ libpng-dev:riscv64 \
+ libpulse-dev:riscv64 \
+ librbd-dev:riscv64 \
+ librdmacm-dev:riscv64 \
+ libsasl2-dev:riscv64 \
+ libsdl2-dev:riscv64 \
+ libsdl2-image-dev:riscv64 \
+ libseccomp-dev:riscv64 \
+ libselinux1-dev:riscv64 \
+ libslirp-dev:riscv64 \
+ libsnappy-dev:riscv64 \
+ libsndio-dev:riscv64 \
+ libspice-protocol-dev:riscv64 \
+ libspice-server-dev:riscv64 \
+ libssh-dev:riscv64 \
+ libstd-rust-dev:riscv64 \
+ libsystemd-dev:riscv64 \
+ libtasn1-6-dev:riscv64 \
+ libubsan1:riscv64 \
+ libudev-dev:riscv64 \
+ liburing-dev:riscv64 \
+ libusb-1.0-0-dev:riscv64 \
+ libusbredirhost-dev:riscv64 \
+ libvdeplug-dev:riscv64 \
+ libvirglrenderer-dev:riscv64 \
+ libvte-2.91-dev:riscv64 \
+ libxdp-dev:riscv64 \
+ libzstd-dev:riscv64 \
+ nettle-dev:riscv64 \
+ systemtap-sdt-dev:riscv64 \
+ zlib1g-dev:riscv64 && \
eatmydata apt-get autoremove -y && \
eatmydata apt-get autoclean -y && \
mkdir -p /usr/local/share/meson/cross && \
@@ -78,6 +181,7 @@ endian = 'little'\n" > /usr/local/share/meson/cross/riscv64-linux-gnu && \
ENV ABI "riscv64-linux-gnu"
ENV MESON_OPTS "--cross-file=riscv64-linux-gnu"
+ENV RUST_TARGET "riscv64gc-unknown-linux-gnu"
ENV QEMU_CONFIGURE_OPTS --cross-prefix=riscv64-linux-gnu-
ENV DEF_TARGET_LIST riscv64-softmmu,riscv64-linux-user
# As a final step configure the user (if env is defined)
@@ -85,3 +189,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian-s390x-cross.docker b/tests/docker/dockerfiles/debian-s390x-cross.docker
index 13ec52c..09a78c1 100644
--- a/tests/docker/dockerfiles/debian-s390x-cross.docker
+++ b/tests/docker/dockerfiles/debian-s390x-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch s390x debian-12 qemu
+# $ lcitool dockerfile --layers all --cross-arch s390x debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -30,11 +30,11 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
gettext \
git \
hostname \
+ libclang-rt-dev \
libglib2.0-dev \
llvm \
locales \
make \
- meson \
mtools \
ncat \
ninja-build \
@@ -45,12 +45,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -67,6 +70,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
dpkg-reconfigure locales && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -81,7 +86,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
eatmydata apt-get install --no-install-recommends -y \
gcc-s390x-linux-gnu \
libaio-dev:s390x \
- libasan6:s390x \
+ libasan8:s390x \
libasound2-dev:s390x \
libattr1-dev:s390x \
libbpf-dev:s390x \
@@ -135,6 +140,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libsndio-dev:s390x \
libspice-protocol-dev:s390x \
libssh-dev:s390x \
+ libstd-rust-dev:s390x \
libsystemd-dev:s390x \
libtasn1-6-dev:s390x \
libubsan1:s390x \
@@ -179,3 +185,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/debian.docker b/tests/docker/dockerfiles/debian.docker
index 0a57c1a..8dd893b 100644
--- a/tests/docker/dockerfiles/debian.docker
+++ b/tests/docker/dockerfiles/debian.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all debian-12 qemu
+# $ lcitool dockerfile --layers all debian-13 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM docker.io/library/debian:12-slim
+FROM docker.io/library/debian:13-slim
RUN export DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
@@ -32,7 +32,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
git \
hostname \
libaio-dev \
- libasan6 \
+ libasan8 \
libasound2-dev \
libattr1-dev \
libbpf-dev \
@@ -43,6 +43,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libcap-ng-dev \
libcapstone-dev \
libcbor-dev \
+ libclang-rt-dev \
libcmocka-dev \
libcurl4-gnutls-dev \
libdaxctl-dev \
@@ -88,6 +89,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev \
libspice-server-dev \
libssh-dev \
+ libstd-rust-dev \
libsystemd-dev \
libtasn1-6-dev \
libubsan1 \
@@ -104,7 +106,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
llvm \
locales \
make \
- meson \
mtools \
multipath-tools \
ncat \
@@ -117,12 +118,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
+ python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
- rustc-web \
+ rustc \
sed \
socat \
sparse \
@@ -146,6 +150,8 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -169,3 +175,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/emsdk-wasm32-cross.docker b/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
index 60a7d02..6b1642a 100644
--- a/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
+++ b/tests/docker/dockerfiles/emsdk-wasm32-cross.docker
@@ -8,7 +8,7 @@ ARG PIXMAN_VERSION=0.44.2
ARG FFI_VERSION=v3.4.7
ARG MESON_VERSION=1.5.0
-FROM emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base
+FROM docker.io/emscripten/emsdk:$EMSDK_VERSION_QEMU AS build-base
ARG MESON_VERSION
ENV TARGET=/builddeps/target
ENV CPATH="$TARGET/include"
diff --git a/tests/docker/dockerfiles/fedora-rust-nightly.docker b/tests/docker/dockerfiles/fedora-rust-nightly.docker
index fe4a6ed..7d31c9f 100644
--- a/tests/docker/dockerfiles/fedora-rust-nightly.docker
+++ b/tests/docker/dockerfiles/fedora-rust-nightly.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all fedora-40 qemu
+# $ lcitool dockerfile --layers all fedora-41 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -32,6 +32,7 @@ exec "$@"\n' > /usr/bin/nosync && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -91,7 +92,6 @@ exec "$@"\n' > /usr/bin/nosync && \
lzo-devel \
make \
mesa-libgbm-devel \
- meson \
mtools \
ncurses-devel \
nettle-devel \
@@ -100,7 +100,7 @@ exec "$@"\n' > /usr/bin/nosync && \
numactl-devel \
openssh-clients \
pam-devel \
- pcre-static \
+ pcre2-static \
pipewire-devel \
pixman-devel \
pkgconfig \
@@ -111,11 +111,13 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -124,7 +126,7 @@ exec "$@"\n' > /usr/bin/nosync && \
spice-server-devel \
swtpm \
systemd-devel \
- systemtap-sdt-devel \
+ systemtap-sdt-dtrace \
tar \
tesseract \
tesseract-langpack-eng \
@@ -148,6 +150,8 @@ exec "$@"\n' > /usr/bin/nosync && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -156,6 +160,7 @@ ENV PYTHON "/usr/bin/python3"
RUN dnf install -y wget
ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo
ENV RUSTC=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustc
+ENV RUSTDOC=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustdoc
ENV CARGO=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo
RUN set -eux && \
rustArch='x86_64-unknown-linux-gnu' && \
@@ -170,6 +175,7 @@ RUN set -eux && \
/usr/local/cargo/bin/rustup run nightly cargo --version && \
/usr/local/cargo/bin/rustup run nightly rustc --version && \
test "$CARGO" = "$(/usr/local/cargo/bin/rustup +nightly which cargo)" && \
+ test "$RUSTDOC" = "$(/usr/local/cargo/bin/rustup +nightly which rustdoc)" && \
test "$RUSTC" = "$(/usr/local/cargo/bin/rustup +nightly which rustc)"
ENV PATH=$CARGO_HOME/bin:$PATH
RUN /usr/local/cargo/bin/rustup run nightly cargo install bindgen-cli
@@ -179,3 +185,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/fedora-win64-cross.docker b/tests/docker/dockerfiles/fedora-win64-cross.docker
index a950344..c76a70c 100644
--- a/tests/docker/dockerfiles/fedora-win64-cross.docker
+++ b/tests/docker/dockerfiles/fedora-win64-cross.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all --cross-arch mingw64 fedora-40 qemu,qemu-win-installer
+# $ lcitool dockerfile --layers all --cross-arch mingw64 fedora-41 qemu,qemu-win-installer
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -25,6 +25,7 @@ exec "$@"\n' > /usr/bin/nosync && \
bzip2 \
ca-certificates \
ccache \
+ compiler-rt \
ctags \
dbus-daemon \
diffutils \
@@ -38,7 +39,6 @@ exec "$@"\n' > /usr/bin/nosync && \
hostname \
llvm \
make \
- meson \
mtools \
ninja-build \
nmap-ncat \
@@ -49,9 +49,10 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rust \
sed \
socat \
@@ -69,6 +70,8 @@ exec "$@"\n' > /usr/bin/nosync && \
nosync dnf clean all -y && \
rm -f /usr/lib*/python3*/EXTERNALLY-MANAGED
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -90,13 +93,15 @@ RUN nosync dnf install -y \
mingw64-gtk-vnc2 \
mingw64-gtk3 \
mingw64-libepoxy \
+ mingw64-libfdt \
mingw64-libgcrypt \
mingw64-libjpeg-turbo \
mingw64-libpng \
mingw64-libtasn1 \
mingw64-nettle \
mingw64-pixman \
- mingw64-pkg-config && \
+ mingw64-pkg-config \
+ rust-std-static-x86_64-pc-windows-gnu && \
nosync dnf clean all -y && \
rpm -qa | sort > /packages.txt && \
mkdir -p /usr/libexec/ccache-wrappers && \
diff --git a/tests/docker/dockerfiles/fedora.docker b/tests/docker/dockerfiles/fedora.docker
index 014e3cc..891a740 100644
--- a/tests/docker/dockerfiles/fedora.docker
+++ b/tests/docker/dockerfiles/fedora.docker
@@ -1,10 +1,10 @@
# THIS FILE WAS AUTO-GENERATED
#
-# $ lcitool dockerfile --layers all fedora-40 qemu
+# $ lcitool dockerfile --layers all fedora-41 qemu
#
# https://gitlab.com/libvirt/libvirt-ci
-FROM registry.fedoraproject.org/fedora:40
+FROM registry.fedoraproject.org/fedora:41
RUN dnf install -y nosync && \
printf '#!/bin/sh\n\
@@ -32,6 +32,7 @@ exec "$@"\n' > /usr/bin/nosync && \
capstone-devel \
ccache \
clang \
+ compiler-rt \
ctags \
cyrus-sasl-devel \
daxctl-devel \
@@ -91,7 +92,6 @@ exec "$@"\n' > /usr/bin/nosync && \
lzo-devel \
make \
mesa-libgbm-devel \
- meson \
mtools \
ncurses-devel \
nettle-devel \
@@ -100,7 +100,7 @@ exec "$@"\n' > /usr/bin/nosync && \
numactl-devel \
openssh-clients \
pam-devel \
- pcre-static \
+ pcre2-static \
pipewire-devel \
pixman-devel \
pkgconfig \
@@ -111,11 +111,13 @@ exec "$@"\n' > /usr/bin/nosync && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx_rtd_theme \
- python3-zombie-imp \
+ python3-wheel \
rdma-core-devel \
rust \
+ rust-std-static \
sed \
snappy-devel \
socat \
@@ -124,7 +126,7 @@ exec "$@"\n' > /usr/bin/nosync && \
spice-server-devel \
swtpm \
systemd-devel \
- systemtap-sdt-devel \
+ systemtap-sdt-dtrace \
tar \
tesseract \
tesseract-langpack-eng \
@@ -148,6 +150,8 @@ exec "$@"\n' > /usr/bin/nosync && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
@@ -158,3 +162,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/opensuse-leap.docker b/tests/docker/dockerfiles/opensuse-leap.docker
index e90225d..75e1747 100644
--- a/tests/docker/dockerfiles/opensuse-leap.docker
+++ b/tests/docker/dockerfiles/opensuse-leap.docker
@@ -19,6 +19,7 @@ RUN zypper update -y && \
ca-certificates \
ccache \
clang \
+ clang-devel \
ctags \
cyrus-sasl-devel \
dbus-1 \
@@ -89,7 +90,7 @@ RUN zypper update -y && \
ninja \
openssh \
pam-devel \
- pcre-devel-static \
+ pcre2-devel-static \
pipewire-devel \
pkgconfig \
python311 \
@@ -132,7 +133,7 @@ RUN zypper update -y && \
RUN /usr/bin/pip3.11 install \
PyYAML \
- meson==1.5.0 \
+ meson==1.8.1 \
pillow \
sphinx \
sphinx-rtd-theme
@@ -147,3 +148,5 @@ ARG USER
ARG UID
RUN if [ "${USER}" ]; then \
id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi
+
+ENV ENABLE_RUST 1
diff --git a/tests/docker/dockerfiles/ubuntu2204.docker b/tests/docker/dockerfiles/ubuntu2204.docker
index 4a1cf2b..b393db5 100644
--- a/tests/docker/dockerfiles/ubuntu2204.docker
+++ b/tests/docker/dockerfiles/ubuntu2204.docker
@@ -42,6 +42,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libcap-ng-dev \
libcapstone-dev \
libcbor-dev \
+ libclang-dev \
libcmocka-dev \
libcurl4-gnutls-dev \
libdaxctl-dev \
@@ -87,6 +88,7 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
libspice-protocol-dev \
libspice-server-dev \
libssh-dev \
+ libstd-rust-dev \
libsystemd-dev \
libtasn1-6-dev \
libubsan1 \
@@ -102,7 +104,6 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
llvm \
locales \
make \
- meson \
mtools \
multipath-tools \
ncat \
@@ -115,10 +116,12 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
python3-opencv \
python3-pillow \
python3-pip \
+ python3-setuptools \
python3-sphinx \
python3-sphinx-rtd-theme \
python3-tomli \
python3-venv \
+ python3-wheel \
python3-yaml \
rpm2cpio \
rustc-1.77 \
@@ -145,12 +148,15 @@ RUN export DEBIAN_FRONTEND=noninteractive && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/clang && \
ln -s /usr/bin/ccache /usr/libexec/ccache-wrappers/gcc
+RUN /usr/bin/pip3 install meson==1.8.1
+
ENV CCACHE_WRAPPERSDIR "/usr/libexec/ccache-wrappers"
ENV LANG "en_US.UTF-8"
ENV MAKE "/usr/bin/make"
ENV NINJA "/usr/bin/ninja"
ENV PYTHON "/usr/bin/python3"
ENV RUSTC=/usr/bin/rustc-1.77
+ENV RUSTDOC=/usr/bin/rustdoc-1.77
ENV CARGO_HOME=/usr/local/cargo
ENV PATH=$CARGO_HOME/bin:$PATH
RUN DEBIAN_FRONTEND=noninteractive eatmydata \
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
new file mode 100644
index 0000000..5ad52f9
--- /dev/null
+++ b/tests/functional/aarch64/meson.build
@@ -0,0 +1,49 @@
+# 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',
+ 'vmstate',
+]
+
+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 d02dc79..a3db267 100755
--- a/tests/functional/test_aarch64_aspeed_ast2700.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700.py
@@ -54,6 +54,10 @@ class AST2x00MachineSDK(QemuSystemTest):
'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+ ASSET_SDK_V907_AST2700A1_VBOOROM = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2700-default-obmc.tar.gz',
+ '6e9e0c4b13e0f26040eca3f4a7f17cf09fc0f5c37c820500ff79370cc3c44add')
+
def do_ast2700_i2c_test(self):
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
@@ -111,8 +115,8 @@ class AST2x00MachineSDK(QemuSystemTest):
self.do_test_aarch64_aspeed_sdk_start(
self.scratch_file(name, 'image-bmc'))
- def test_aarch64_ast2700_evb_sdk_v09_06(self):
- self.set_machine('ast2700-evb')
+ def test_aarch64_ast2700a0_evb_sdk_v09_06(self):
+ self.set_machine('ast2700a0-evb')
self.archive_extract(self.ASSET_SDK_V906_AST2700)
self.start_ast2700_test('ast2700-a0-default')
@@ -127,10 +131,10 @@ class AST2x00MachineSDK(QemuSystemTest):
self.verify_openbmc_boot_and_login('ast2700-default')
self.do_ast2700_i2c_test()
- def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_06(self):
+ def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_07(self):
self.set_machine('ast2700a1-evb')
- self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
+ self.archive_extract(self.ASSET_SDK_V907_AST2700A1_VBOOROM)
self.start_ast2700_test_vbootrom('ast2700-default')
self.verify_vbootrom_firmware_flow()
self.verify_openbmc_boot_and_login('ast2700-default')
diff --git a/tests/functional/test_aarch64_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py
index b85370e..b85370e 100755
--- a/tests/functional/test_aarch64_aspeed_ast2700fc.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py
diff --git a/tests/functional/aarch64/test_device_passthrough.py b/tests/functional/aarch64/test_device_passthrough.py
new file mode 100755
index 0000000..05a3f52
--- /dev/null
+++ b/tests/functional/aarch64/test_device_passthrough.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+#
+# Boots a nested guest and compare content of a device (passthrough) to a
+# reference image. Both vfio group and iommufd passthrough methods are tested.
+#
+# Copyright (c) 2025 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from os.path import join
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import exec_command, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+from random import randbytes
+
+guest_script = '''
+#!/usr/bin/env bash
+
+set -euo pipefail
+set -x
+
+# find disks from nvme serial
+dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
+dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
+pci_vfio=$(basename $(readlink -f /sys/block/$dev_vfio/../../../))
+pci_iommufd=$(basename $(readlink -f /sys/block/$dev_iommufd/../../../))
+
+# bind disks to vfio
+for p in "$pci_vfio" "$pci_iommufd"; do
+ if [ "$(cat /sys/bus/pci/devices/$p/driver_override)" == vfio-pci ]; then
+ continue
+ fi
+ echo $p > /sys/bus/pci/drivers/nvme/unbind
+ echo vfio-pci > /sys/bus/pci/devices/$p/driver_override
+ echo $p > /sys/bus/pci/drivers/vfio-pci/bind
+done
+
+# boot nested guest and execute /host/nested_guest.sh
+# one disk is passed through vfio group, the other, through iommufd
+qemu-system-aarch64 \
+-M virt \
+-display none \
+-serial stdio \
+-cpu host \
+-enable-kvm \
+-m 1G \
+-kernel /host/Image.gz \
+-drive format=raw,file=/host/guest.ext4,if=virtio \
+-append "root=/dev/vda init=/init -- bash /host/nested_guest.sh" \
+-virtfs local,path=/host,mount_tag=host,security_model=mapped,readonly=off \
+-device vfio-pci,host=$pci_vfio \
+-object iommufd,id=iommufd0 \
+-device vfio-pci,host=$pci_iommufd,iommufd=iommufd0
+'''
+
+nested_guest_script = '''
+#!/usr/bin/env bash
+
+set -euo pipefail
+set -x
+
+image_vfio=/host/disk_vfio
+image_iommufd=/host/disk_iommufd
+
+dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
+dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
+
+# compare if devices are identical to original images
+diff $image_vfio /dev/$dev_vfio
+diff $image_iommufd /dev/$dev_iommufd
+
+echo device_passthrough_test_ok
+'''
+
+class Aarch64DevicePassthrough(QemuSystemTest):
+
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/device_passthrough
+ # $ ./build.sh && ./archive_artifacts.sh out.tar.xz
+ #
+ # Linux kernel is compiled with defconfig +
+ # IOMMUFD + VFIO_DEVICE_CDEV + ARM_SMMU_V3_IOMMUFD
+ # https://docs.kernel.org/driver-api/vfio.html#vfio-device-cde
+ ASSET_DEVICE_PASSTHROUGH_STACK = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/device_passthrough-a9612a2.tar.xz'),
+ 'f7d2f70912e7231986e6e293e1a2c4786dd02bec113a7acb6bfc619e96155455')
+
+ # This tests the device passthrough implementation, by booting a VM
+ # supporting it with two nvme disks attached, and launching a nested VM
+ # reading their content.
+ def test_aarch64_device_passthrough(self):
+ self.set_machine('virt')
+ self.require_accelerator('tcg')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_DEVICE_PASSTHROUGH_STACK.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ stack = self.scratch_file('out')
+ kernel = join(stack, 'Image.gz')
+ rootfs_host = join(stack, 'host.ext4')
+ disk_vfio = join(stack, 'disk_vfio')
+ disk_iommufd = join(stack, 'disk_iommufd')
+ guest_cmd = join(stack, 'guest.sh')
+ nested_guest_cmd = join(stack, 'nested_guest.sh')
+ # we generate two random disks
+ with open(disk_vfio, "wb") as d: d.write(randbytes(512))
+ with open(disk_iommufd, "wb") as d: d.write(randbytes(1024))
+ with open(guest_cmd, 'w') as s: s.write(guest_script)
+ with open(nested_guest_cmd, 'w') as s: s.write(nested_guest_script)
+
+ self.vm.add_args('-cpu', 'max')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'virt,'
+ 'virtualization=on,'
+ 'gic-version=max,'
+ 'iommu=smmuv3')
+ self.vm.add_args('-kernel', kernel)
+ self.vm.add_args('-drive', f'format=raw,file={rootfs_host}')
+ self.vm.add_args('-drive',
+ f'file={disk_vfio},if=none,id=vfio,format=raw')
+ self.vm.add_args('-device', 'nvme,serial=vfio,drive=vfio')
+ self.vm.add_args('-drive',
+ f'file={disk_iommufd},if=none,id=iommufd,format=raw')
+ self.vm.add_args('-device', 'nvme,serial=iommufd,drive=iommufd')
+ self.vm.add_args('-virtfs',
+ f'local,path={stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ # boot and execute guest script
+ # init will trigger a kernel panic if script fails
+ self.vm.add_args('-append',
+ 'root=/dev/vda init=/init -- bash /host/guest.sh')
+
+ self.vm.launch()
+ wait_for_console_pattern(self, 'device_passthrough_test_ok',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_hotplug_pci.py b/tests/functional/aarch64/test_hotplug_pci.py
new file mode 100755
index 0000000..bf67720
--- /dev/null
+++ b/tests/functional/aarch64/test_hotplug_pci.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+#
+# The test hotplugs a PCI device and checks it on a Linux guest.
+#
+# Copyright (c) 2025 Linaro Ltd.
+#
+# Author:
+# Gustavo Romero <gustavo.romero@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import BUILD_DIR
+
+class HotplugPCI(LinuxKernelTest):
+
+ ASSET_KERNEL = Asset(
+ ('https://ftp.debian.org/debian/dists/trixie/main/installer-arm64/'
+ '20250803/images/netboot/debian-installer/arm64/linux'),
+ '93a6e4f9627d759375d28f863437a86a0659e125792a435f8e526dda006b7d5e')
+
+ ASSET_INITRD = Asset(
+ ('https://ftp.debian.org/debian/dists/trixie/main/installer-arm64/'
+ '20250803/images/netboot/debian-installer/arm64/initrd.gz'),
+ 'f6c78af7078ca67638ef3a50c926cd3c1485673243f8b37952e6bd854d6ba007')
+
+ def test_hotplug_pci(self):
+
+ self.set_machine('virt')
+
+ self.vm.add_args('-m', '512M',
+ '-cpu', 'cortex-a57',
+ '-append',
+ 'console=ttyAMA0,115200 init=/bin/sh',
+ '-device',
+ 'pcie-root-port,bus=pcie.0,chassis=1,slot=1,id=pcie.1',
+ '-bios',
+ self.build_file('pc-bios', 'edk2-aarch64-code.fd'))
+
+ # BusyBox prompt
+ prompt = "~ #"
+ self.launch_kernel(self.ASSET_KERNEL.fetch(),
+ self.ASSET_INITRD.fetch(),
+ wait_for=prompt)
+
+ # Check for initial state: 2 network adapters, lo and enp0s1.
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '2')
+
+ # Hotplug one network adapter to the root port, i.e. pcie.1 bus.
+ self.vm.cmd('device_add',
+ driver='virtio-net-pci',
+ bus='pcie.1',
+ addr=0,
+ id='na')
+ # Wait for the kernel to recognize the new device.
+ self.wait_for_console_pattern('virtio-pci')
+ self.wait_for_console_pattern('virtio_net')
+
+ # Check if there is a new network adapter.
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '3')
+
+ self.vm.cmd('device_del', id='na')
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '2')
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_aarch64_imx8mp_evk.py b/tests/functional/aarch64/test_imx8mp_evk.py
index 638bf9e..99ddcde 100755
--- a/tests/functional/test_aarch64_imx8mp_evk.py
+++ b/tests/functional/aarch64/test_imx8mp_evk.py
@@ -49,6 +49,7 @@ class Imx8mpEvkMachine(LinuxKernelTest):
self.DTB_OFFSET, self.DTB_SIZE)
def test_aarch64_imx8mp_evk_usdhc(self):
+ self.require_accelerator("tcg")
self.set_machine('imx8mp-evk')
self.vm.set_console(console_index=1)
self.vm.add_args('-m', '2G',
diff --git a/tests/functional/aarch64/test_kvm.py b/tests/functional/aarch64/test_kvm.py
new file mode 100755
index 0000000..9fb9286
--- /dev/null
+++ b/tests/functional/aarch64/test_kvm.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+#
+# Functional test that runs subsets of kvm-unit-tests on Aarch64.
+# These can run on TCG and any accelerator supporting nested
+# virtualisation.
+#
+# Copyright (c) 2025 Linaro
+#
+# Author:
+# Alex Bennée <alex.bennee@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait
+from qemu_test.linuxkernel import LinuxKernelTest
+
+
+class Aarch64VirtKVMTests(LinuxKernelTest):
+
+ ASSET_KVM_TEST_KERNEL = Asset(
+ 'https://fileserver.linaro.org/s/HmjaxXXYHYSqbes/'
+ 'download?path=%2F&files='
+ 'image-with-kvm-tool-and-unit-tests.gz',
+ '34de4aaea90db5da42729e7d28b77f392c37a2f4da859f889a5234aaf0970696')
+
+ # make it easier to detect successful return to shell
+ PS1 = 'RES=[$?] # '
+ OK_CMD = 'RES=[0] # '
+
+ # base of tests
+ KUT_BASE = "/usr/share/kvm-unit-tests/"
+
+ def _launch_guest(self, kvm_mode="nvhe"):
+
+ self.set_machine('virt')
+ kernel_path = self.ASSET_KVM_TEST_KERNEL.fetch()
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ f"console=ttyAMA0 kvm-arm.mode={kvm_mode}")
+
+ self.vm.add_args("-cpu", "cortex-a72")
+ self.vm.add_args("-machine", "virt,gic-version=3,virtualization=on",
+ '-kernel', kernel_path,
+ '-append', kernel_command_line)
+ self.vm.add_args("-smp", "2", "-m", "320")
+
+ self.vm.launch()
+
+ self.wait_for_console_pattern('buildroot login:')
+ ec_and_wait(self, 'root', '#')
+ ec_and_wait(self, f"export PS1='{self.PS1}'", self.OK_CMD)
+
+ # this is just a smoketest, we don't run all the tests in the image
+ def _smoketest_kvm(self):
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-setup", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-smp", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-kernel", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-user", self.OK_CMD)
+
+ def test_aarch64_nvhe_selftest(self):
+ self._launch_guest("nvhe")
+ self._smoketest_kvm()
+
+ def test_aarch64_vhe_selftest(self):
+ self._launch_guest("vhe")
+ self._smoketest_kvm()
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/aarch64/test_migration.py b/tests/functional/aarch64/test_migration.py
new file mode 100755
index 0000000..70267e7
--- /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 0000000..1c6e45e
--- /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 74f6630..74f6630 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 7a4302b..7a4302b 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 db12e76..db12e76 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 58d4532..ec3348c 100755
--- a/tests/functional/test_aarch64_reverse_debug.py
+++ b/tests/functional/aarch64/test_reverse_debug.py
@@ -2,36 +2,34 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
-# Reverse debugging test
+# Reverse debugging test for aarch64
#
# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
#
# Author:
# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
#
# 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 qemu_test import Asset, skipIfMissingImports, skipFlakyTest
+from qemu_test import Asset, skipFlakyTest
from reverse_debugging import ReverseDebugging
-@skipIfMissingImports('avocado.utils')
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')
- @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2921")
def test_aarch64_virt(self):
self.set_machine('virt')
self.cpu = 'cortex-a53'
- kernel_path = self.KERNEL_ASSET.fetch()
- self.reverse_debugging(args=('-kernel', kernel_path))
+ kernel_path = self.ASSET_KERNEL.fetch()
+ self.reverse_debugging(gdb_arch='aarch64', args=('-kernel', kernel_path))
if __name__ == '__main__':
diff --git a/tests/functional/aarch64/test_rme_sbsaref.py b/tests/functional/aarch64/test_rme_sbsaref.py
new file mode 100755
index 0000000..6f92858
--- /dev/null
+++ b/tests/functional/aarch64/test_rme_sbsaref.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Realms environment on sbsa-ref machine and a
+# nested guest VM using it.
+#
+# Copyright (c) 2024 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+from os.path import join
+import shutil
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class Aarch64RMESbsaRefMachine(QemuSystemTest):
+
+ # Stack is inspired from:
+ # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/rme_sbsa_release
+ # ./build.sh && ./archive_artifacts.sh out.tar.xz
+ ASSET_RME_STACK_SBSA = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/rme_sbsa_release-6a2dfc5.tar.xz'),
+ '5adba482aa069912292a8da746c6b21268224d9d81c97fe7c0bed690579ebdcb')
+
+ # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
+ # and launching a nested VM using it.
+ def test_aarch64_rme_sbsaref(self):
+ self.set_machine('sbsa-ref')
+ self.require_accelerator('tcg')
+ self.require_netdev('user')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_RME_STACK_SBSA.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ rme_stack = self.scratch_file('.')
+ pflash0 = join(rme_stack, 'out', 'SBSA_FLASH0.fd')
+ pflash1 = join(rme_stack, 'out', 'SBSA_FLASH1.fd')
+ rootfs = join(rme_stack, 'out', 'host.ext4')
+
+ efi = join(rme_stack, 'out', 'EFI')
+ os.makedirs(efi, exist_ok=True)
+ shutil.copyfile(join(rme_stack, 'out', 'Image'), join(efi, 'Image'))
+ with open(join(efi, 'startup.nsh'), 'w') as startup:
+ startup.write('fs0:Image nokaslr root=/dev/vda rw init=/init --'
+ ' /host/out/lkvm run --realm'
+ ' -m 256m'
+ ' --restricted_mem'
+ ' --kernel /host/out/Image'
+ ' --disk /host/out/guest.ext4'
+ ' --params "root=/dev/vda rw init=/init"')
+
+ self.vm.add_args('-cpu', 'max,x-rme=on')
+ self.vm.add_args('-smp', '2')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'sbsa-ref')
+ self.vm.add_args('-drive', f'file={pflash0},format=raw,if=pflash')
+ self.vm.add_args('-drive', f'file={pflash1},format=raw,if=pflash')
+ self.vm.add_args('-drive', f'file=fat:rw:{efi},format=raw')
+ self.vm.add_args('-drive', f'format=raw,file={rootfs},if=virtio')
+ self.vm.add_args('-virtfs',
+ f'local,path={rme_stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ self.vm.launch()
+ # Wait for host and guest VM boot to complete.
+ wait_for_console_pattern(self, 'root@guest',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_rme_virt.py b/tests/functional/aarch64/test_rme_virt.py
new file mode 100755
index 0000000..5e23773
--- /dev/null
+++ b/tests/functional/aarch64/test_rme_virt.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Realms environment on virt machine and a nested
+# guest VM using it.
+#
+# Copyright (c) 2024 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from os.path import join
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import exec_command, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+class Aarch64RMEVirtMachine(QemuSystemTest):
+
+ # Stack is inspired from:
+ # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/rme_release
+ # ./build.sh && ./archive_artifacts.sh out.tar.xz
+ ASSET_RME_STACK_VIRT = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/rme_release-56bc99e.tar.xz'),
+ '0e3dc6b8a4b828dbae09c951a40dcb710eded084b32432b50c69cf4173ffa4be')
+
+ # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
+ # and launching a nested VM using it.
+ def test_aarch64_rme_virt(self):
+ self.set_machine('virt')
+ self.require_accelerator('tcg')
+ self.require_netdev('user')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_RME_STACK_VIRT.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ rme_stack = self.scratch_file('.')
+ kernel = join(rme_stack, 'out', 'Image')
+ bios = join(rme_stack, 'out', 'flash.bin')
+ rootfs = join(rme_stack, 'out', 'host.ext4')
+
+ self.vm.add_args('-cpu', 'max,x-rme=on')
+ self.vm.add_args('-smp', '2')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'virt,acpi=off,'
+ 'virtualization=on,'
+ 'secure=on,'
+ 'gic-version=3')
+ self.vm.add_args('-bios', bios)
+ self.vm.add_args('-kernel', kernel)
+ self.vm.add_args('-drive', f'format=raw,file={rootfs},if=virtio')
+ self.vm.add_args('-virtfs',
+ f'local,path={rme_stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ # We need to add nokaslr to avoid triggering this sporadic bug:
+ # https://gitlab.com/qemu-project/qemu/-/issues/2823
+ self.vm.add_args('-append',
+ 'nokaslr root=/dev/vda rw init=/init --'
+ ' /host/out/lkvm run --realm'
+ ' -m 256m'
+ ' --restricted_mem'
+ ' --kernel /host/out/Image'
+ ' --disk /host/out/guest.ext4'
+ ' --params "root=/dev/vda rw init=/init"')
+
+ self.vm.launch()
+ # Wait for host and guest VM boot to complete.
+ wait_for_console_pattern(self, 'root@guest',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/aarch64/test_sbsaref.py
index e6a55ae..d3402f5 100755
--- a/tests/functional/test_aarch64_sbsaref.py
+++ b/tests/functional/aarch64/test_sbsaref.py
@@ -40,8 +40,6 @@ def fetch_firmware(test):
with open(path, "ab+") as fd:
fd.truncate(256 << 20) # Expand volumes to 256MiB
- test.set_machine('sbsa-ref')
- test.vm.set_console()
test.vm.add_args(
"-drive", f"if=pflash,file={fs0_path},format=raw",
"-drive", f"if=pflash,file={fs1_path},format=raw",
@@ -68,8 +66,11 @@ class Aarch64SbsarefMachine(QemuSystemTest):
def test_sbsaref_edk2_firmware(self):
+ self.set_machine('sbsa-ref')
+
fetch_firmware(self)
+ self.vm.set_console()
self.vm.add_args('-cpu', 'cortex-a57')
self.vm.launch()
diff --git a/tests/functional/test_aarch64_sbsaref_alpine.py b/tests/functional/aarch64/test_sbsaref_alpine.py
index 6108ec6..abb8f51 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):
@@ -26,8 +26,9 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_alpine_linux(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
+ fetch_firmware(self)
iso_path = self.ASSET_ALPINE_ISO.fetch()
self.vm.set_console()
diff --git a/tests/functional/test_aarch64_sbsaref_freebsd.py b/tests/functional/aarch64/test_sbsaref_freebsd.py
index 26dfc58..3b942f7 100755
--- a/tests/functional/test_aarch64_sbsaref_freebsd.py
+++ b/tests/functional/aarch64/test_sbsaref_freebsd.py
@@ -12,23 +12,24 @@
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):
ASSET_FREEBSD_ISO = Asset(
- ('https://download.freebsd.org/releases/arm64/aarch64/ISO-IMAGES/'
- '14.1/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso'),
- '44cdbae275ef1bb6dab1d5fbb59473d4f741e1c8ea8a80fd9e906b531d6ad461')
+ ('http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/arm64'
+ '/aarch64/ISO-IMAGES/14.1/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso.xz'),
+ '7313a4495ffd71ab77b49b1e83f571521c32756e1d75bf48bd890e0ab0f75827')
# This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_freebsd14(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
- img_path = self.ASSET_FREEBSD_ISO.fetch()
+ fetch_firmware(self)
+ img_path = self.uncompress(self.ASSET_FREEBSD_ISO)
self.vm.set_console()
self.vm.add_args(
diff --git a/tests/functional/test_aarch64_smmu.py b/tests/functional/aarch64/test_smmu.py
index c65d0f2..e0f4a92 100755
--- a/tests/functional/test_aarch64_smmu.py
+++ b/tests/functional/aarch64/test_smmu.py
@@ -17,7 +17,7 @@ import time
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import BUILD_DIR
-from qemu.utils import kvm_available
+from qemu.utils import kvm_available, hvf_available
class SMMU(LinuxKernelTest):
@@ -45,11 +45,17 @@ class SMMU(LinuxKernelTest):
self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
def common_vm_setup(self, kernel, initrd, disk):
- self.require_accelerator("kvm")
+ if hvf_available(self.qemu_bin):
+ accel = "hvf"
+ elif kvm_available(self.qemu_bin):
+ accel = "kvm"
+ else:
+ self.skipTest("Neither HVF nor KVM accelerator is available")
+ self.require_accelerator(accel)
self.require_netdev('user')
self.set_machine("virt")
self.vm.add_args('-m', '1G')
- self.vm.add_args("-accel", "kvm")
+ self.vm.add_args("-accel", accel)
self.vm.add_args("-cpu", "host")
self.vm.add_args("-machine", "iommu=smmuv3")
self.vm.add_args("-d", "guest_errors")
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/aarch64/test_tcg_plugins.py
index cb7e929..cb7e929 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 75adc8a..75adc8a 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 4d0ad90..63071f9 100755
--- a/tests/functional/test_aarch64_virt.py
+++ b/tests/functional/aarch64/test_virt.py
@@ -72,8 +72,6 @@ class Aarch64VirtMachine(QemuSystemTest):
self.set_machine('virt')
self.require_accelerator("tcg")
- logger = logging.getLogger('aarch64_virt')
-
kernel_path = self.ASSET_KERNEL.fetch()
self.vm.set_console()
@@ -91,7 +89,7 @@ class Aarch64VirtMachine(QemuSystemTest):
'rng-random,id=rng0,filename=/dev/urandom')
# Also add a scratch block device
- logger.info('creating scratch qcow2 image')
+ self.log.info('creating scratch qcow2 image')
image_path = self.scratch_file('scratch.qcow2')
qemu_img = get_qemu_img(self)
check_call([qemu_img, 'create', '-f', 'qcow2', image_path, '8M'],
diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/aarch64/test_virt_gpu.py
index 3844727..4e50887 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 3399042..261d796 100755
--- a/tests/functional/test_aarch64_xen.py
+++ b/tests/functional/aarch64/test_xen.py
@@ -33,6 +33,7 @@ class BootXen(LinuxKernelTest):
"""
Launch Xen with a dom0 guest kernel
"""
+ self.require_accelerator("tcg") # virtualization=on
self.set_machine('virt')
self.cpu = "cortex-a57"
self.kernel_path = self.ASSET_KERNEL.fetch()
diff --git a/tests/functional/test_aarch64_xlnx_versal.py b/tests/functional/aarch64/test_xlnx_versal.py
index 4b9c49e..45aa6e1 100755
--- a/tests/functional/test_aarch64_xlnx_versal.py
+++ b/tests/functional/aarch64/test_xlnx_versal.py
@@ -6,7 +6,7 @@
from qemu_test import LinuxKernelTest, Asset
-class XlnxVersalVirtMachine(LinuxKernelTest):
+class AmdVersalVirtMachine(LinuxKernelTest):
ASSET_KERNEL = Asset(
('http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/'
@@ -20,8 +20,8 @@ class XlnxVersalVirtMachine(LinuxKernelTest):
'/ubuntu-installer/arm64/initrd.gz'),
'e7a5e716b6f516d8be315c06e7331aaf16994fe4222e0e7cfb34bc015698929e')
- def test_aarch64_xlnx_versal_virt(self):
- self.set_machine('xlnx-versal-virt')
+ def common_aarch64_amd_versal_virt(self, machine):
+ self.set_machine(machine)
kernel_path = self.ASSET_KERNEL.fetch()
initrd_path = self.ASSET_INITRD.fetch()
@@ -33,5 +33,11 @@ class XlnxVersalVirtMachine(LinuxKernelTest):
self.vm.launch()
self.wait_for_console_pattern('Checked W+X mappings: passed')
+ def test_aarch64_amd_versal_virt(self):
+ self.common_aarch64_amd_versal_virt('amd-versal-virt')
+
+ def test_aarch64_amd_versal2_virt(self):
+ self.common_aarch64_amd_versal_virt('amd-versal2-virt')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/alpha/meson.build b/tests/functional/alpha/meson.build
new file mode 100644
index 0000000..26a5b3f
--- /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 c5d7181..c5d7181 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 0000000..f11b523
--- /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 24a17ef..24a17ef 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 0000000..e4e7dba
--- /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 77037f0..e47b597 100755
--- a/tests/functional/test_arm_aspeed_ast1030.py
+++ b/tests/functional/arm/test_aspeed_ast1030.py
@@ -7,22 +7,23 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import LinuxKernelTest, Asset
+from aspeed import AspeedTest
from qemu_test import exec_command_and_wait_for_pattern
-class AST1030Machine(LinuxKernelTest):
+class AST1030Machine(AspeedTest):
- ASSET_ZEPHYR_3_00 = Asset(
+ ASSET_ZEPHYR_3_02 = Asset(
('https://github.com/AspeedTech-BMC'
- '/zephyr/releases/download/v00.03.00/ast1030-evb-demo.zip'),
- '37fe3ecd4a1b9d620971a15b96492a81093435396eeac69b6f3e384262ff555f')
+ '/zephyr/releases/download/v00.03.02/ast1030-evb-demo.zip'),
+ '1ec83caab3ddd5d09481772801be7210e222cb015ce22ec6fffb8a76956dcd4f')
- def test_ast1030_zephyros_3_00(self):
+ def test_arm_ast1030_zephyros_3_02(self):
self.set_machine('ast1030-evb')
- kernel_name = "ast1030-evb-demo/zephyr.elf"
+ kernel_name = "ast1030-evb-demo-3/zephyr.elf"
kernel_file = self.archive_extract(
- self.ASSET_ZEPHYR_3_00, member=kernel_name)
+ self.ASSET_ZEPHYR_3_02, member=kernel_name)
self.vm.set_console()
self.vm.add_args('-kernel', kernel_file, '-nographic')
@@ -36,7 +37,7 @@ class AST1030Machine(LinuxKernelTest):
'/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'),
'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c')
- def test_ast1030_zephyros_1_07(self):
+ def test_arm_ast1030_zephyros_1_07(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.bin"
@@ -68,6 +69,21 @@ class AST1030Machine(LinuxKernelTest):
'kernel uptime',
]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
+ def test_arm_ast1030_otp_blockdev_device(self):
+ self.vm.set_machine("ast1030-evb")
+
+ kernel_name = "ast1030-evb-demo-3/zephyr.elf"
+ kernel_file = self.archive_extract(self.ASSET_ZEPHYR_3_02, member=kernel_name)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-kernel", kernel_file,
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.vm.launch()
+ self.wait_for_console_pattern("Booting Zephyr OS")
if __name__ == '__main__':
- LinuxKernelTest.main()
+ AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/arm/test_aspeed_ast2500.py
index 6923fe8..4fdd81e 100755
--- a/tests/functional/test_arm_aspeed_ast2500.py
+++ b/tests/functional/arm/test_aspeed_ast2500.py
@@ -37,14 +37,14 @@ class AST2500Machine(AspeedTest):
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V906_AST2500 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2500-default-obmc.tar.gz',
- '542db84645b4efd8aed50385d7f4dd1caff379a987032311cfa7b563a3addb2a')
+ ASSET_SDK_V907_AST2500 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2500-default-obmc.tar.gz',
+ 'd52bcc279a37c8d7679b3e4ef22cc77c36f0f6624c687b37334f798828afb077')
def test_arm_ast2500_evb_sdk(self):
self.set_machine('ast2500-evb')
- self.archive_extract(self.ASSET_SDK_V906_AST2500)
+ self.archive_extract(self.ASSET_SDK_V907_AST2500)
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2500-default", "image-bmc"))
diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/arm/test_aspeed_ast2600.py
index fdae4c9..f655c0b 100755
--- a/tests/functional/test_arm_aspeed_ast2600.py
+++ b/tests/functional/arm/test_aspeed_ast2600.py
@@ -97,19 +97,39 @@ class AST2600Machine(AspeedTest):
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V906_AST2600 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2600-default-obmc.tar.gz',
- '768d76e247896ad78c154b9cff4f766da2ce65f217d620b286a4a03a8a4f68f5')
+ ASSET_SDK_V907_AST2600 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.07/ast2600-default-obmc.tar.gz',
+ 'cb6c08595bcbba1672ce716b068ba4e48eda1ed9abe78a07b30392ba2278feba')
+
+ def do_ast2600_pcie_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:00.0',
+ '80:00.0 Host bridge: '
+ 'ASPEED Technology, Inc. Device 2600')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:08.0',
+ '80:08.0 PCI bridge: '
+ 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 81:00.0',
+ '81:00.0 Ethernet controller: '
+ 'Intel Corporation 82574L Gigabit Network Connection')
+ exec_command_and_wait_for_pattern(self,
+ 'ip addr show dev eth4',
+ 'inet 10.0.2.15/24')
def test_arm_ast2600_evb_sdk(self):
self.set_machine('ast2600-evb')
+ self.require_netdev('user')
- self.archive_extract(self.ASSET_SDK_V906_AST2600)
+ self.archive_extract(self.ASSET_SDK_V907_AST2600)
self.vm.add_args('-device',
'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.0')
+ self.vm.add_args('-netdev', 'user,id=net1')
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2600-default", "image-bmc"))
@@ -135,6 +155,22 @@ class AST2600Machine(AspeedTest):
year = time.strftime("%Y")
exec_command_and_wait_for_pattern(self,
'/sbin/hwclock -f /dev/rtc1', year)
+ self.do_ast2600_pcie_test()
+
+ def test_arm_ast2600_otp_blockdev_device(self):
+ self.vm.set_machine("ast2600-evb")
+
+ image_path = self.archive_extract(self.ASSET_SDK_V907_AST2600)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.do_test_arm_aspeed_sdk_start(
+ self.scratch_file("ast2600-default", "image-bmc"))
+ self.wait_for_console_pattern("ast2600-default login:")
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_bletchley.py b/tests/functional/arm/test_aspeed_bletchley.py
index 5a60b24..5a60b24 100644..100755
--- a/tests/functional/test_arm_aspeed_bletchley.py
+++ b/tests/functional/arm/test_aspeed_bletchley.py
diff --git a/tests/functional/arm/test_aspeed_catalina.py b/tests/functional/arm/test_aspeed_catalina.py
new file mode 100755
index 0000000..dc2f24e
--- /dev/null
+++ b/tests/functional/arm/test_aspeed_catalina.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from aspeed import AspeedTest
+
+
+class CatalinaMachine(AspeedTest):
+
+ ASSET_CATALINA_FLASH = Asset(
+ 'https://github.com/legoater/qemu-aspeed-boot/raw/a866feb5ef81245b4827a214584bf6bcc72939f6/images/catalina-bmc/obmc-phosphor-image-catalina-20250619123021.static.mtd.xz',
+ '287402e1ba021991e06be1d098f509444a02a3d81a73a932f66528b159e864f9')
+
+ def test_arm_ast2600_catalina_openbmc(self):
+ image_path = self.uncompress(self.ASSET_CATALINA_FLASH)
+
+ self.do_test_arm_aspeed_openbmc('catalina-bmc', image=image_path,
+ uboot='2019.04', cpu_id='0xf00',
+ soc='AST2600 rev A3')
+
+if __name__ == '__main__':
+ AspeedTest.main()
diff --git a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
new file mode 100755
index 0000000..8e8e3f0
--- /dev/null
+++ b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from aspeed import AspeedTest
+
+
+class GB200Machine(AspeedTest):
+
+ ASSET_GB200_FLASH = Asset(
+ 'https://github.com/legoater/qemu-aspeed-boot/raw/refs/heads/master/images/gb200nvl-obmc/obmc-phosphor-image-gb200nvl-obmc-20250702182348.static.mtd.xz',
+ 'b84819317cb3dc762895ad507705978ef000bfc77c50c33a63bdd37921db0dbc')
+
+ def test_arm_aspeed_gb200_openbmc(self):
+ image_path = self.uncompress(self.ASSET_GB200_FLASH)
+
+ self.do_test_arm_aspeed_openbmc('gb200nvl-bmc', image=image_path,
+ uboot='2019.04', cpu_id='0xf00',
+ soc='AST2600 rev A3',
+ image_hostname='gb200nvl-obmc')
+
+if __name__ == '__main__':
+ AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/arm/test_aspeed_palmetto.py
index ff0b821..ff0b821 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 602d619..602d619 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 0447212..0447212 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 51a2d47..51a2d47 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 f273fc8..f273fc8 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 8bed64b..8bed64b 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 21a1a59..21a1a59 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 fe1be3d..fe1be3d 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 b536c2f..b536c2f 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 f9f3f06..f9f3f06 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 4f00924..23ae919 100755
--- a/tests/functional/test_arm_integratorcp.py
+++ b/tests/functional/arm/test_integratorcp.py
@@ -77,7 +77,6 @@ class IntegratorMachine(QemuSystemTest):
command_line='screendump %s' % screendump_path)
if 'unknown command' in res:
self.skipTest('screendump not available')
- logger = logging.getLogger('framebuffer')
cpu_count = 1
match_threshold = 0.92
@@ -88,7 +87,7 @@ class IntegratorMachine(QemuSystemTest):
loc = np.where(result >= match_threshold)
tux_count = 0
for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
- logger.debug('found Tux at position [x, y] = %s', pt)
+ self.log.debug('found Tux at position [x, y] = %s', pt)
self.assertGreaterEqual(tux_count, cpu_count)
if __name__ == '__main__':
diff --git a/tests/functional/arm/test_max78000fthr.py b/tests/functional/arm/test_max78000fthr.py
new file mode 100755
index 0000000..a82980b
--- /dev/null
+++ b/tests/functional/arm/test_max78000fthr.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Functional test that checks the max78000fthr machine.
+# Tests ICC, GCR, TRNG, AES, and UART
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class Max78000Machine(QemuSystemTest):
+
+ ASSET_FW = Asset(
+ 'https://github.com/JacksonDonaldson/max78000Test/raw/main/build/max78000.bin',
+ '86940b4bf60931bc6a8aa5db4b9f7f3cf8f64dbbd7ac534647980e536cf3adf7')
+
+ def test_fthr(self):
+ self.set_machine('max78000fthr')
+ fw_path = self.ASSET_FW.fetch()
+ self.vm.set_console()
+ self.vm.add_args('-kernel', fw_path)
+ self.vm.add_args('-device', "loader,file=" + fw_path + ",addr=0x10000000")
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'started')
+
+ # i -> prints instruction cache values
+ exec_command_and_wait_for_pattern(self, 'i', 'CTRL: 00010001')
+
+ # r -> gcr resets the machine
+ exec_command_and_wait_for_pattern(self, 'r', 'started')
+
+ # z -> sets some memory, then has gcr zero it
+ exec_command_and_wait_for_pattern(self, 'z', 'initial value: 12345678')
+ wait_for_console_pattern(self, "after memz: 00000000")
+
+ # t -> runs trng
+ exec_command_and_wait_for_pattern(self, 't', 'random data:')
+
+ # a -> runs aes
+ exec_command_and_wait_for_pattern(self, 'a',
+ 'encrypted to : a47ca9dd e0df4c86 a070af6e 91710dec')
+ wait_for_console_pattern(self,
+ 'encrypted to : cab7a28e bf456751 9049fcea 8960494b')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_arm_microbit.py b/tests/functional/arm/test_microbit.py
index 68ea4e7..68ea4e7 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 0000000..0aa89f4
--- /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 f9bfa8c..f9bfa8c 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 cb0545f..cb0545f 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 d3c7aaa..d3c7aaa 100755
--- a/tests/functional/test_arm_raspi2.py
+++ b/tests/functional/arm/test_raspi2.py
diff --git a/tests/functional/arm/test_realview.py b/tests/functional/arm/test_realview.py
new file mode 100755
index 0000000..82cc964
--- /dev/null
+++ b/tests/functional/arm/test_realview.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel on a realview arm machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, exec_command_and_wait_for_pattern
+from qemu_test import Asset
+
+
+class RealviewMachine(LinuxKernelTest):
+
+ ASSET_REALVIEW_MPCORE = Asset(
+ ('https://archive.openwrt.org/chaos_calmer/15.05.1/realview/generic/'
+ 'openwrt-15.05.1-realview-vmlinux-initramfs.elf'),
+ 'd3a01037f33e7512d46d50975588d5c3a0e0cbf25f37afab44775c2a2be523e6')
+
+ def test_realview_ep_mpcore(self):
+ self.require_netdev('user')
+ self.set_machine('realview-eb-mpcore')
+ kernel_path = self.ASSET_REALVIEW_MPCORE.fetch()
+ self.vm.set_console()
+ kernel_param = 'console=ttyAMA0 mem=128M quiet'
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_param)
+ self.vm.launch()
+ self.wait_for_console_pattern('Please press Enter to activate')
+ prompt = ':/#'
+ exec_command_and_wait_for_pattern(self, '', prompt)
+ exec_command_and_wait_for_pattern(self, 'dmesg', kernel_param)
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ ('while ! dmesg | grep "br-lan: port 1(eth0) entered" ;'
+ ' do sleep 1 ; done'),
+ 'entered forwarding state')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ 'while ! ifconfig | grep "10.0.2.15" ; do sleep 1 ; done',
+ 'addr:10.0.2.15')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self, 'ping -c 1 10.0.2.2',
+ '1 packets received, 0% packet loss')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_arm_replay.py b/tests/functional/arm/test_replay.py
index e002e6a..e002e6a 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 3154e7f..3154e7f 100755
--- a/tests/functional/test_arm_smdkc210.py
+++ b/tests/functional/arm/test_smdkc210.py
diff --git a/tests/functional/arm/test_stellaris.py b/tests/functional/arm/test_stellaris.py
new file mode 100755
index 0000000..cbd21cb
--- /dev/null
+++ b/tests/functional/arm/test_stellaris.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Functional test that checks the serial console of the stellaris machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class StellarisMachine(QemuSystemTest):
+
+ ASSET_DAY22 = Asset(
+ 'https://www.qemu-advent-calendar.org/2023/download/day22.tar.gz',
+ 'ae3a63ef4b7a22c21bfc7fc0d85e402fe95e223308ed23ac854405016431ff51')
+
+ def test_lm3s6965evb(self):
+ self.set_machine('lm3s6965evb')
+ kernel_path = self.archive_extract(self.ASSET_DAY22,
+ member='day22/day22.bin')
+ self.vm.set_console()
+ self.vm.add_args('-kernel', kernel_path)
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'In a one horse open')
+
+ ASSET_NOTMAIN = Asset(
+ 'https://github.com/Ahelion/QemuArmM4FDemoSw/raw/master/build/notmain.bin',
+ '6ceda031aa081a420fca2fca9e137fa681d6e3820d820ad1917736cb265e611a')
+
+ def test_lm3s811evb(self):
+ self.set_machine('lm3s811evb')
+ kernel_path = self.ASSET_NOTMAIN.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-cpu', 'cortex-m4')
+ self.vm.add_args('-kernel', kernel_path)
+ self.vm.launch()
+
+ # The test kernel emits an initial '!' and then waits for input.
+ # For each character that we send it responds with a certain
+ # other ASCII character.
+ wait_for_console_pattern(self, '!')
+ exec_command_and_wait_for_pattern(self, '789', 'cdf')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/arm/test_sx1.py
index 25800b3..25800b3 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 4ac85f4..4ac85f4 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 6b11552..6b11552 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 7b65491..7b65491 100755
--- a/tests/functional/test_arm_virt.py
+++ b/tests/functional/arm/test_virt.py
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
index 7a40d5d..47e84e0 100644
--- a/tests/functional/aspeed.py
+++ b/tests/functional/aspeed.py
@@ -8,8 +8,13 @@ from qemu_test import LinuxKernelTest
class AspeedTest(LinuxKernelTest):
def do_test_arm_aspeed_openbmc(self, machine, image, uboot='2019.04',
- cpu_id='0x0', soc='AST2500 rev A1'):
- hostname = machine.removesuffix('-bmc')
+ cpu_id='0x0', soc='AST2500 rev A1',
+ image_hostname=None):
+ # Allow for the image hostname to not end in "-bmc"
+ if image_hostname is not None:
+ hostname = image_hostname
+ else:
+ hostname = machine.removesuffix('-bmc')
self.set_machine(machine)
self.vm.set_console()
@@ -56,3 +61,11 @@ class AspeedTest(LinuxKernelTest):
self.wait_for_console_pattern('U-Boot 2019.04')
self.wait_for_console_pattern('## Loading kernel from FIT Image')
self.wait_for_console_pattern('Starting kernel ...')
+
+ def generate_otpmem_image(self):
+ path = self.scratch_file("otpmem.img")
+ pattern = b'\x00\x00\x00\x00\xff\xff\xff\xff' * (16 * 1024 // 8)
+ with open(path, "wb") as f:
+ f.write(pattern)
+ return path
+
diff --git a/tests/functional/avr/meson.build b/tests/functional/avr/meson.build
new file mode 100644
index 0000000..7a2cb70
--- /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 8e47b42..6359b72 100755
--- a/tests/functional/test_avr_mega2560.py
+++ b/tests/functional/avr/test_mega2560.py
@@ -18,12 +18,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import time
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
-from qemu_test import QemuSystemTest, Asset
class AVR6Machine(QemuSystemTest):
- timeout = 5
ASSET_ROM = Asset(('https://github.com/seharris/qemu-avr-tests'
'/raw/36c3e67b8755dcf/free-rtos/Demo'
@@ -40,13 +38,12 @@ class AVR6Machine(QemuSystemTest):
self.set_machine('arduino-mega-2560-v3')
self.vm.add_args('-bios', rom_path)
self.vm.add_args('-nographic')
+ self.vm.set_console()
self.vm.launch()
- time.sleep(2)
- self.vm.shutdown()
+ wait_for_console_pattern(self,
+ 'XABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWXA')
- self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
- self.vm.get_log())
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/avr/test_uno.py b/tests/functional/avr/test_uno.py
new file mode 100755
index 0000000..adb3b73
--- /dev/null
+++ b/tests/functional/avr/test_uno.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+#
+# QEMU AVR Arduino UNO functional test
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+
+
+class UnoMachine(QemuSystemTest):
+
+ ASSET_UNO = Asset(
+ ('https://github.com/RahulRNandan/LED_Blink_AVR/raw/'
+ 'c6d602cbb974a193/build/main.elf'),
+ '3009a4e2cf5c5b65142f538abdf66d4dc6bc6beab7e552fff9ae314583761b72')
+
+ def test_uno(self):
+ """
+ The binary constantly prints out 'LED Blink'
+ """
+ self.set_machine('arduino-uno')
+ rom_path = self.ASSET_UNO.fetch()
+
+ self.vm.add_args('-bios', rom_path)
+ self.vm.set_console()
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'LED Blink')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/generic/meson.build b/tests/functional/generic/meson.build
new file mode 100644
index 0000000..013cc96
--- /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 0081b06..0081b06 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 e8cbc37..e8cbc37 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 3ab3b67..3ab3b67 100755
--- a/tests/functional/test_version.py
+++ b/tests/functional/generic/test_version.py
diff --git a/tests/functional/generic/test_vmstate.py b/tests/functional/generic/test_vmstate.py
new file mode 100755
index 0000000..387ff54
--- /dev/null
+++ b/tests/functional/generic/test_vmstate.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+'''This test runs the vmstate-static-checker script with the current QEMU'''
+
+import subprocess
+
+from qemu_test import QemuSystemTest, skipFlakyTest
+
+
+@skipFlakyTest("vmstate-static-checker can produce false positives")
+class VmStateTest(QemuSystemTest):
+ '''
+ This test helps to check whether there are problems between old
+ reference data and the current QEMU
+ '''
+
+ def test_vmstate_7_2(self):
+ '''Check reference data from QEMU v7.2'''
+
+ target_machine = {
+ 'aarch64': 'virt-7.2',
+ 'm68k': 'virt-7.2',
+ 'ppc64': 'pseries-7.2',
+ 's390x': 's390-ccw-virtio-7.2',
+ 'x86_64': 'pc-q35-7.2',
+ }
+ self.set_machine(target_machine[self.arch])
+
+ # Run QEMU to get the current vmstate json file:
+ dst_json = self.scratch_file('dest.json')
+ self.log.info('Dumping vmstate from %s', self.qemu_bin)
+ cp = subprocess.run([self.qemu_bin, '-nodefaults',
+ '-M', target_machine[self.arch],
+ '-dump-vmstate', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=True)
+ if cp.stdout:
+ self.log.info('QEMU output: %s', cp.stdout)
+
+ # Check whether the old vmstate json file is still compatible:
+ src_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ self.arch,
+ target_machine[self.arch] + '.json')
+ self.log.info('Comparing vmstate with %s', src_json)
+ checkerscript = self.data_file('..', '..', 'scripts',
+ 'vmstate-static-checker.py')
+ cp = subprocess.run([checkerscript, '-s', src_json, '-d', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=False)
+ if cp.returncode != 0:
+ self.fail('Running vmstate-static-checker failed:\n' + cp.stdout +
+ '\nThis either means that there is a migration bug '
+ 'that needs to be fixed, or\nvmstate-static-checker.py '
+ 'needs to be improved (e.g. extend the changed_names\n'
+ 'in case a field has been renamed), or drop the '
+ 'problematic field from\n' + src_json +
+ '\nin case the script cannot be fixed easily.')
+ if cp.stdout:
+ self.log.warning('vmstate-static-checker output: %s', cp.stdout)
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_vnc.py b/tests/functional/generic/test_vnc.py
index 5c0ee5f..f1dd159 100755
--- a/tests/functional/test_vnc.py
+++ b/tests/functional/generic/test_vnc.py
@@ -31,6 +31,7 @@ def check_connect(port: int) -> bool:
class Vnc(QemuSystemTest):
def test_no_vnc_change_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S')
self.vm.launch()
@@ -62,6 +63,7 @@ class Vnc(QemuSystemTest):
raise excp
def test_change_password_requires_a_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S', '-vnc', ':1,to=999')
self.launch_guarded()
self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
@@ -74,6 +76,7 @@ class Vnc(QemuSystemTest):
'Could not set password')
def test_change_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S', '-vnc', ':1,to=999,password=on')
self.launch_guarded()
self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
@@ -103,6 +106,7 @@ class Vnc(QemuSystemTest):
self.assertTrue(check_connect(c))
def test_change_listen(self):
+ self.set_machine('none')
with Ports() as ports:
a, b, c = ports.find_free_ports(3)
self.do_test_change_listen(a, b, c)
diff --git a/tests/functional/hppa/meson.build b/tests/functional/hppa/meson.build
new file mode 100644
index 0000000..df2f7cc
--- /dev/null
+++ b/tests/functional/hppa/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_hppa_system_quick = [
+ 'seabios',
+]
+
+tests_hppa_system_thorough = [
+ 'cdboot',
+]
diff --git a/tests/functional/hppa/test_cdboot.py b/tests/functional/hppa/test_cdboot.py
new file mode 100755
index 0000000..84421e8
--- /dev/null
+++ b/tests/functional/hppa/test_cdboot.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# CD boot test for HPPA machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class HppaCdBoot(QemuSystemTest):
+
+ ASSET_CD = Asset(
+ ('https://github.com/philmd/qemu-testing-blob/raw/ec1b741/'
+ 'hppa/hp9000/712/C7120023.frm'),
+ '32c612ad2074516986bdc27768903c561fa92af2ca48e5ac3f3359ade1c42f70')
+
+ def test_cdboot(self):
+ self.set_machine('B160L')
+ cdrom_path = self.ASSET_CD.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-cdrom', cdrom_path,
+ '-boot', 'd',
+ '-no-reboot')
+ self.vm.launch()
+ wait_for_console_pattern(self, 'Unrecognized MODEL TYPE = 502')
+ wait_for_console_pattern(self, 'UPDATE PAUSED>')
+
+ exec_command_and_wait_for_pattern(self, 'exit\r', 'UPDATE>')
+ exec_command_and_wait_for_pattern(self, 'ls\r', 'IMAGE1B')
+ wait_for_console_pattern(self, 'UPDATE>')
+ exec_command_and_wait_for_pattern(self, 'exit\r',
+ 'THIS UTILITY WILL NOW RESET THE SYSTEM.....')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_hppa_seabios.py b/tests/functional/hppa/test_seabios.py
index 661b246..661b246 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 0000000..23d8c21
--- /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 0000000..a57f316
--- /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 7c4c260..7c4c260 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 f3ccf11..f3ccf11 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 0000000..d168717
--- /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 b7d9abf..b7d9abf 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 0000000..679faaf
--- /dev/null
+++ b/tests/functional/m68k/meson.build
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_m68k_system_quick = [
+ 'vmstate',
+]
+
+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 c7d1998..c7d1998 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 13c72bd..e5e1c69 100755
--- a/tests/functional/test_m68k_nextcube.py
+++ b/tests/functional/m68k/test_nextcube.py
@@ -29,8 +29,15 @@ class NextCubeMachine(QemuSystemTest):
self.vm.launch()
self.log.info('VM launched, waiting for display')
- # TODO: wait for the 'displaysurface_create 1120x832' trace-event.
- time.sleep(2)
+ # Wait for the FPU test to finish, then the display is available, too:
+ while True:
+ res = self.vm.cmd('human-monitor-command',
+ command_line='info registers')
+ if ("F0 = 400e 8400000000000000" in res and
+ "F1 = 400e 83ff000000000000" in res and
+ "F2 = 400e 83ff000000000000" in res):
+ break
+ time.sleep(0.1)
res = self.vm.cmd('human-monitor-command',
command_line='screendump %s' % screenshot_path)
@@ -44,7 +51,8 @@ class NextCubeMachine(QemuSystemTest):
self.check_bootrom_framebuffer(screenshot_path)
from PIL import Image
- width, height = Image.open(screenshot_path).size
+ with Image.open(screenshot_path) as image:
+ width, height = image.size
self.assertEqual(width, 1120)
self.assertEqual(height, 832)
@@ -55,10 +63,10 @@ class NextCubeMachine(QemuSystemTest):
self.check_bootrom_framebuffer(screenshot_path)
lines = tesseract_ocr(screenshot_path)
text = '\n'.join(lines)
+ self.assertIn('Backplane slot', text)
+ self.assertIn('Ethernet address', text)
self.assertIn('Testing the FPU', text)
- self.assertIn('System test failed. Error code', text)
- self.assertIn('Boot command', text)
- self.assertIn('Next>', text)
+
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_m68k_q800.py b/tests/functional/m68k/test_q800.py
index 400b7ae..b3e6553 100755
--- a/tests/functional/test_m68k_q800.py
+++ b/tests/functional/m68k/test_q800.py
@@ -25,7 +25,8 @@ class Q800MachineTest(LinuxKernelTest):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 vga=off')
self.vm.add_args('-kernel', kernel_path,
- '-append', kernel_command_line)
+ '-append', kernel_command_line,
+ '-audio', 'none')
self.vm.launch()
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.wait_for_console_pattern(console_pattern)
diff --git a/tests/functional/test_m68k_replay.py b/tests/functional/m68k/test_replay.py
index 18c1db5..213d6ae 100755
--- a/tests/functional/test_m68k_replay.py
+++ b/tests/functional/m68k/test_replay.py
@@ -24,7 +24,8 @@ class M68kReplay(ReplayKernelBase):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 vga=off')
console_pattern = 'No filesystem could mount root'
- self.run_rr(kernel_path, kernel_command_line, console_pattern)
+ self.run_rr(kernel_path, kernel_command_line, console_pattern,
+ args=('-audio', 'none'))
ASSET_MCF5208 = Asset(
'https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/day07.tar.xz',
diff --git a/tests/functional/test_m68k_tuxrun.py b/tests/functional/m68k/test_tuxrun.py
index 7eacba1..7eacba1 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 52b4706..725630d 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -9,330 +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_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_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_imx8mp_evk',
- '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_rainier',
- 'arm_bpim2u',
- 'arm_canona1100',
- 'arm_collie',
- 'arm_cubieboard',
- 'arm_emcraft_sf2',
- 'arm_integratorcp',
- 'arm_microbit',
- 'arm_orangepi',
- 'arm_quanta_gsj',
- 'arm_raspi2',
- 'arm_replay',
- 'arm_smdkc210',
- 'arm_sx1',
- 'arm_vexpress',
- 'arm_virt',
- 'arm_tuxrun',
-]
-
-tests_arm_linuxuser_thorough = [
- 'arm_bflt',
-]
-
-tests_avr_system_thorough = [
- 'avr_mega2560',
-]
-
-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_tuxrun',
-]
-
-tests_rx_system_thorough = [
- 'rx_gdbsim',
-]
-
-tests_s390x_system_thorough = [
- 's390x_ccw_virtio',
- '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',
-]
-
-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']
@@ -362,7 +66,7 @@ foreach speed : ['quick', 'thorough']
target_tests = get_variable('tests_' + target_base + '_' + sysmode + '_' + speed, [])
endif
- test_deps = roms
+ test_deps = [roms, keymap_targets]
test_env = environment()
if have_tools
test_env.set('QEMU_TEST_QEMU_IMG', meson.global_build_root() / 'qemu-img')
@@ -373,9 +77,19 @@ foreach speed : ['quick', 'thorough']
test_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
meson.current_source_dir())
+ # Define the GDB environment variable if gdb is available.
+ gdb = get_option('gdb')
+ if gdb != ''
+ test_env.set('QEMU_TEST_GDB', gdb)
+ endif
+
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()
@@ -389,6 +103,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
@@ -404,8 +123,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
@@ -413,4 +132,4 @@ endforeach
run_target('precache-functional',
depends: precache_all,
- command: ['true'])
+ command: [python, '-c', ''])
diff --git a/tests/functional/microblaze/meson.build b/tests/functional/microblaze/meson.build
new file mode 100644
index 0000000..8069ca9
--- /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 7484c41..7484c41 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 c93fa14..f093b16 100755
--- a/tests/functional/test_microblaze_s3adsp1800.py
+++ b/tests/functional/microblaze/test_s3adsp1800.py
@@ -25,12 +25,14 @@ class MicroblazeMachine(QemuSystemTest):
('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'),
'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22')
- def do_ballerina_be_test(self, machine):
- self.set_machine(machine)
+ def do_ballerina_be_test(self, force_endianness=False):
+ self.set_machine('petalogix-s3adsp1800')
self.archive_extract(self.ASSET_IMAGE_BE)
self.vm.set_console()
self.vm.add_args('-kernel',
self.scratch_file('day17', 'ballerina.bin'))
+ if force_endianness:
+ self.vm.add_args('-M', 'endianness=big')
self.vm.launch()
wait_for_console_pattern(self, 'This architecture does not have '
'kernel memory protection')
@@ -39,12 +41,14 @@ class MicroblazeMachine(QemuSystemTest):
# message, that's why we don't test for a later string here. This
# needs some investigation by a microblaze wizard one day...
- def do_xmaton_le_test(self, machine):
+ def do_xmaton_le_test(self, force_endianness=False):
self.require_netdev('user')
- self.set_machine(machine)
+ self.set_machine('petalogix-s3adsp1800')
self.archive_extract(self.ASSET_IMAGE_LE)
self.vm.set_console()
self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin'))
+ if force_endianness:
+ self.vm.add_args('-M', 'endianness=little')
tftproot = self.scratch_file('day13')
self.vm.add_args('-nic', f'user,tftp={tftproot}')
self.vm.launch()
@@ -59,9 +63,13 @@ class MicroblazeMachine(QemuSystemTest):
class MicroblazeBigEndianMachine(MicroblazeMachine):
ASSET_IMAGE_BE = MicroblazeMachine.ASSET_IMAGE_BE
+ ASSET_IMAGE_LE = MicroblazeMachine.ASSET_IMAGE_LE
def test_microblaze_s3adsp1800_legacy_be(self):
- self.do_ballerina_be_test('petalogix-s3adsp1800')
+ self.do_ballerina_be_test()
+
+ def test_microblaze_s3adsp1800_legacy_le(self):
+ self.do_xmaton_le_test(force_endianness=True)
if __name__ == '__main__':
diff --git a/tests/functional/microblazeel/meson.build b/tests/functional/microblazeel/meson.build
new file mode 100644
index 0000000..27619dc
--- /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 ab59941..75ce885 100755
--- a/tests/functional/test_microblazeel_s3adsp1800.py
+++ b/tests/functional/microblazeel/test_s3adsp1800.py
@@ -7,15 +7,19 @@
# 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):
ASSET_IMAGE_LE = MicroblazeMachine.ASSET_IMAGE_LE
+ ASSET_IMAGE_BE = MicroblazeMachine.ASSET_IMAGE_BE
def test_microblaze_s3adsp1800_legacy_le(self):
- self.do_xmaton_le_test('petalogix-s3adsp1800')
+ self.do_xmaton_le_test()
+
+ def test_microblaze_s3adsp1800_legacy_be(self):
+ self.do_ballerina_be_test(force_endianness=True)
if __name__ == '__main__':
diff --git a/tests/functional/test_migration.py b/tests/functional/migration.py
index c4393c3..0739554 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 0000000..49aaf53
--- /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 89b9556..30279f0 100755
--- a/tests/functional/test_mips_malta.py
+++ b/tests/functional/mips/test_malta.py
@@ -80,10 +80,8 @@ def mips_check_wheezy(test, kernel_path, image_path, kernel_command_line,
exec_command_and_wait_for_pattern(test, 'cat /proc/devices', 'usb')
exec_command_and_wait_for_pattern(test, 'cat /proc/ioports',
' : piix4_smbus')
- # lspci for the host bridge does not work on big endian targets:
- # https://gitlab.com/qemu-project/qemu/-/issues/2826
- # exec_command_and_wait_for_pattern(test, 'lspci -d 11ab:4620',
- # 'GT-64120')
+ exec_command_and_wait_for_pattern(test, 'lspci -d 11ab:4620',
+ 'GT-64120')
exec_command_and_wait_for_pattern(test,
'cat /sys/bus/i2c/devices/i2c-0/name',
'SMBus PIIX4 adapter')
diff --git a/tests/functional/test_mips_replay.py b/tests/functional/mips/test_replay.py
index 4327481..4327481 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 6771dbd..6771dbd 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 0000000..3ff2118
--- /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 53c3e0c..a553d3c 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 0e4c659..0e4c659 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 0000000..69ec501
--- /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 35e500b..35e500b 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 f85371e..f85371e 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 3cc79b7..170147b 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):
@@ -159,7 +159,6 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
command_line='screendump %s' % screendump_path)
if 'unknown command' in res:
self.skipTest('screendump not available')
- logger = logging.getLogger('framebuffer')
match_threshold = 0.95
screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR)
@@ -171,7 +170,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
h, w = tuxlogo_bgr.shape[:2]
debug_png = os.getenv('QEMU_TEST_CV2_SCREENDUMP_PNG_PATH')
for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1):
- logger.debug('found Tux at position (x, y) = %s', pt)
+ self.log.debug('found Tux at position (x, y) = %s', pt)
cv2.rectangle(screendump_bgr, pt,
(pt[0] + w, pt[1] + h), (0, 0, 255), 2)
if debug_png:
@@ -191,7 +190,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 26a6ccf..26a6ccf 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 0a24757..0a24757 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 0000000..8bfdf06
--- /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 9ee2884..427e163 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 5f4796c..5f4796c 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 d4b39ba..d4b39ba 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 751cf10..6a06c1e 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"""
@@ -83,18 +63,5 @@ class Multiprocess(QemuSystemTest):
'cat /sys/bus/pci/devices/*/uevent',
'PCI_ID=1000:0012')
- 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()
+ proxy_sock.close()
+ remote_sock.close()
diff --git a/tests/functional/or1k/meson.build b/tests/functional/or1k/meson.build
new file mode 100644
index 0000000..e246e2a
--- /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 2b60a93..2b60a93 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 f9f0b69..f9f0b69 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 0000000..ae061fe
--- /dev/null
+++ b/tests/functional/ppc/meson.build
@@ -0,0 +1,23 @@
+# 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',
+ 'ppe42',
+ 'replay',
+ 'sam460ex',
+ 'tuxrun',
+ 'virtex_ml507',
+]
diff --git a/tests/functional/test_ppc_40p.py b/tests/functional/ppc/test_40p.py
index 614972a..614972a 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 5386016..5386016 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 8600e2e..8600e2e 100755
--- a/tests/functional/test_ppc_amiga.py
+++ b/tests/functional/ppc/test_amiga.py
diff --git a/tests/functional/ppc/test_bamboo.py b/tests/functional/ppc/test_bamboo.py
new file mode 100755
index 0000000..c634ae7
--- /dev/null
+++ b/tests/functional/ppc/test_bamboo.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Test that Linux kernel boots on the ppc bamboo board and check the console
+#
+# Copyright (c) 2021 Red Hat
+#
+# 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 qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class BambooMachine(QemuSystemTest):
+
+ timeout = 90
+
+ ASSET_KERNEL = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc_bamboo-2023.11-8-gdcd9f0f6eb-20240105/vmlinux'),
+ 'a2e12eb45b73491ac62fc0bbeb68dead0dc5c0f22cf83146558389209b420ad1')
+ ASSET_INITRD = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc_bamboo-2023.11-8-gdcd9f0f6eb-20240105/rootfs.cpio'),
+ 'd2a36bdb8763b389765dc8c29d4904cec2bd001c587f92e85ab9eb10d5ddda54')
+
+ def test_ppc_bamboo(self):
+ self.set_machine('bamboo')
+ self.require_accelerator("tcg")
+ self.require_netdev('user')
+
+ kernel = self.ASSET_KERNEL.fetch()
+ initrd = self.ASSET_INITRD.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-kernel', kernel,
+ '-initrd', initrd,
+ '-nic', 'user,model=virtio-net-pci,restrict=on')
+ self.vm.launch()
+ wait_for_console_pattern(self, 'buildroot login:')
+ exec_command_and_wait_for_pattern(self, 'root', '#')
+ exec_command_and_wait_for_pattern(self, 'ping -c1 10.0.2.2',
+ '1 packets transmitted, 1 packets received, 0% packet loss')
+ exec_command_and_wait_for_pattern(self, 'halt', 'System Halted')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_ppc_mac.py b/tests/functional/ppc/test_mac.py
index 9e4bc1a..9e4bc1a 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 0000000..a869282
--- /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 0715410..0715410 100755
--- a/tests/functional/test_ppc_mpc8544ds.py
+++ b/tests/functional/ppc/test_mpc8544ds.py
diff --git a/tests/functional/ppc/test_ppe42.py b/tests/functional/ppc/test_ppe42.py
new file mode 100644
index 0000000..26bbe11
--- /dev/null
+++ b/tests/functional/ppc/test_ppe42.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the IBM PPE42 processor
+#
+# Copyright (c) 2025, IBM Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset
+import asyncio
+
+class Ppe42Machine(QemuSystemTest):
+
+ timeout = 90
+ poll_period = 1.0
+
+ ASSET_PPE42_TEST_IMAGE = Asset(
+ ('https://github.com/milesg-github/ppe42-tests/raw/refs/heads/main/'
+ 'images/ppe42-test.out'),
+ '03c1ac0fb7f6c025102a02776a93b35101dae7c14b75e4eab36a337e39042ea8')
+
+ def _test_completed(self):
+ self.log.info("Checking for test completion...")
+ try:
+ output = self.vm.cmd('human-monitor-command',
+ command_line='info registers')
+ except Exception as err:
+ self.log.debug(f"'info registers' cmd failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ self.log.info(output)
+ if "NIP fff80200" in output:
+ self.log.info("<test completed>")
+ return True
+ else:
+ self.log.info("<test not completed>")
+ return False
+
+ def _wait_pass_fail(self, timeout):
+ while not self._test_completed():
+ if timeout >= self.poll_period:
+ timeout = timeout - self.poll_period
+ self.log.info(f"Waiting {self.poll_period} seconds for test"
+ " to complete...")
+ e = None
+ try:
+ e = self.vm.event_wait('STOP', self.poll_period)
+
+ except asyncio.TimeoutError:
+ self.log.info("Poll period ended.")
+ pass
+
+ except Exception as err:
+ self.log.debug(f"event_wait() failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ if e != None:
+ self.log.debug(f"Execution stopped: {e}")
+ self.log.debug("Exiting due to test failure")
+ self.fail("Failure detected!")
+ break
+ else:
+ self.fail("Timed out waiting for test completion.")
+
+ def test_ppe42_instructions(self):
+ self.set_machine('ppe42_machine')
+ self.require_accelerator("tcg")
+ image_path = self.ASSET_PPE42_TEST_IMAGE.fetch()
+ self.vm.add_args('-nographic')
+ self.vm.add_args('-device', f'loader,file={image_path}')
+ self.vm.add_args('-device', 'loader,addr=0xfff80040,cpu-num=0')
+ self.vm.add_args('-action', 'panic=pause')
+ self.vm.launch()
+ self._wait_pass_fail(self.timeout)
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_ppc_replay.py b/tests/functional/ppc/test_replay.py
index 8382070..8382070 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 31cf9dd..31cf9dd 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 5458a7f..5458a7f 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 8fe4354..8fe4354 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 0000000..1fa0a70
--- /dev/null
+++ b/tests/functional/ppc64/meson.build
@@ -0,0 +1,26 @@
+# 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',
+ 'vmstate',
+]
+
+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 f5fcad9..f5fcad9 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 d87f440..d87f440 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 dfd9c01..dfd9c01 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 0000000..5dfdaaf
--- /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 685e217..9ada832 100755
--- a/tests/functional/test_ppc64_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
@@ -18,9 +18,14 @@ class powernvMachine(LinuxKernelTest):
good_message = 'VFS: Cannot open root device'
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora-secondary/'
- 'releases/29/Everything/ppc64le/os/ppc/ppc64/vmlinuz'),
- '383c2f5c23bc0d9d32680c3924d3fd7ee25cc5ef97091ac1aa5e1d853422fc5f')
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/vmlinux'),
+ '6fd29aff9ad4362511ea5d0acbb510667c7031928e97d64ec15bbc5daf4b8151')
+
+ ASSET_INITRD = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/rootfs.ext2'),
+ 'aee2192b692077c4bde31cb56ce474424b358f17cec323d5c94af3970c9aada2')
def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
self.require_accelerator("tcg")
@@ -78,27 +83,24 @@ class powernvMachine(LinuxKernelTest):
wait_for_console_pattern(self, console_pattern, self.panic_message)
wait_for_console_pattern(self, self.good_message, self.panic_message)
-
- ASSET_EPAPR_KERNEL = Asset(
- ('https://github.com/open-power/op-build/releases/download/v2.7/'
- 'zImage.epapr'),
- '0ab237df661727e5392cee97460e8674057a883c5f74381a128fa772588d45cd')
-
def do_test_ppc64_powernv(self, proc):
self.require_accelerator("tcg")
- kernel_path = self.ASSET_EPAPR_KERNEL.fetch()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ initrd_path = self.ASSET_INITRD.fetch()
self.vm.set_console()
self.vm.add_args('-kernel', kernel_path,
- '-append', 'console=tty0 console=hvc0',
+ '-drive',
+ f'file={initrd_path},format=raw,if=none,id=drive0,readonly=on',
+ '-append', 'root=/dev/nvme0n1 console=tty0 console=hvc0',
'-device', 'pcie-pci-bridge,id=bridge1,bus=pcie.1,addr=0x0',
- '-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234',
+ '-device', 'nvme,drive=drive0,bus=pcie.2,addr=0x0,serial=1234',
'-device', 'e1000e,bus=bridge1,addr=0x3',
'-device', 'nec-usb-xhci,bus=bridge1,addr=0x2')
self.vm.launch()
self.wait_for_console_pattern("CPU: " + proc + " generation processor")
- self.wait_for_console_pattern("zImage starting: loaded")
- self.wait_for_console_pattern("Run /init as init process")
+ self.wait_for_console_pattern("INIT: Starting kernel at ")
+ self.wait_for_console_pattern("Run /sbin/init as init process")
# Device detection output driven by udev probing is sometimes cut off
# from console output, suspect S14silence-console init script.
@@ -114,5 +116,9 @@ class powernvMachine(LinuxKernelTest):
self.set_machine('powernv10')
self.do_test_ppc64_powernv('P10')
+ def test_powernv11(self):
+ self.set_machine('powernv11')
+ self.do_test_ppc64_powernv('Power11')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/test_ppc64_pseries.py b/tests/functional/ppc64/test_pseries.py
index 6705793..6705793 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 e8c9c4b..e8c9c4b 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 5931ade..69551fb 100755
--- a/tests/functional/test_ppc64_reverse_debug.py
+++ b/tests/functional/ppc64/test_reverse_debug.py
@@ -2,39 +2,36 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
-# Reverse debugging test
+# Reverse debugging test for ppc64
#
# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
#
# Author:
# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
#
# 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 qemu_test import skipIfMissingImports, skipFlakyTest
+from qemu_test import skipFlakyTest
from reverse_debugging import ReverseDebugging
-@skipIfMissingImports('avocado.utils')
class ReverseDebugging_ppc64(ReverseDebugging):
- REG_PC = 0x40
-
@skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
def test_ppc64_pseries(self):
self.set_machine('pseries')
# SLOF branches back to its entry point, which causes this test
# to take the 'hit a breakpoint again' path. That's not a problem,
# just slightly different than the other machines.
- self.endian_is_le = False
- self.reverse_debugging()
+ self.reverse_debugging(gdb_arch='powerpc:common64')
@skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
def test_ppc64_powernv(self):
self.set_machine('powernv')
- self.endian_is_le = False
- self.reverse_debugging()
+ self.reverse_debugging(gdb_arch='powerpc:common64')
if __name__ == '__main__':
diff --git a/tests/functional/test_ppc64_tuxrun.py b/tests/functional/ppc64/test_tuxrun.py
index e8f79c6..e8f79c6 100755
--- a/tests/functional/test_ppc64_tuxrun.py
+++ b/tests/functional/ppc64/test_tuxrun.py
diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py
index af41c2c..3201935 100644
--- a/tests/functional/qemu_test/__init__.py
+++ b/tests/functional/qemu_test/__init__.py
@@ -15,6 +15,8 @@ from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
from .linuxkernel import LinuxKernelTest
from .decorators import skipIfMissingCommands, skipIfNotMachine, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \
- skipIfMissingImports, skipIfOperatingSystem
+ skipIfMissingImports, skipIfOperatingSystem, skipLockedMemoryTest, \
+ skipIfMissingEnv
from .archive import archive_extract
from .uncompress import uncompress
+from .gdb import GDB
diff --git a/tests/functional/qemu_test/asset.py b/tests/functional/qemu_test/asset.py
index 704b84d..f666125 100644
--- a/tests/functional/qemu_test/asset.py
+++ b/tests/functional/qemu_test/asset.py
@@ -15,7 +15,7 @@ import urllib.request
from time import sleep
from pathlib import Path
from shutil import copyfileobj
-from urllib.error import HTTPError
+from urllib.error import HTTPError, URLError
class AssetError(Exception):
def __init__(self, asset, msg, transient=False):
@@ -72,6 +72,10 @@ class Asset:
return self.hash == hl.hexdigest()
def valid(self):
+ if os.getenv("QEMU_TEST_REFRESH_CACHE", None) is not None:
+ self.log.info("Force refresh of asset %s", self.url)
+ return False
+
return self.cache_file.exists() and self._check(self.cache_file)
def fetchable(self):
@@ -167,9 +171,25 @@ class Asset:
raise AssetError(self, "Unable to download: "
"HTTP error %d" % e.code)
continue
+ except URLError as e:
+ # This is typically a network/service level error
+ # eg urlopen error [Errno 110] Connection timed out>
+ tmp_cache_file.unlink()
+ self.log.error("Unable to download %s: URL error %s",
+ self.url, e.reason)
+ raise AssetError(self, "Unable to download: URL error %s" %
+ e.reason, transient=True)
+ except ConnectionError as e:
+ # A socket connection failure, such as dropped conn
+ # or refused conn
+ tmp_cache_file.unlink()
+ self.log.error("Unable to download %s: Connection error %s",
+ self.url, e)
+ continue
except Exception as e:
tmp_cache_file.unlink()
- raise AssetError(self, "Unable to download: " % e)
+ raise AssetError(self, "Unable to download: %s" % e,
+ transient=True)
if not os.path.exists(tmp_cache_file):
raise AssetError(self, "Download retries exceeded", transient=True)
@@ -205,7 +225,6 @@ class Asset:
log.addHandler(handler)
for name, asset in vars(test.__class__).items():
if name.startswith("ASSET_") and type(asset) == Asset:
- log.info("Attempting to cache '%s'" % asset)
try:
asset.fetch()
except AssetError as e:
diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py
index dc5f422..f544566 100644
--- a/tests/functional/qemu_test/cmd.py
+++ b/tests/functional/qemu_test/cmd.py
@@ -45,13 +45,16 @@ def is_readable_executable_file(path):
# If end of line is seen, with neither @success or @failure
# return False
#
+# In both cases, also return the contents of the line (in bytes)
+# up to that point.
+#
# If @failure is seen, then mark @test as failed
def _console_read_line_until_match(test, vm, success, failure):
msg = bytes([])
done = False
while True:
c = vm.console_socket.recv(1)
- if c is None:
+ if not c:
done = True
test.fail(
f"EOF in console, expected '{success}'")
@@ -76,10 +79,23 @@ def _console_read_line_until_match(test, vm, success, failure):
except:
console_logger.debug(msg)
- return done
+ return done, msg
def _console_interaction(test, success_message, failure_message,
send_string, keep_sending=False, vm=None):
+ """
+ Interact with the console until either message is seen.
+
+ :param success_message: if this message appears, finish interaction
+ :param failure_message: if this message appears, test fails
+ :param send_string: a string to send to the console before trying
+ to read a new line
+ :param keep_sending: keep sending the send string each time
+ :param vm: the VM to interact with
+
+ :return: The collected output (in bytes form).
+ """
+
assert not keep_sending or send_string
assert success_message or send_string
@@ -101,6 +117,8 @@ def _console_interaction(test, success_message, failure_message,
if failure_message is not None:
failure_message_b = failure_message.encode()
+ out = bytes([])
+
while True:
if send_string:
vm.console_socket.sendall(send_string.encode())
@@ -113,14 +131,21 @@ def _console_interaction(test, success_message, failure_message,
break
continue
- if _console_read_line_until_match(test, vm,
- success_message_b,
- failure_message_b):
+ done, line = _console_read_line_until_match(test, vm,
+ success_message_b,
+ failure_message_b)
+
+ out += line
+
+ if done:
break
+ return out
+
def interrupt_interactive_console_until_pattern(test, success_message,
failure_message=None,
- interrupt_string='\r'):
+ interrupt_string='\r',
+ vm=None):
"""
Keep sending a string to interrupt a console prompt, while logging the
console output. Typical use case is to break a boot loader prompt, such:
@@ -140,10 +165,13 @@ def interrupt_interactive_console_until_pattern(test, success_message,
:param failure_message: if this message appears, test fails
:param interrupt_string: a string to send to the console before trying
to read a new line
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message,
- interrupt_string, True)
+ return _console_interaction(test, success_message, failure_message,
+ interrupt_string, True, vm=vm)
def wait_for_console_pattern(test, success_message, failure_message=None,
vm=None):
@@ -155,11 +183,15 @@ def wait_for_console_pattern(test, success_message, failure_message=None,
:type test: :class:`qemu_test.QemuSystemTest`
:param success_message: if this message appears, test succeeds
:param failure_message: if this message appears, test fails
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message, None, vm=vm)
+ return _console_interaction(test, success_message, failure_message,
+ None, vm=vm)
-def exec_command(test, command):
+def exec_command(test, command, vm=None):
"""
Send a command to a console (appending CRLF characters), while logging
the content.
@@ -167,12 +199,16 @@ def exec_command(test, command):
:param test: a test containing a VM.
:type test: :class:`qemu_test.QemuSystemTest`
:param command: the command to send
+ :param vm: VM to use
:type command: str
+
+ :return: The collected output (in bytes form).
"""
- _console_interaction(test, None, None, command + '\r')
+ return _console_interaction(test, None, None, command + '\r', vm=vm)
def exec_command_and_wait_for_pattern(test, command,
- success_message, failure_message=None):
+ success_message, failure_message=None,
+ vm=None):
"""
Send a command to a console (appending CRLF characters), then wait
for success_message to appear on the console, while logging the.
@@ -184,9 +220,14 @@ def exec_command_and_wait_for_pattern(test, command,
:param command: the command to send
:param success_message: if this message appears, test succeeds
:param failure_message: if this message appears, test fails
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message, command + '\r')
+
+ return _console_interaction(test, success_message, failure_message,
+ command + '\r', vm=vm)
def get_qemu_img(test):
test.log.debug('Looking for and selecting a qemu-img binary')
diff --git a/tests/functional/qemu_test/decorators.py b/tests/functional/qemu_test/decorators.py
index 50d29de..b239295 100644
--- a/tests/functional/qemu_test/decorators.py
+++ b/tests/functional/qemu_test/decorators.py
@@ -5,11 +5,30 @@
import importlib
import os
import platform
+import resource
from unittest import skipIf, skipUnless
from .cmd import which
'''
+Decorator to skip execution of a test if the provided
+environment variables are not set.
+Example:
+
+ @skipIfMissingEnv("QEMU_ENV_VAR0", "QEMU_ENV_VAR1")
+'''
+def skipIfMissingEnv(*vars_):
+ missing_vars = []
+ for var in vars_:
+ if os.getenv(var) == None:
+ missing_vars.append(var)
+
+ has_vars = True if len(missing_vars) == 0 else False
+
+ return skipUnless(has_vars, f"Missing env var(s): {', '.join(missing_vars)}")
+
+'''
+
Decorator to skip execution of a test if the list
of command binaries is not available in $PATH.
Example:
@@ -131,3 +150,20 @@ def skipIfMissingImports(*args):
return skipUnless(has_imports, 'required import(s) "%s" not installed' %
", ".join(args))
+
+'''
+Decorator to skip execution of a test if the system's
+locked memory limit is below the required threshold.
+Takes required locked memory threshold in kB.
+Example:
+
+ @skipLockedMemoryTest(2_097_152)
+'''
+def skipLockedMemoryTest(locked_memory):
+ # get memlock hard limit in bytes
+ _, ulimit_memory = resource.getrlimit(resource.RLIMIT_MEMLOCK)
+
+ return skipUnless(
+ ulimit_memory == resource.RLIM_INFINITY or ulimit_memory >= locked_memory * 1024,
+ f'Test required {locked_memory} kB of available locked memory',
+ )
diff --git a/tests/functional/qemu_test/gdb.py b/tests/functional/qemu_test/gdb.py
new file mode 100644
index 0000000..558d476
--- /dev/null
+++ b/tests/functional/qemu_test/gdb.py
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# A simple interface module built around pygdbmi for handling GDB commands.
+#
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Gustavo Romero <gustavo.romero@linaro.org>
+#
+
+import re
+
+
+class GDB:
+ """Provides methods to run and capture GDB command output."""
+
+
+ def __init__(self, gdb_path, echo=True, suffix='# ', prompt="$ "):
+ from pygdbmi.gdbcontroller import GdbController
+ from pygdbmi.constants import GdbTimeoutError
+ type(self).TimeoutError = GdbTimeoutError
+
+ gdb_cmd = [gdb_path, "-q", "--interpreter=mi2"]
+ self.gdbmi = GdbController(gdb_cmd)
+ self.echo = echo
+ self.suffix = suffix
+ self.prompt = prompt
+ self.response = None
+ self.cmd_output = None
+
+
+ def get_payload(self, response, kind):
+ output = []
+ for o in response:
+ # Unpack payloads of the same type.
+ _type, _, payload, *_ = o.values()
+ if _type == kind:
+ output += [payload]
+
+ # Some output lines do not end with \n but begin with it,
+ # so remove the leading \n and merge them with the next line
+ # that ends with \n.
+ lines = [line.lstrip('\n') for line in output]
+ lines = "".join(lines)
+ lines = lines.splitlines(keepends=True)
+
+ return lines
+
+
+ def cli(self, cmd, timeout=32.0):
+ self.response = self.gdbmi.write(cmd, timeout_sec=timeout)
+ self.cmd_output = self.get_payload(self.response, kind="console")
+ if self.echo:
+ print(self.suffix + self.prompt + cmd)
+
+ if len(self.cmd_output) > 0:
+ cmd_output = self.suffix.join(self.cmd_output)
+ print(self.suffix + cmd_output, end="")
+
+ return self
+
+
+ def get_addr(self):
+ address_pattern = r"0x[0-9A-Fa-f]+"
+ cmd_output = "".join(self.cmd_output) # Concat output lines.
+
+ match = re.search(address_pattern, cmd_output)
+
+ return int(match[0], 16) if match else None
+
+
+ def get_log(self):
+ r = self.get_payload(self.response, kind="log")
+ r = "".join(r)
+
+ return r
+
+
+ def get_console(self):
+ r = "".join(self.cmd_output)
+
+ return r
+
+
+ def exit(self):
+ self.gdbmi.exit()
diff --git a/tests/functional/qemu_test/ports.py b/tests/functional/qemu_test/ports.py
index 631b77a..81174a6 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 50c401b..2c0abde 100644
--- a/tests/functional/qemu_test/testcase.py
+++ b/tests/functional/qemu_test/testcase.py
@@ -19,11 +19,12 @@ import shutil
from subprocess import run
import sys
import tempfile
+import warnings
import unittest
import uuid
from qemu.machine import QEMUMachine
-from qemu.utils import kvm_available, tcg_available
+from qemu.utils import hvf_available, kvm_available, tcg_available
from .archive import archive_extract
from .asset import Asset
@@ -204,6 +205,10 @@ class QemuBaseTest(unittest.TestCase):
self.outputdir = self.build_file('tests', 'functional',
self.arch, self.id())
self.workdir = os.path.join(self.outputdir, 'scratch')
+ if os.path.exists(self.workdir):
+ # Purge as safety net in case of unclean termination of
+ # previous test, or use of QEMU_TEST_KEEP_SCRATCH
+ shutil.rmtree(self.workdir)
os.makedirs(self.workdir, exist_ok=True)
self.log_filename = self.log_file('base.log')
@@ -232,8 +237,13 @@ class QemuBaseTest(unittest.TestCase):
self.socketdir = None
self.machinelog.removeHandler(self._log_fh)
self.log.removeHandler(self._log_fh)
+ self._log_fh.close()
+ @staticmethod
def main():
+ warnings.simplefilter("default")
+ os.environ["PYTHONWARNINGS"] = "default"
+
path = os.path.basename(sys.argv[0])[:-3]
cache = os.environ.get("QEMU_TEST_PRECACHE", None)
@@ -244,14 +254,15 @@ class QemuBaseTest(unittest.TestCase):
tr = pycotap.TAPTestRunner(message_log = pycotap.LogMode.LogToError,
test_output_log = pycotap.LogMode.LogToError)
res = unittest.main(module = None, testRunner = tr, exit = False,
- argv=["__dummy__", path])
+ argv=[sys.argv[0], path] + sys.argv[1:])
+ failed = {}
for (test, message) in res.result.errors + res.result.failures:
-
- if hasattr(test, "log_filename"):
+ if hasattr(test, "log_filename") and not test.id() in failed:
print('More information on ' + test.id() + ' could be found here:'
'\n %s' % test.log_filename, file=sys.stderr)
if hasattr(test, 'console_log_name'):
print(' %s' % test.console_log_name, file=sys.stderr)
+ failed[test.id()] = True
sys.exit(not res.result.wasSuccessful())
@@ -317,7 +328,9 @@ class QemuSystemTest(QemuBaseTest):
:type accelerator: str
"""
checker = {'tcg': tcg_available,
- 'kvm': kvm_available}.get(accelerator)
+ 'kvm': kvm_available,
+ 'hvf': hvf_available,
+ }.get(accelerator)
if checker is None:
self.skipTest("Don't know how to check for the presence "
"of accelerator %s" % accelerator)
@@ -395,6 +408,10 @@ class QemuSystemTest(QemuBaseTest):
def tearDown(self):
for vm in self._vms.values():
- vm.shutdown()
+ try:
+ vm.shutdown()
+ except Exception as ex:
+ self.log.error("Failed to teardown VM: %s" % ex)
logging.getLogger('console').removeHandler(self._console_log_fh)
+ self._console_log_fh.close()
super().tearDown()
diff --git a/tests/functional/replay_kernel.py b/tests/functional/replay_kernel.py
index 80795eb..acb1d29 100644
--- a/tests/functional/replay_kernel.py
+++ b/tests/functional/replay_kernel.py
@@ -32,15 +32,14 @@ class ReplayKernelBase(LinuxKernelTest):
# icount requires TCG to be available
self.require_accelerator('tcg')
- logger = logging.getLogger('replay')
start_time = time.time()
vm = self.get_vm(name='recording' if record else 'replay')
vm.set_console()
if record:
- logger.info('recording the execution...')
+ self.log.info('recording the execution...')
mode = 'record'
else:
- logger.info('replaying the execution...')
+ self.log.info('replaying the execution...')
mode = 'replay'
vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
(shift, mode, replay_path),
@@ -54,15 +53,15 @@ class ReplayKernelBase(LinuxKernelTest):
self.wait_for_console_pattern(console_pattern, vm)
if record:
vm.shutdown()
- logger.info('finished the recording with log size %s bytes'
+ self.log.info('finished the recording with log size %s bytes'
% os.path.getsize(replay_path))
self.run_replay_dump(replay_path)
- logger.info('successfully tested replay-dump.py')
+ self.log.info('successfully tested replay-dump.py')
else:
vm.wait()
- logger.info('successfully finished the replay')
+ self.log.info('successfully finished the replay')
elapsed = time.time() - start_time
- logger.info('elapsed time %.2f sec' % elapsed)
+ self.log.info('elapsed time %.2f sec' % elapsed)
return elapsed
def run_replay_dump(self, replay_path):
@@ -80,5 +79,4 @@ class ReplayKernelBase(LinuxKernelTest):
True, shift, args, replay_path)
t2 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
False, shift, args, replay_path)
- logger = logging.getLogger('replay')
- logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
+ self.log.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
diff --git a/tests/functional/reverse_debugging.py b/tests/functional/reverse_debugging.py
index f9a1d39..68cfcb3 100644
--- a/tests/functional/reverse_debugging.py
+++ b/tests/functional/reverse_debugging.py
@@ -1,18 +1,23 @@
-# Reverse debugging test
-#
# SPDX-License-Identifier: GPL-2.0-or-later
#
+# Reverse debugging test
+#
# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
#
# Author:
# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
#
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-import os
+
import logging
+import os
+from subprocess import check_output
-from qemu_test import LinuxKernelTest, get_qemu_img
+from qemu_test import LinuxKernelTest, get_qemu_img, GDB, \
+ skipIfMissingEnv, skipIfMissingImports
from qemu_test.ports import Ports
@@ -28,13 +33,9 @@ class ReverseDebugging(LinuxKernelTest):
that the execution is stopped at the last of them.
"""
- timeout = 10
STEPS = 10
- endian_is_le = True
def run_vm(self, record, shift, args, replay_path, image_path, port):
- from avocado.utils import datadrainer
-
logger = logging.getLogger('replay')
vm = self.get_vm(name='record' if record else 'replay')
vm.set_console()
@@ -52,55 +53,20 @@ class ReverseDebugging(LinuxKernelTest):
if args:
vm.add_args(*args)
vm.launch()
- console_drainer = datadrainer.LineLogger(vm.console_socket.fileno(),
- logger=self.log.getChild('console'),
- stop_check=(lambda : not vm.is_running()))
- console_drainer.start()
return vm
@staticmethod
- def get_reg_le(g, reg):
- res = g.cmd(b'p%x' % reg)
- num = 0
- for i in range(len(res))[-2::-2]:
- num = 0x100 * num + int(res[i:i + 2], 16)
- return num
-
- @staticmethod
- def get_reg_be(g, reg):
- res = g.cmd(b'p%x' % reg)
- return int(res, 16)
-
- def get_reg(self, g, reg):
- # value may be encoded in BE or LE order
- if self.endian_is_le:
- return self.get_reg_le(g, reg)
- else:
- return self.get_reg_be(g, reg)
-
- def get_pc(self, g):
- return self.get_reg(g, self.REG_PC)
-
- def check_pc(self, g, addr):
- pc = self.get_pc(g)
- if pc != addr:
- self.fail('Invalid PC (read %x instead of %x)' % (pc, addr))
-
- @staticmethod
- def gdb_step(g):
- g.cmd(b's', b'T05thread:01;')
-
- @staticmethod
- def gdb_bstep(g):
- g.cmd(b'bs', b'T05thread:01;')
+ def get_pc(gdb: GDB):
+ return gdb.cli("print $pc").get_addr()
@staticmethod
def vm_get_icount(vm):
return vm.qmp('query-replay')['return']['icount']
- def reverse_debugging(self, shift=7, args=None):
- from avocado.utils import gdb
- from avocado.utils import process
+ @skipIfMissingImports("pygdbmi") # Required by GDB class
+ @skipIfMissingEnv("QEMU_TEST_GDB")
+ def reverse_debugging(self, gdb_arch, shift=7, args=None):
+ from qemu_test import GDB
logger = logging.getLogger('replay')
@@ -111,8 +77,9 @@ class ReverseDebugging(LinuxKernelTest):
if qemu_img is None:
self.skipTest('Could not find "qemu-img", which is required to '
'create the temporary qcow2 image')
- cmd = '%s create -f qcow2 %s 128M' % (qemu_img, image_path)
- process.run(cmd)
+ out = check_output([qemu_img, 'create', '-f', 'qcow2', image_path, '128M'],
+ encoding='utf8')
+ logger.info("qemu-img: %s" % out)
replay_path = os.path.join(self.workdir, 'replay.bin')
@@ -129,68 +96,107 @@ class ReverseDebugging(LinuxKernelTest):
with Ports() as ports:
port = ports.find_free_port()
vm = self.run_vm(False, shift, args, replay_path, image_path, port)
- logger.info('connecting to gdbstub')
- g = gdb.GDBRemote('127.0.0.1', port, False, False)
- g.connect()
- r = g.cmd(b'qSupported')
- if b'qXfer:features:read+' in r:
- g.cmd(b'qXfer:features:read:target.xml:0,ffb')
- if b'ReverseStep+' not in r:
+
+ try:
+ logger.info('Connecting to gdbstub...')
+ self.reverse_debugging_run(vm, port, gdb_arch, last_icount)
+ logger.info('Test passed.')
+ except GDB.TimeoutError:
+ # Convert a GDB timeout exception into a unittest failure exception.
+ raise self.failureException("Timeout while connecting to or "
+ "communicating with gdbstub...") from None
+ except Exception:
+ # Re-throw exceptions from unittest, like the ones caused by fail(),
+ # skipTest(), etc.
+ raise
+
+ def reverse_debugging_run(self, vm, port, gdb_arch, last_icount):
+ logger = logging.getLogger('replay')
+
+ gdb_cmd = os.getenv('QEMU_TEST_GDB')
+ gdb = GDB(gdb_cmd)
+
+ r = gdb.cli("set architecture").get_log()
+ if gdb_arch not in r:
+ self.skipTest(f"GDB does not support arch '{gdb_arch}'")
+
+ gdb.cli("set debug remote 1")
+
+ c = gdb.cli(f"target remote localhost:{port}").get_console()
+ if not f"Remote debugging using localhost:{port}" in c:
+ self.fail("Could not connect to gdbstub!")
+
+ # Remote debug messages are in 'log' payloads.
+ r = gdb.get_log()
+ if 'ReverseStep+' not in r:
self.fail('Reverse step is not supported by QEMU')
- if b'ReverseContinue+' not in r:
+ if 'ReverseContinue+' not in r:
self.fail('Reverse continue is not supported by QEMU')
+ gdb.cli("set debug remote 0")
+
logger.info('stepping forward')
steps = []
# record first instruction addresses
for _ in range(self.STEPS):
- pc = self.get_pc(g)
+ pc = self.get_pc(gdb)
logger.info('saving position %x' % pc)
steps.append(pc)
- self.gdb_step(g)
+ gdb.cli("stepi")
# visit the recorded instruction in reverse order
logger.info('stepping backward')
for addr in steps[::-1]:
- self.gdb_bstep(g)
- self.check_pc(g, addr)
logger.info('found position %x' % addr)
+ gdb.cli("reverse-stepi")
+ pc = self.get_pc(gdb)
+ if pc != addr:
+ logger.info('Invalid PC (read %x instead of %x)' % (pc, addr))
+ self.fail('Reverse stepping failed!')
# visit the recorded instruction in forward order
logger.info('stepping forward')
for addr in steps:
- self.check_pc(g, addr)
- self.gdb_step(g)
logger.info('found position %x' % addr)
+ pc = self.get_pc(gdb)
+ if pc != addr:
+ logger.info('Invalid PC (read %x instead of %x)' % (pc, addr))
+ self.fail('Forward stepping failed!')
+ gdb.cli("stepi")
# set breakpoints for the instructions just stepped over
logger.info('setting breakpoints')
for addr in steps:
- # hardware breakpoint at addr with len=1
- g.cmd(b'Z1,%x,1' % addr, b'OK')
+ gdb.cli(f"break *{hex(addr)}")
# this may hit a breakpoint if first instructions are executed
# again
logger.info('continuing execution')
vm.qmp('replay-break', icount=last_icount - 1)
# continue - will return after pausing
- # This could stop at the end and get a T02 return, or by
- # re-executing one of the breakpoints and get a T05 return.
- g.cmd(b'c')
+ # This can stop at the end of the replay-break and gdb gets a SIGINT,
+ # or by re-executing one of the breakpoints and gdb stops at a
+ # breakpoint.
+ gdb.cli("continue")
+
if self.vm_get_icount(vm) == last_icount - 1:
logger.info('reached the end (icount %s)' % (last_icount - 1))
else:
logger.info('hit a breakpoint again at %x (icount %s)' %
- (self.get_pc(g), self.vm_get_icount(vm)))
+ (self.get_pc(gdb), self.vm_get_icount(vm)))
logger.info('running reverse continue to reach %x' % steps[-1])
# reverse continue - will return after stopping at the breakpoint
- g.cmd(b'bc', b'T05thread:01;')
+ gdb.cli("reverse-continue")
# assume that none of the first instructions is executed again
# breaking the order of the breakpoints
- self.check_pc(g, steps[-1])
+ pc = self.get_pc(gdb)
+ if pc != steps[-1]:
+ self.fail("'reverse-continue' did not hit the first PC in reverse order!")
+
logger.info('successfully reached %x' % steps[-1])
logger.info('exiting gdb and qemu')
+ gdb.exit()
vm.shutdown()
diff --git a/tests/functional/riscv32/meson.build b/tests/functional/riscv32/meson.build
new file mode 100644
index 0000000..f3ebbb8
--- /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 0000000..30acbbe
--- /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 0000000..d1ac706
--- /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 3c57020..3c57020 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 0000000..c1704d9
--- /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 0000000..2d613a2
--- /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 d077e40..d077e40 100755
--- a/tests/functional/test_riscv_opensbi.py
+++ b/tests/functional/riscv64/test_opensbi.py
diff --git a/tests/functional/riscv64/test_sifive_u.py b/tests/functional/riscv64/test_sifive_u.py
new file mode 100755
index 0000000..358ff0d
--- /dev/null
+++ b/tests/functional/riscv64/test_sifive_u.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel on a Sifive U machine
+# and checks the console
+#
+# Copyright (c) Linaro Ltd.
+#
+# Author:
+# Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu_test import Asset, LinuxKernelTest
+from qemu_test import skipIfMissingCommands
+
+
+class SifiveU(LinuxKernelTest):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/riscv64/Image',
+ '2bd8132a3bf21570290042324fff48c987f42f2a00c08de979f43f0662ebadba')
+ ASSET_ROOTFS = Asset(
+ ('https://github.com/groeck/linux-build-test/raw/'
+ '9819da19e6eef291686fdd7b029ea00e764dc62f/rootfs/riscv64/'
+ 'rootfs.ext2.gz'),
+ 'b6ed95610310b7956f9bf20c4c9c0c05fea647900df441da9dfe767d24e8b28b')
+
+ def do_test_riscv64_sifive_u_mmc_spi(self, connect_card):
+ self.set_machine('sifive_u')
+ kernel_path = self.ASSET_KERNEL.fetch()
+ rootfs_path = self.uncompress(self.ASSET_ROOTFS)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'earlycon=sbi console=ttySIF0 '
+ 'root=/dev/mmcblk0 ')
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line,
+ '-no-reboot')
+ if connect_card:
+ kernel_command_line += 'panic=-1 noreboot rootwait '
+ self.vm.add_args('-drive', f'file={rootfs_path},if=sd,format=raw')
+ pattern = 'Boot successful.'
+ else:
+ kernel_command_line += 'panic=0 noreboot '
+ pattern = 'Cannot open root device "mmcblk0" or unknown-block(0,0)'
+
+ self.vm.launch()
+ self.wait_for_console_pattern(pattern)
+
+ os.remove(rootfs_path)
+
+ def test_riscv64_sifive_u_nommc_spi(self):
+ self.do_test_riscv64_sifive_u_mmc_spi(False)
+
+ def test_riscv64_sifive_u_mmc_spi(self):
+ self.do_test_riscv64_sifive_u_mmc_spi(True)
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_riscv64_tuxrun.py b/tests/functional/riscv64/test_tuxrun.py
index 0d8de36..0d8de36 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 0000000..6af83a9
--- /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 4924579..4924579 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 0000000..70cd36e
--- /dev/null
+++ b/tests/functional/s390x/meson.build
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_s390x_timeouts = {
+ 'ccw_virtio' : 420,
+}
+
+tests_s390x_system_quick = [
+ 'vmstate',
+]
+
+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 453711a..453711a 100755
--- a/tests/functional/test_s390x_ccw_virtio.py
+++ b/tests/functional/s390x/test_ccw_virtio.py
diff --git a/tests/functional/s390x/test_pxelinux.py b/tests/functional/s390x/test_pxelinux.py
new file mode 100755
index 0000000..c00cce6
--- /dev/null
+++ b/tests/functional/s390x/test_pxelinux.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+'''
+Functional test that checks the pxelinux.cfg network booting of a s390x VM
+(TFTP booting without config file is already tested by the pxe qtest, so
+we don't repeat that here).
+'''
+
+import os
+import shutil
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+
+
+PXELINUX_CFG_CONTENTS='''# pxelinux.cfg style config file
+default Debian
+label Nonexisting
+kernel kernel.notavailable
+initrd initrd.notavailable
+label Debian
+kernel kernel.debian
+initrd initrd.debian
+append testoption=teststring
+label Fedora
+kernel kernel.fedora
+'''
+
+class S390PxeLinux(QemuSystemTest):
+ '''
+ Test various ways of booting via a pxelinux.cfg file, for details see:
+ https://wiki.syslinux.org/wiki/index.php?title=PXELINUX#Configuration
+ '''
+
+ ASSET_DEBIAN_KERNEL = Asset(
+ ('https://snapshot.debian.org/archive/debian/'
+ '20201126T092837Z/dists/buster/main/installer-s390x/'
+ '20190702+deb10u6/images/generic/kernel.debian'),
+ 'd411d17c39ae7ad38d27534376cbe88b68b403c325739364122c2e6f1537e818')
+
+ ASSET_DEBIAN_INITRD = Asset(
+ ('https://snapshot.debian.org/archive/debian/'
+ '20201126T092837Z/dists/buster/main/installer-s390x/'
+ '20190702+deb10u6/images/generic/initrd.debian'),
+ '836bbd0fe6a5ca81274c28c2b063ea315ce1868660866e9b60180c575fef9fd5')
+
+ ASSET_FEDORA_KERNEL = Asset(
+ ('https://archives.fedoraproject.org/pub/archive'
+ '/fedora-secondary/releases/31/Server/s390x/os'
+ '/images/kernel.img'),
+ '480859574f3f44caa6cd35c62d70e1ac0609134e22ce2a954bbed9b110c06e0b')
+
+ def pxelinux_launch(self, pl_name='default', extra_opts=None):
+ '''Create a pxelinux.cfg file in the right location and launch QEMU'''
+ self.require_netdev('user')
+ self.set_machine('s390-ccw-virtio')
+
+ debian_kernel = self.ASSET_DEBIAN_KERNEL.fetch()
+ debian_initrd = self.ASSET_DEBIAN_INITRD.fetch()
+ fedora_kernel = self.ASSET_FEDORA_KERNEL.fetch()
+
+ # Prepare a folder for the TFTP "server":
+ tftpdir = self.scratch_file('tftp')
+ shutil.rmtree(tftpdir, ignore_errors=True) # Remove stale stuff
+ os.mkdir(tftpdir)
+ shutil.copy(debian_kernel, os.path.join(tftpdir, 'kernel.debian'))
+ shutil.copy(debian_initrd, os.path.join(tftpdir, 'initrd.debian'))
+ shutil.copy(fedora_kernel, os.path.join(tftpdir, 'kernel.fedora'))
+
+ pxelinuxdir = self.scratch_file('tftp', 'pxelinux.cfg')
+ os.mkdir(pxelinuxdir)
+
+ cfg_fname = self.scratch_file('tftp', 'pxelinux.cfg', pl_name)
+ with open(cfg_fname, 'w', encoding='utf-8') as f:
+ f.write(PXELINUX_CFG_CONTENTS)
+
+ virtio_net_dev = 'virtio-net-ccw,netdev=n1,bootindex=1'
+ if extra_opts:
+ virtio_net_dev += ',' + extra_opts
+
+ self.vm.add_args('-m', '384',
+ '-netdev', f'user,id=n1,tftp={tftpdir}',
+ '-device', virtio_net_dev)
+ self.vm.set_console()
+ self.vm.launch()
+
+
+ def test_default(self):
+ '''Check whether the guest uses the "default" file name'''
+ self.pxelinux_launch()
+ # The kernel prints its arguments to the console, so we can use
+ # this to check whether the kernel parameters are correctly handled:
+ wait_for_console_pattern(self, 'testoption=teststring')
+ # Now also check that we've successfully loaded the initrd:
+ wait_for_console_pattern(self, 'Unpacking initramfs...')
+ wait_for_console_pattern(self, 'Run /init as init process')
+
+ def test_mac(self):
+ '''Check whether the guest uses file name based on its MAC address'''
+ self.pxelinux_launch(pl_name='01-02-ca-fe-ba-be-42',
+ extra_opts='mac=02:ca:fe:ba:be:42,loadparm=3')
+ wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x')
+
+ def test_uuid(self):
+ '''Check whether the guest uses file name based on its UUID'''
+ # Also add a non-bootable disk to check the fallback to network boot:
+ self.vm.add_args('-blockdev', 'null-co,size=65536,node-name=d1',
+ '-device', 'virtio-blk,drive=d1,bootindex=0,loadparm=1',
+ '-uuid', '550e8400-e29b-11d4-a716-446655441234')
+ self.pxelinux_launch(pl_name='550e8400-e29b-11d4-a716-446655441234')
+ wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)')
+
+ def test_ip(self):
+ '''Check whether the guest uses file name based on its IP address'''
+ self.vm.add_args('-M', 'loadparm=3')
+ self.pxelinux_launch(pl_name='0A00020F')
+ wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x')
+
+ def test_menu(self):
+ '''Check whether the boot menu works for pxelinux.cfg booting'''
+ self.vm.add_args('-boot', 'menu=on,splash-time=10')
+ self.pxelinux_launch(pl_name='0A00')
+ wait_for_console_pattern(self, '[1] Nonexisting')
+ wait_for_console_pattern(self, '[2] Debian')
+ wait_for_console_pattern(self, '[3] Fedora')
+ wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_s390x_replay.py b/tests/functional/s390x/test_replay.py
index 33b5843..33b5843 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 1b5dc65..1b5dc65 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 8df3c68..8df3c68 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 0000000..56f824e
--- /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 03a64837..03a64837 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 1748f8c..1748f8c 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 0000000..25e9a6e
--- /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 473093b..473093b 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 0000000..88732be
--- /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 0000000..dd6d578
--- /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 865d648..865d648 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 7cd28eb..7cd28eb 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 0000000..2e04e7d
--- /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 0000000..a8a6c73
--- /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 27ac289..27ac289 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 3be08d6..0d7b43d 100755
--- a/tests/functional/test_sparc64_tuxrun.py
+++ b/tests/functional/sparc64/test_tuxrun.py
@@ -24,6 +24,7 @@ class TuxRunSparc64Test(TuxRunBaselineTest):
'479c3dc104c82b68be55e2c0c5c38cd473d0b37ad4badccde4775bb88ce34611')
def test_sparc64(self):
+ self.set_machine('sun4u')
self.root='sda'
self.wait_for_shutdown=False
self.common_tuxrun(kernel_asset=self.ASSET_SPARC64_KERNEL,
diff --git a/tests/functional/test_aarch64_rme_sbsaref.py b/tests/functional/test_aarch64_rme_sbsaref.py
deleted file mode 100755
index 746770e..0000000
--- a/tests/functional/test_aarch64_rme_sbsaref.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python3
-#
-# Functional test that boots a Realms environment on sbsa-ref machine and a
-# nested guest VM using it.
-#
-# Copyright (c) 2024 Linaro Ltd.
-#
-# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-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
-
-
-class Aarch64RMESbsaRefMachine(QemuSystemTest):
-
- # Stack is built with OP-TEE build environment from those instructions:
- # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
- # https://github.com/pbo-linaro/qemu-rme-stack
- ASSET_RME_STACK_SBSA = Asset(
- ('https://fileserver.linaro.org/s/KJyeBxL82mz2r7F/'
- 'download/rme-stack-op-tee-4.2.0-cca-v4-sbsa.tar.gz'),
- 'dd9ab28ec869bdf3b5376116cb3689103b43433fd5c4bca0f4a8d8b3c104999e')
-
- # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
- # and launching a nested VM using it.
- def test_aarch64_rme_sbsaref(self):
- self.set_machine('sbsa-ref')
- self.require_accelerator('tcg')
- self.require_netdev('user')
-
- self.vm.set_console()
-
- stack_path_tar_gz = self.ASSET_RME_STACK_SBSA.fetch()
- self.archive_extract(stack_path_tar_gz, format="tar")
-
- rme_stack = self.scratch_file('rme-stack-op-tee-4.2.0-cca-v4-sbsa')
- pflash0 = os.path.join(rme_stack, 'images', 'SBSA_FLASH0.fd')
- pflash1 = os.path.join(rme_stack, 'images', 'SBSA_FLASH1.fd')
- virtual = os.path.join(rme_stack, 'images', 'disks', 'virtual')
- drive = os.path.join(rme_stack, 'out-br', 'images', 'rootfs.ext4')
-
- self.vm.add_args('-cpu', 'max,x-rme=on,pauth-impdef=on')
- self.vm.add_args('-m', '2G')
- self.vm.add_args('-M', 'sbsa-ref')
- self.vm.add_args('-drive', f'file={pflash0},format=raw,if=pflash')
- self.vm.add_args('-drive', f'file={pflash1},format=raw,if=pflash')
- self.vm.add_args('-drive', f'file=fat:rw:{virtual},format=raw')
- self.vm.add_args('-drive', f'format=raw,if=none,file={drive},id=hd0')
- self.vm.add_args('-device', 'virtio-blk-pci,drive=hd0')
- self.vm.add_args('-device', 'virtio-9p-pci,fsdev=shr0,mount_tag=shr0')
- self.vm.add_args('-fsdev', f'local,security_model=none,path={rme_stack},id=shr0')
- self.vm.add_args('-device', 'virtio-net-pci,netdev=net0')
- self.vm.add_args('-netdev', 'user,id=net0')
-
- self.vm.launch()
- # Wait for host VM boot to complete.
- wait_for_console_pattern(self, 'Welcome to Buildroot',
- failure_message='Synchronous Exception at')
- exec_command_and_wait_for_pattern(self, 'root', '#')
-
- test_realms_guest(self)
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/test_aarch64_rme_virt.py
deleted file mode 100755
index 8452d27..0000000
--- a/tests/functional/test_aarch64_rme_virt.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python3
-#
-# Functional test that boots a Realms environment on virt machine and a nested
-# guest VM using it.
-#
-# Copyright (c) 2024 Linaro Ltd.
-#
-# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-import os
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, wait_for_console_pattern
-from qemu_test import exec_command_and_wait_for_pattern
-
-def test_realms_guest(test_rme_instance):
-
- # Boot the (nested) guest VM
- exec_command(test_rme_instance,
- 'qemu-system-aarch64 -M virt,gic-version=3 '
- '-cpu host -enable-kvm -m 512M '
- '-M confidential-guest-support=rme0 '
- '-object rme-guest,id=rme0 '
- '-device virtio-net-pci,netdev=net0,romfile= '
- '-netdev user,id=net0 '
- '-kernel /mnt/out/bin/Image '
- '-initrd /mnt/out-br/images/rootfs.cpio '
- '-serial stdio')
- # Detect Realm activation during (nested) guest boot.
- wait_for_console_pattern(test_rme_instance,
- 'SMC_RMI_REALM_ACTIVATE')
- # Wait for (nested) guest boot to complete.
- wait_for_console_pattern(test_rme_instance,
- 'Welcome to Buildroot')
- exec_command_and_wait_for_pattern(test_rme_instance, 'root', '#')
- # query (nested) guest cca report
- exec_command(test_rme_instance, 'cca-workload-attestation report')
- wait_for_console_pattern(test_rme_instance,
- '"cca-platform-hash-algo-id": "sha-256"')
- wait_for_console_pattern(test_rme_instance,
- '"cca-realm-hash-algo-id": "sha-512"')
- wait_for_console_pattern(test_rme_instance,
- '"cca-realm-public-key-hash-algo-id": "sha-256"')
-
-class Aarch64RMEVirtMachine(QemuSystemTest):
-
- # Stack is built with OP-TEE build environment from those instructions:
- # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
- # https://github.com/pbo-linaro/qemu-rme-stack
- ASSET_RME_STACK_VIRT = Asset(
- ('https://fileserver.linaro.org/s/iaRsNDJp2CXHMSJ/'
- 'download/rme-stack-op-tee-4.2.0-cca-v4-qemu_v8.tar.gz'),
- '1851adc232b094384d8b879b9a2cfff07ef3d6205032b85e9b3a4a9ae6b0b7ad')
-
- # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
- # and launching a nested VM using it.
- def test_aarch64_rme_virt(self):
- self.set_machine('virt')
- self.require_accelerator('tcg')
- self.require_netdev('user')
-
- self.vm.set_console()
-
- stack_path_tar_gz = self.ASSET_RME_STACK_VIRT.fetch()
- self.archive_extract(stack_path_tar_gz, format="tar")
-
- rme_stack = self.scratch_file('rme-stack-op-tee-4.2.0-cca-v4-qemu_v8')
- kernel = os.path.join(rme_stack, 'out', 'bin', 'Image')
- bios = os.path.join(rme_stack, 'out', 'bin', 'flash.bin')
- drive = os.path.join(rme_stack, 'out-br', 'images', 'rootfs.ext4')
-
- self.vm.add_args('-cpu', 'max,x-rme=on,pauth-impdef=on')
- self.vm.add_args('-m', '2G')
- self.vm.add_args('-M', 'virt,acpi=off,'
- 'virtualization=on,'
- 'secure=on,'
- 'gic-version=3')
- self.vm.add_args('-bios', bios)
- self.vm.add_args('-kernel', kernel)
- self.vm.add_args('-drive', f'format=raw,if=none,file={drive},id=hd0')
- self.vm.add_args('-device', 'virtio-blk-pci,drive=hd0')
- self.vm.add_args('-device', 'virtio-9p-device,fsdev=shr0,mount_tag=shr0')
- self.vm.add_args('-fsdev', f'local,security_model=none,path={rme_stack},id=shr0')
- self.vm.add_args('-device', 'virtio-net-pci,netdev=net0')
- self.vm.add_args('-netdev', 'user,id=net0')
- # We need to add nokaslr to avoid triggering this sporadic bug:
- # https://gitlab.com/qemu-project/qemu/-/issues/2823
- self.vm.add_args('-append', 'root=/dev/vda nokaslr')
-
- self.vm.launch()
- # Wait for host VM boot to complete.
- wait_for_console_pattern(self, 'Welcome to Buildroot',
- failure_message='Synchronous Exception at')
- exec_command_and_wait_for_pattern(self, 'root', '#')
-
- test_realms_guest(self)
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/test_ppc_bamboo.py b/tests/functional/test_ppc_bamboo.py
deleted file mode 100755
index fddcc24..0000000
--- a/tests/functional/test_ppc_bamboo.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python3
-#
-# Test that Linux kernel boots on the ppc bamboo board and check the console
-#
-# Copyright (c) 2021 Red Hat
-#
-# 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 qemu_test import QemuSystemTest, Asset
-from qemu_test import wait_for_console_pattern
-from qemu_test import exec_command_and_wait_for_pattern
-
-
-class BambooMachine(QemuSystemTest):
-
- timeout = 90
-
- ASSET_IMAGE = Asset(
- ('http://landley.net/aboriginal/downloads/binaries/'
- 'system-image-powerpc-440fp.tar.gz'),
- 'c12b58f841c775a0e6df4832a55afe6b74814d1565d08ddeafc1fb949a075c5e')
-
- def test_ppc_bamboo(self):
- self.set_machine('bamboo')
- self.require_accelerator("tcg")
- self.require_netdev('user')
- self.archive_extract(self.ASSET_IMAGE)
- self.vm.set_console()
- self.vm.add_args('-kernel',
- self.scratch_file('system-image-powerpc-440fp',
- 'linux'),
- '-initrd',
- self.scratch_file('system-image-powerpc-440fp',
- 'rootfs.cpio.gz'),
- '-nic', 'user,model=rtl8139,restrict=on')
- self.vm.launch()
- wait_for_console_pattern(self, 'Type exit when done')
- exec_command_and_wait_for_pattern(self, 'ping 10.0.2.2',
- '10.0.2.2 is alive!')
- exec_command_and_wait_for_pattern(self, 'halt', 'System Halted')
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
new file mode 100644
index 0000000..f78eec5
--- /dev/null
+++ b/tests/functional/x86_64/meson.build
@@ -0,0 +1,39 @@
+# 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 = [
+ 'bad_vmstate',
+ 'cpu_model_versions',
+ 'cpu_queries',
+ 'mem_addr_space',
+ 'memlock',
+ 'migration',
+ 'pc_cpu_hotplug_props',
+ 'virtio_version',
+ 'vmstate',
+]
+
+tests_x86_64_system_thorough = [
+ 'acpi_bits',
+ 'hotplug_blk',
+ 'hotplug_cpu',
+ 'intel_iommu',
+ 'kvm_xen',
+ 'linux_initrd',
+ 'multiprocess',
+ 'netdev_ethtool',
+ 'replay',
+ 'reverse_debug',
+ 'tuxrun',
+ 'vfio_user_client',
+ 'virtio_balloon',
+ 'virtio_gpu',
+]
diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/x86_64/test_acpi_bits.py
index 8e0563a..9a28165 100755
--- a/tests/functional/test_acpi_bits.py
+++ b/tests/functional/x86_64/test_acpi_bits.py
@@ -121,10 +121,10 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self._debugcon_log = 'debugcon-log.txt'
def _print_log(self, log):
- self.logger.info('\nlogs from biosbits follows:')
- self.logger.info('==========================================\n')
- self.logger.info(log)
- self.logger.info('==========================================\n')
+ self.log.info('\nlogs from biosbits follows:')
+ self.log.info('==========================================\n')
+ self.log.info(log)
+ self.log.info('==========================================\n')
def copy_bits_config(self):
""" copies the bios bits config file into bits.
@@ -138,8 +138,8 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.assertTrue(os.path.exists(bits_config_file))
self.assertTrue(os.path.exists(target_config_dir))
shutil.copy2(bits_config_file, target_config_dir)
- self.logger.info('copied config file %s to %s',
- bits_config_file, target_config_dir)
+ self.log.info('copied config file %s to %s',
+ bits_config_file, target_config_dir)
def copy_test_scripts(self):
"""copies the python test scripts into bits. """
@@ -163,8 +163,8 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
newfilename = os.path.splitext(filename)[0] + '.py'
shutil.copy2(os.path.join(bits_test_dir, filename),
os.path.join(target_test_dir, newfilename))
- self.logger.info('copied test file %s to %s',
- filename, target_test_dir)
+ self.log.info('copied test file %s to %s',
+ filename, target_test_dir)
# now remove the pyc test file if it exists, otherwise the
# changes in the python test script won't be executed.
@@ -172,9 +172,9 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
if os.access(os.path.join(target_test_dir, testfile_pyc),
os.F_OK):
os.remove(os.path.join(target_test_dir, testfile_pyc))
- self.logger.info('removed compiled file %s',
- os.path.join(target_test_dir,
- testfile_pyc))
+ self.log.info('removed compiled file %s',
+ os.path.join(target_test_dir,
+ testfile_pyc))
def fix_mkrescue(self, mkrescue):
""" grub-mkrescue is a bash script with two variables, 'prefix' and
@@ -216,7 +216,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.fix_mkrescue(mkrescue_script)
- self.logger.info('using grub-mkrescue for generating biosbits iso ...')
+ self.log.info('using grub-mkrescue for generating biosbits iso ...')
try:
if os.getenv('V') or os.getenv('BITS_DEBUG'):
@@ -225,7 +225,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
check=True)
- self.logger.info("grub-mkrescue output %s" % proc.stdout)
+ self.log.info("grub-mkrescue output %s" % proc.stdout)
else:
subprocess.check_call([mkrescue_script, '-o',
iso_file, bits_dir],
@@ -238,11 +238,10 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.assertTrue(os.access(iso_file, os.R_OK))
- self.logger.info('iso file %s successfully generated.', iso_file)
+ self.log.info('iso file %s successfully generated.', iso_file)
def setUp(self): # pylint: disable=arguments-differ
super().setUp()
- self.logger = self.log
prebuiltDir = self.scratch_file('prebuilt')
if not os.path.isdir(prebuiltDir):
@@ -333,7 +332,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
# in batch mode and then automatically initiate a vm shutdown.
self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT)
self._vm.wait(timeout=None)
- self.logger.debug("Checking console output ...")
+ self.log.debug("Checking console output ...")
self.parse_log()
if __name__ == '__main__':
diff --git a/tests/functional/x86_64/test_bad_vmstate.py b/tests/functional/x86_64/test_bad_vmstate.py
new file mode 100755
index 0000000..40098a8
--- /dev/null
+++ b/tests/functional/x86_64/test_bad_vmstate.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+'''Test whether the vmstate-static-checker script detects problems correctly'''
+
+import subprocess
+
+from qemu_test import QemuBaseTest
+
+
+EXPECTED_OUTPUT='''Warning: checking incompatible machine types: "pc-i440fx-2.1", "pc-i440fx-2.2"
+Section "fw_cfg" does not exist in dest
+Section "fusbh200-ehci-usb" version error: 2 > 1
+Section "fusbh200-ehci-usb", Description "ehci-core": expected field "usbsts", got "usbsts_pending"; skipping rest
+Section "pci-serial-4x" Description "pci-serial-multi": Entry "Fields" missing
+Section "intel-hda-generic", Description "intel-hda", Field "pci": missing description
+Section "cfi.pflash01": Entry "Description" missing
+Section "megasas", Description "PCIDevice": expected field "irq_state", while dest has no further fields
+Section "PIIX3-xen" Description "PIIX3": minimum version error: 1 < 2
+Section "PIIX3-xen" Description "PIIX3": Entry "Subsections" missing
+Section "tpci200": Description "tpci200" missing, got "tpci2002" instead; skipping
+Section "sun-fdtwo" Description "fdc": version error: 2 > 1
+Section "sun-fdtwo", Description "fdrive": Subsection "fdrive/media_rate" not found
+Section "usb-kbd" Description "usb-kbd" Field "kbd.keycodes" size mismatch: 4 , 2
+'''
+
+class BadVmStateTest(QemuBaseTest):
+ '''Test class for testing vmstat-static-checker script with bad input'''
+
+ def test_checker(self):
+ """
+ Test whether the checker script correctly detects the changes
+ between dump1.json and dump2.json.
+ """
+ src_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ 'dump1.json')
+ dst_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ 'dump2.json')
+ checkerscript = self.data_file('..', '..', 'scripts',
+ 'vmstate-static-checker.py')
+
+ self.log.info('Comparing %s with %s', src_json, dst_json)
+ cp = subprocess.run([checkerscript, '-s', src_json, '-d', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=False)
+ if cp.returncode != 13:
+ self.fail('Unexpected return code of vmstate-static-checker: ' +
+ cp.returncode)
+ if cp.stdout != EXPECTED_OUTPUT:
+ self.log.info('vmstate-static-checker output:\n%s', cp.stdout)
+ self.log.info('expected output:\n%s', EXPECTED_OUTPUT)
+ self.fail('Unexpected vmstate-static-checker output!')
+
+
+if __name__ == '__main__':
+ QemuBaseTest.main()
diff --git a/tests/functional/test_x86_cpu_model_versions.py b/tests/functional/x86_64/test_cpu_model_versions.py
index bd18acd..36c968f 100755
--- a/tests/functional/test_x86_cpu_model_versions.py
+++ b/tests/functional/x86_64/test_cpu_model_versions.py
@@ -72,44 +72,11 @@ class X86CPUModelAliases(QemuSystemTest):
self.assertNotIn("EPYC-IBPB-v1", cpus,
"EPYC-IBPB shouldn't be versioned")
- def test_4_0_alias_compatibility(self):
- """
- Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
- """
- self.set_machine('pc-i440fx-4.0')
- # pc-*-4.0 won't expose non-versioned CPU models as aliases
- # We do this to help management software to keep compatibility
- # with older QEMU versions that didn't have the versioned CPU model
- self.vm.add_args('-S')
- self.vm.launch()
- cpus = dict((m['name'], m) for m in
- self.vm.cmd('query-cpu-definitions'))
-
- self.assertFalse(cpus['Cascadelake-Server']['static'],
- 'unversioned Cascadelake-Server CPU model must not be static')
- self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
- 'Cascadelake-Server must not be an alias')
- self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
- 'Cascadelake-Server-v1 must not be an alias')
-
- self.assertFalse(cpus['qemu64']['static'],
- 'unversioned qemu64 CPU model must not be static')
- self.assertNotIn('alias-of', cpus['qemu64'],
- 'qemu64 must not be an alias')
- self.assertNotIn('alias-of', cpus['qemu64-v1'],
- 'qemu64-v1 must not be an alias')
-
- self.validate_variant_aliases(cpus)
-
- # On pc-*-4.0, no CPU model should be reported as an alias:
- for name,c in cpus.items():
- self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))
-
- def test_4_1_alias(self):
+ def test_unversioned_alias(self):
"""
Check if unversioned CPU model is an alias pointing to right version
"""
- self.set_machine('pc-i440fx-4.1')
+ self.set_machine('pc')
self.vm.add_args('-S')
self.vm.launch()
@@ -133,7 +100,7 @@ class X86CPUModelAliases(QemuSystemTest):
self.validate_variant_aliases(cpus)
- # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
+ # On recent PC machines, -noTSX and -IBRS models should be aliases:
self.assertEqual(cpus["Haswell"].get('alias-of'),
"Haswell-v1",
"Haswell must be an alias")
@@ -247,8 +214,8 @@ class CascadelakeArchCapabilities(QemuSystemTest):
cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
return self.vm.cmd('qom-get', path=cpu_path, property=prop)
- def test_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test(self):
+ self.set_machine('pc')
# machine-type only:
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
@@ -256,80 +223,27 @@ class CascadelakeArchCapabilities(QemuSystemTest):
'enforce=off')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
-
- def test_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
-
- def test_set_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # command line must override machine-type if CPU model is not versioned:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server,x-force-features=on,check=off,'
- 'enforce=off,+arch-capabilities')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
+ 'pc + Cascadelake-Server should not have arch-capabilities')
- def test_unset_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test_unset(self):
+ self.set_machine('pc')
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
'Cascadelake-Server,x-force-features=on,check=off,'
'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
-
- def test_v1_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # versioned CPU model overrides machine-type:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v1,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
-
- def test_v2_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v2,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
-
- def test_v1_set_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # command line must override machine-type and versioned CPU model:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v1,x-force-features=on,check=off,'
- 'enforce=off,+arch-capabilities')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
+ 'pc + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
- def test_v2_unset_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test_v2_unset(self):
+ self.set_machine('pc')
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
'Cascadelake-Server-v2,x-force-features=on,check=off,'
'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
+ 'pc + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_cpu_queries.py b/tests/functional/x86_64/test_cpu_queries.py
index b1122a0..b1122a0 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 7ddbfef..7ddbfef 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 7b9200a..7b9200a 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 62268d6..62268d6 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 a5d4450..a5d4450 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 2207f83..2207f83 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 2d9d31e..61b4a19 100755
--- a/tests/functional/test_mem_addr_space.py
+++ b/tests/functional/x86_64/test_mem_addr_space.py
@@ -58,8 +58,8 @@ class MemAddrCheck(QemuSystemTest):
should start fine.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.6G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=59.6G',
'-cpu', 'pentium,pse36=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -76,8 +76,8 @@ class MemAddrCheck(QemuSystemTest):
with pse36 above.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.6G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=59.6G',
'-cpu', 'pentium,pae=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -93,8 +93,8 @@ class MemAddrCheck(QemuSystemTest):
same options as the failing case above with pse36 cpu feature.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium,pse36=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -111,8 +111,8 @@ class MemAddrCheck(QemuSystemTest):
with the same options as the case above.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium,pae=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -128,8 +128,8 @@ class MemAddrCheck(QemuSystemTest):
with pse36 ON.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium2', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -148,8 +148,8 @@ class MemAddrCheck(QemuSystemTest):
above 4 GiB due to the PCI hole and simplicity.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=4G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=4G',
'-cpu', 'pentium', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -176,8 +176,8 @@ class MemAddrCheck(QemuSystemTest):
make QEMU fail with the error message.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m',
- '512,slots=1,maxmem=988G',
+ self.set_machine('pc-q35-7.0')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=988G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -197,8 +197,8 @@ class MemAddrCheck(QemuSystemTest):
than 988 GiB).
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=976G',
+ self.set_machine('pc-q35-7.1')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=976G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -214,8 +214,8 @@ class MemAddrCheck(QemuSystemTest):
successfully start when maxmem is < 988G.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m',
- '512,slots=1,maxmem=987.5G',
+ self.set_machine('pc-q35-7.0')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=987.5G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -231,8 +231,8 @@ class MemAddrCheck(QemuSystemTest):
successfully start when maxmem is < 976G.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=975.5G',
+ self.set_machine('pc-q35-7.1')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=975.5G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -249,9 +249,9 @@ class MemAddrCheck(QemuSystemTest):
"above_4G" memory starts at 4G.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'Skylake-Server',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=976G',
+ '-m', '512,slots=1,maxmem=976G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -274,9 +274,9 @@ class MemAddrCheck(QemuSystemTest):
fail to start.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=992G',
+ '-m', '512,slots=1,maxmem=992G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -293,9 +293,9 @@ class MemAddrCheck(QemuSystemTest):
QEMU should start fine.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=990G',
+ '-m', '512,slots=1,maxmem=990G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -314,12 +314,12 @@ class MemAddrCheck(QemuSystemTest):
alignment constraints with 40 bits (1 TiB) of processor physical bits.
"""
self.ensure_64bit_binary()
+ self.set_machine('q35')
self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40',
- '-machine', 'q35,cxl=on', '-m',
- '512,slots=1,maxmem=987G',
+ '-m', '512,slots=1,maxmem=987G',
'-display', 'none',
'-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1',
- '-M', 'cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=1G')
+ '-M', 'cxl=on,cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=1G')
self.vm.set_qmp_monitor(enabled=False)
self.vm.launch()
self.vm.wait()
@@ -333,9 +333,10 @@ class MemAddrCheck(QemuSystemTest):
with cxl enabled.
"""
self.ensure_64bit_binary()
+ self.set_machine('q35')
self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40',
- '-machine', 'q35,cxl=on', '-m',
- '512,slots=1,maxmem=987G',
+ '-machine', 'cxl=on',
+ '-m', '512,slots=1,maxmem=987G',
'-display', 'none',
'-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1')
self.vm.set_qmp_monitor(enabled=False)
diff --git a/tests/functional/x86_64/test_memlock.py b/tests/functional/x86_64/test_memlock.py
new file mode 100755
index 0000000..81bce80
--- /dev/null
+++ b/tests/functional/x86_64/test_memlock.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# Functional test that check overcommit memlock options
+#
+# Copyright (c) Yandex Technologies LLC, 2025
+#
+# Author:
+# Alexandr Moshkov <dtalexundeer@yandex-team.ru>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import re
+
+from typing import Dict
+
+from qemu_test import QemuSystemTest
+from qemu_test import skipLockedMemoryTest
+
+
+STATUS_VALUE_PATTERN = re.compile(r'^(\w+):\s+(\d+) kB', re.MULTILINE)
+
+
+@skipLockedMemoryTest(2_097_152) # 2GB
+class MemlockTest(QemuSystemTest):
+ """
+ Runs a guest with memlock options.
+ Then verify, that this options is working correctly
+ by checking the status file of the QEMU process.
+ """
+
+ def common_vm_setup_with_memlock(self, memlock):
+ self.vm.add_args('-overcommit', f'mem-lock={memlock}')
+ self.vm.launch()
+
+ def test_memlock_off(self):
+ self.common_vm_setup_with_memlock('off')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # libgcrypt may mlock a few pages
+ self.assertTrue(status['VmLck'] < 32)
+
+ def test_memlock_on(self):
+ self.common_vm_setup_with_memlock('on')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # VmLck > 0 kB and almost all memory is resident
+ self.assertTrue(status['VmLck'] > 0)
+ self.assertTrue(status['VmRSS'] >= status['VmSize'] * 0.70)
+
+ def test_memlock_onfault(self):
+ self.common_vm_setup_with_memlock('on-fault')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # VmLck > 0 kB and only few memory is resident
+ self.assertTrue(status['VmLck'] > 0)
+ self.assertTrue(status['VmRSS'] <= status['VmSize'] * 0.30)
+
+ def get_process_status_values(self, pid: int) -> Dict[str, int]:
+ result = {}
+ raw_status = self._get_raw_process_status(pid)
+
+ for line in raw_status.split('\n'):
+ if m := STATUS_VALUE_PATTERN.match(line):
+ result[m.group(1)] = int(m.group(2))
+
+ return result
+
+ def _get_raw_process_status(self, pid: int) -> str:
+ try:
+ with open(f'/proc/{pid}/status', 'r') as f:
+ return f.read()
+ except FileNotFoundError:
+ self.skipTest("Can't open status file of the process")
+
+
+if __name__ == '__main__':
+ MemlockTest.main()
diff --git a/tests/functional/x86_64/test_migration.py b/tests/functional/x86_64/test_migration.py
new file mode 100755
index 0000000..f3a517a
--- /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 0000000..756629d
--- /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 ee1a397..ee1a397 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 9d5a37c..2bed8ad 100755
--- a/tests/functional/test_pc_cpu_hotplug_props.py
+++ b/tests/functional/x86_64/test_pc_cpu_hotplug_props.py
@@ -26,6 +26,7 @@ from qemu_test import QemuSystemTest
class OmittedCPUProps(QemuSystemTest):
def test_no_die_id(self):
+ self.set_machine('pc')
self.vm.add_args('-nodefaults', '-S')
self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
diff --git a/tests/functional/test_x86_64_replay.py b/tests/functional/x86_64/test_replay.py
index 27287d4..27287d4 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 d713e91..2b31ae8 100755
--- a/tests/functional/test_x86_64_reverse_debug.py
+++ b/tests/functional/x86_64/test_reverse_debug.py
@@ -2,34 +2,29 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
#
-# Reverse debugging test
+# Reverse debugging test for x86_64
#
# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
#
# Author:
# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
#
# 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 qemu_test import skipIfMissingImports, skipFlakyTest
+from qemu_test import skipFlakyTest
from reverse_debugging import ReverseDebugging
-@skipIfMissingImports('avocado.utils')
class ReverseDebugging_X86_64(ReverseDebugging):
- REG_PC = 0x10
- REG_CS = 0x12
- def get_pc(self, g):
- return self.get_reg_le(g, self.REG_PC) \
- + self.get_reg_le(g, self.REG_CS) * 0x10
-
@skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2922")
def test_x86_64_pc(self):
self.set_machine('pc')
# start with BIOS only
- self.reverse_debugging()
+ self.reverse_debugging(gdb_arch='x86-64')
if __name__ == '__main__':
diff --git a/tests/functional/test_x86_64_tuxrun.py b/tests/functional/x86_64/test_tuxrun.py
index fcbc62b..fcbc62b 100755
--- a/tests/functional/test_x86_64_tuxrun.py
+++ b/tests/functional/x86_64/test_tuxrun.py
diff --git a/tests/functional/x86_64/test_vfio_user_client.py b/tests/functional/x86_64/test_vfio_user_client.py
new file mode 100755
index 0000000..8bc16e5
--- /dev/null
+++ b/tests/functional/x86_64/test_vfio_user_client.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2025 Nutanix, Inc.
+#
+# Author:
+# Mark Cave-Ayland <mark.caveayland@nutanix.com>
+# John Levon <john.levon@nutanix.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+"""
+Check basic vfio-user-pci client functionality. The test starts two VMs:
+
+ - the server VM runs the libvfio-user "gpio" example server inside it,
+ piping vfio-user traffic between a local UNIX socket and a virtio-serial
+ port. On the host, the virtio-serial port is backed by a local socket.
+
+ - the client VM loads the gpio-pci-idio-16 kernel module, with the
+ vfio-user client connecting to the above local UNIX socket.
+
+This way, we don't depend on trying to run a vfio-user server on the host
+itself.
+
+Once both VMs are running, we run some basic configuration on the gpio device
+and verify that the server is logging the expected out. As this is consistent
+given the same VM images, we just do a simple direct comparison.
+"""
+
+import os
+
+from qemu_test import Asset
+from qemu_test import QemuSystemTest
+from qemu_test import exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+# Exact output can vary, so we just sample for some expected lines.
+EXPECTED_SERVER_LINES = [
+ "gpio: adding DMA region [0, 0xc0000) offset=0 flags=0x3",
+ "gpio: devinfo flags 0x3, num_regions 9, num_irqs 5",
+ "gpio: region_info[0] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[1] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[2] offset 0 flags 0x3 size 256 argsz 32",
+ "gpio: region_info[3] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[4] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[5] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[7] offset 0 flags 0x3 size 256 argsz 32",
+ "gpio: region7: read 256 bytes at 0",
+ "gpio: region7: read 0 from (0x30:4)",
+ "gpio: cleared EROM",
+ "gpio: I/O space enabled",
+ "gpio: memory space enabled",
+ "gpio: SERR# enabled",
+ "gpio: region7: wrote 0x103 to (0x4:2)",
+ "gpio: I/O space enabled",
+ "gpio: memory space enabled",
+]
+
+class VfioUserClient(QemuSystemTest):
+ """vfio-user testing class."""
+
+ ASSET_REPO = 'https://github.com/mcayland-ntx/libvfio-user-test'
+
+ ASSET_KERNEL = Asset(
+ f'{ASSET_REPO}/raw/refs/heads/main/images/bzImage',
+ '40292fa6ce95d516e26bccf5974e138d0db65a6de0bc540cabae060fe9dea605'
+ )
+
+ ASSET_ROOTFS = Asset(
+ f'{ASSET_REPO}/raw/refs/heads/main/images/rootfs.ext2',
+ 'e1e3abae8aebb8e6e77f08b1c531caeacf46250c94c815655c6bbea59fc3d1c1'
+ )
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.kernel_path = None
+ self.rootfs_path = None
+
+ def configure_server_vm_args(self, server_vm, sock_path):
+ """
+ Configuration for the server VM. Set up virtio-serial device backed by
+ the given socket path.
+ """
+ server_vm.add_args('-kernel', self.kernel_path)
+ server_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
+ server_vm.add_args('-drive',
+ f"file={self.rootfs_path},if=ide,format=raw,id=drv0")
+ server_vm.add_args('-snapshot')
+ server_vm.add_args('-chardev',
+ f"socket,id=sock0,path={sock_path},telnet=off,server=on,wait=off")
+ server_vm.add_args('-device', 'virtio-serial')
+ server_vm.add_args('-device',
+ 'virtserialport,chardev=sock0,name=org.fedoraproject.port.0')
+
+ def configure_client_vm_args(self, client_vm, sock_path):
+ """
+ Configuration for the client VM. Point the vfio-user-pci device to the
+ socket path configured above.
+ """
+
+ client_vm.add_args('-kernel', self.kernel_path)
+ client_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
+ client_vm.add_args('-drive',
+ f'file={self.rootfs_path},if=ide,format=raw,id=drv0')
+ client_vm.add_args('-snapshot')
+ client_vm.add_args('-device',
+ '{"driver":"vfio-user-pci",' +
+ '"socket":{"path": "%s", "type": "unix"}}' % sock_path)
+
+ def setup_vfio_user_pci_server(self, server_vm):
+ """
+ Start the libvfio-user server within the server VM, and arrange
+ for data to shuttle between its socket and the virtio serial port.
+ """
+ wait_for_console_pattern(self, 'login:', None, server_vm)
+ exec_command_and_wait_for_pattern(self, 'root', '#', None, server_vm)
+
+ exec_command_and_wait_for_pattern(self,
+ 'gpio-pci-idio-16 -v /tmp/vfio-user.sock >/var/tmp/gpio.out 2>&1 &',
+ '#', None, server_vm)
+
+ # wait for libvfio-user socket to appear
+ while True:
+ out = exec_command_and_wait_for_pattern(self,
+ 'ls --color=no /tmp/vfio-user.sock', '#', None, server_vm)
+ ls_out = out.decode().splitlines()[1].strip()
+ if ls_out == "/tmp/vfio-user.sock":
+ break
+
+ exec_command_and_wait_for_pattern(self,
+ 'socat UNIX-CONNECT:/tmp/vfio-user.sock /dev/vport0p1,ignoreeof ' +
+ ' &', '#', None, server_vm)
+
+ def test_vfio_user_pci(self):
+ """Run basic sanity test."""
+
+ self.set_machine('pc')
+ self.require_device('virtio-serial')
+ self.require_device('vfio-user-pci')
+
+ self.kernel_path = self.ASSET_KERNEL.fetch()
+ self.rootfs_path = self.ASSET_ROOTFS.fetch()
+
+ sock_dir = self.socket_dir()
+ socket_path = os.path.join(sock_dir.name, 'vfio-user.sock')
+
+ server_vm = self.get_vm(name='server')
+ server_vm.set_console()
+ self.configure_server_vm_args(server_vm, socket_path)
+
+ server_vm.launch()
+
+ self.log.debug('starting libvfio-user server')
+
+ self.setup_vfio_user_pci_server(server_vm)
+
+ client_vm = self.get_vm(name="client")
+ client_vm.set_console()
+ self.configure_client_vm_args(client_vm, socket_path)
+
+ try:
+ client_vm.launch()
+ except:
+ self.log.error('client VM failed to start, dumping server logs')
+ exec_command_and_wait_for_pattern(self, 'cat /var/tmp/gpio.out',
+ '#', None, server_vm)
+ raise
+
+ self.log.debug('waiting for client VM boot')
+
+ wait_for_console_pattern(self, 'login:', None, client_vm)
+ exec_command_and_wait_for_pattern(self, 'root', '#', None, client_vm)
+
+ #
+ # Here, we'd like to actually interact with the gpio device a little
+ # more as described at:
+ #
+ # https://github.com/nutanix/libvfio-user/blob/master/docs/qemu.md
+ #
+ # Unfortunately, the buildroot Linux kernel has some undiagnosed issue
+ # so we don't get /sys/class/gpio. Nonetheless just the basic
+ # initialization and setup is enough for basic testing of vfio-user.
+ #
+
+ self.log.debug('collecting libvfio-user server output')
+
+ out = exec_command_and_wait_for_pattern(self,
+ 'cat /var/tmp/gpio.out',
+ 'gpio: region2: wrote 0 to (0x1:1)',
+ None, server_vm)
+
+ gpio_server_out = [s for s in out.decode().splitlines()
+ if s.startswith("gpio:")]
+
+ for line in EXPECTED_SERVER_LINES:
+ if line not in gpio_server_out:
+ self.log.error(f'Missing server debug line: {line}')
+ self.fail(False)
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_virtio_balloon.py b/tests/functional/x86_64/test_virtio_balloon.py
index 5877b6c..5877b6c 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 81c9156..be96de2 100755
--- a/tests/functional/test_virtio_gpu.py
+++ b/tests/functional/x86_64/test_virtio_gpu.py
@@ -108,6 +108,7 @@ class VirtioGPUx86(QemuSystemTest):
shell=False,
close_fds=False,
)
+ self._vug_log_file.close()
self.vm.set_console()
self.vm.add_args("-cpu", "host")
@@ -135,6 +136,7 @@ class VirtioGPUx86(QemuSystemTest):
"features: +virgl +edid")
self.vm.shutdown()
qemu_sock.close()
+ vug_sock.close()
vugp.terminate()
vugp.wait()
diff --git a/tests/functional/test_virtio_version.py b/tests/functional/x86_64/test_virtio_version.py
index a5ea732..a5ea732 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 0000000..d61d82a
--- /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 147c920..147c920 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 eb00a3b..eb00a3b 100755
--- a/tests/functional/test_xtensa_replay.py
+++ b/tests/functional/xtensa/test_replay.py
diff --git a/tests/guest-debug/test_gdbstub.py b/tests/guest-debug/test_gdbstub.py
index 4f08089..e017ccb 100644
--- a/tests/guest-debug/test_gdbstub.py
+++ b/tests/guest-debug/test_gdbstub.py
@@ -1,7 +1,6 @@
"""Helper functions for gdbstub testing
"""
-from __future__ import print_function
import argparse
import gdb
import os
diff --git a/tests/include/meson.build b/tests/include/meson.build
index 9abba30..8e8d1ec 100644
--- a/tests/include/meson.build
+++ b/tests/include/meson.build
@@ -13,4 +13,4 @@ test_qapi_outputs_extra = [
test_qapi_files_extra = custom_target('QAPI test (include)',
output: test_qapi_outputs_extra,
input: test_qapi_files,
- command: 'true')
+ command: [python, '-c', ''])
diff --git a/tests/lcitool/libvirt-ci b/tests/lcitool/libvirt-ci
-Subproject 18c4bfe02c467e5639bf9a687139735ccd7a3ff
+Subproject 9da20ff7c3bc9067804a7561c2ff87583b43485
diff --git a/tests/lcitool/mappings.yml b/tests/lcitool/mappings.yml
index 673baf3..8f0e95e 100644
--- a/tests/lcitool/mappings.yml
+++ b/tests/lcitool/mappings.yml
@@ -8,6 +8,10 @@ mappings:
meson:
OpenSUSELeap15:
+ # Use Meson from PyPI wherever Rust is enabled
+ Debian:
+ Fedora:
+ Ubuntu:
python3:
OpenSUSELeap15: python311-base
@@ -72,7 +76,7 @@ mappings:
pypi_mappings:
# Request more recent version
meson:
- default: meson==1.5.0
+ default: meson==1.8.1
# Drop packages that need devel headers
python3-numpy:
diff --git a/tests/lcitool/projects/qemu.yml b/tests/lcitool/projects/qemu.yml
index c07242f..82812e7 100644
--- a/tests/lcitool/projects/qemu.yml
+++ b/tests/lcitool/projects/qemu.yml
@@ -44,6 +44,7 @@ packages:
- libcacard
- libcap-ng
- libcbor
+ - libclang-rt
- libcurl
- libdrm
- libepoxy
@@ -91,7 +92,6 @@ packages:
- pkg-config
- pulseaudio
- python3
- - python3-imp
- python3-numpy
- python3-opencv
- python3-pillow
@@ -104,6 +104,7 @@ packages:
- python3-venv
- rpm2cpio
- rust
+ - rust-std
- sdl2
- sdl2-image
- sed
diff --git a/tests/lcitool/refresh b/tests/lcitool/refresh
index 8474ea8..056cfb6 100755
--- a/tests/lcitool/refresh
+++ b/tests/lcitool/refresh
@@ -63,7 +63,8 @@ add_user_mapping = [
" id ${USER} 2>/dev/null || useradd -u ${UID} -U ${USER}; fi\n"
]
-def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None):
+def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None,
+ enable_rust=True):
filename = Path(src_dir, "tests", "docker", "dockerfiles", host + ".docker")
cmd = lcitool_cmd + ["dockerfile"]
if cross is not None:
@@ -75,6 +76,8 @@ def generate_dockerfile(host, target, project="qemu", cross=None, trailer=None):
else:
trailer = "\n".join(add_user_mapping)
+ if enable_rust:
+ trailer += "\nENV ENABLE_RUST 1\n"
generate(filename, cmd, trailer)
@@ -97,10 +100,15 @@ def generate_yaml(os, target, arch, trailer=None):
generate(filename, cmd, trailer)
+alpine_extras = [
+ "# https://gitlab.alpinelinux.org/alpine/aports/-/issues/17463\n",
+ "RUN apk add clang19-libclang\n",
+]
+
# Netmap still needs to be manually built as it is yet to be packaged
# into a distro. We also add cscope and gtags which are used in the CI
# test
-debian12_extras = [
+debian13_extras = [
"# netmap/cscope/global\n",
"RUN DEBIAN_FRONTEND=noninteractive eatmydata \\\n",
" apt install -y --no-install-recommends \\\n",
@@ -121,6 +129,7 @@ fedora_rustup_nightly_extras = [
"RUN dnf install -y wget\n",
"ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo\n",
"ENV RUSTC=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustc\n",
+ "ENV RUSTDOC=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/rustdoc\n",
"ENV CARGO=/usr/local/rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo\n",
"RUN set -eux && \\\n",
" rustArch='x86_64-unknown-linux-gnu' && \\\n",
@@ -135,6 +144,7 @@ fedora_rustup_nightly_extras = [
" /usr/local/cargo/bin/rustup run nightly cargo --version && \\\n",
" /usr/local/cargo/bin/rustup run nightly rustc --version && \\\n",
' test "$CARGO" = "$(/usr/local/cargo/bin/rustup +nightly which cargo)" && \\\n',
+ ' test "$RUSTDOC" = "$(/usr/local/cargo/bin/rustup +nightly which rustdoc)" && \\\n',
' test "$RUSTC" = "$(/usr/local/cargo/bin/rustup +nightly which rustc)"\n',
'ENV PATH=$CARGO_HOME/bin:$PATH\n',
'RUN /usr/local/cargo/bin/rustup run nightly cargo install bindgen-cli\n',
@@ -143,6 +153,7 @@ fedora_rustup_nightly_extras = [
ubuntu2204_rust_extras = [
"ENV RUSTC=/usr/bin/rustc-1.77\n",
+ "ENV RUSTDOC=/usr/bin/rustdoc-1.77\n",
"ENV CARGO_HOME=/usr/local/cargo\n",
'ENV PATH=$CARGO_HOME/bin:$PATH\n',
"RUN DEBIAN_FRONTEND=noninteractive eatmydata \\\n",
@@ -164,48 +175,51 @@ try:
#
# Standard native builds
#
- generate_dockerfile("alpine", "alpine-321")
+ generate_dockerfile("alpine", "alpine-321",
+ trailer="".join(alpine_extras))
generate_dockerfile("centos9", "centos-stream-9")
- generate_dockerfile("debian", "debian-12",
- trailer="".join(debian12_extras))
- generate_dockerfile("fedora", "fedora-40")
+ generate_dockerfile("debian", "debian-13",
+ trailer="".join(debian13_extras))
+ generate_dockerfile("fedora", "fedora-41")
generate_dockerfile("opensuse-leap", "opensuse-leap-15")
generate_dockerfile("ubuntu2204", "ubuntu-2204",
- trailer="".join(ubuntu2204_rust_extras))
+ trailer="".join(ubuntu2204_rust_extras),
+ # https://bugs.launchpad.net/ubuntu/+source/rustc-1.83/+bug/2120318
+ enable_rust=False)
#
# Non-fatal Rust-enabled build
#
- generate_dockerfile("fedora-rust-nightly", "fedora-40",
+ generate_dockerfile("fedora-rust-nightly", "fedora-41",
trailer="".join(fedora_rustup_nightly_extras))
#
# Cross compiling builds
#
- generate_dockerfile("debian-amd64-cross", "debian-12",
+ generate_dockerfile("debian-amd64-cross", "debian-13",
cross="x86_64",
trailer=cross_build("x86_64-linux-gnu-",
"x86_64-softmmu,"
"x86_64-linux-user,"
"i386-softmmu,i386-linux-user"))
- generate_dockerfile("debian-arm64-cross", "debian-12",
+ generate_dockerfile("debian-arm64-cross", "debian-13",
cross="aarch64",
trailer=cross_build("aarch64-linux-gnu-",
"aarch64-softmmu,aarch64-linux-user"))
- generate_dockerfile("debian-armhf-cross", "debian-12",
+ generate_dockerfile("debian-armhf-cross", "debian-13",
cross="armv7l",
trailer=cross_build("arm-linux-gnueabihf-",
"arm-softmmu,arm-linux-user"))
- generate_dockerfile("debian-i686-cross", "debian-12",
+ generate_dockerfile("debian-i686-cross", "debian-13",
cross="i686",
trailer=cross_build("i686-linux-gnu-",
- "x86_64-softmmu,"
- "x86_64-linux-user,"
"i386-softmmu,i386-linux-user"))
+ # mips no longer supported in debian-13
+ # https://www.debian.org/releases/trixie/release-notes/issues.html#mips-architectures-removed
generate_dockerfile("debian-mips64el-cross", "debian-12",
cross="mips64el",
trailer=cross_build("mips64el-linux-gnuabi64-",
@@ -216,7 +230,7 @@ try:
trailer=cross_build("mipsel-linux-gnu-",
"mipsel-softmmu,mipsel-linux-user"))
- generate_dockerfile("debian-ppc64el-cross", "debian-12",
+ generate_dockerfile("debian-ppc64el-cross", "debian-13",
cross="ppc64le",
trailer=cross_build("powerpc64le-linux-gnu-",
"ppc64-softmmu,ppc64-linux-user"))
@@ -224,21 +238,23 @@ try:
# while not yet a release architecture the packages are still
# build while part of testing
generate_dockerfile("debian-riscv64-cross", "debian-13",
- project="qemu-minimal",
cross="riscv64",
trailer=cross_build("riscv64-linux-gnu-",
"riscv64-softmmu,riscv64-linux-user"))
- generate_dockerfile("debian-s390x-cross", "debian-12",
+ generate_dockerfile("debian-s390x-cross", "debian-13",
cross="s390x",
trailer=cross_build("s390x-linux-gnu-",
"s390x-softmmu,s390x-linux-user"))
- generate_dockerfile("fedora-win64-cross", "fedora-40",
+ generate_dockerfile("fedora-win64-cross", "fedora-41",
project='qemu,qemu-win-installer',
cross="mingw64",
trailer=cross_build("x86_64-w64-mingw32-",
- "x86_64-softmmu"))
+ "x86_64-softmmu"),
+ # linking with rust is buggy:
+ # https://github.com/mesonbuild/meson/pull/14991
+ enable_rust=False)
#
# Cirrus packages lists for GitLab
@@ -254,8 +270,8 @@ try:
#
# Ansible package lists
#
- generate_yaml("ubuntu", "ubuntu-2204", "aarch64")
- generate_yaml("ubuntu", "ubuntu-2204", "s390x")
+ generate_yaml("ubuntu", "ubuntu-2404", "aarch64")
+ generate_yaml("ubuntu", "ubuntu-2404", "s390x")
sys.exit(0)
diff --git a/tests/meson.build b/tests/meson.build
index c596192..cbe7916 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -88,3 +88,4 @@ subdir('qapi-schema')
subdir('qtest')
subdir('migration-stress')
subdir('functional')
+subdir('tracetool')
diff --git a/tests/qapi-schema/doc-bad-section.err b/tests/qapi-schema/doc-bad-section.err
deleted file mode 100644
index 785cacc..0000000
--- a/tests/qapi-schema/doc-bad-section.err
+++ /dev/null
@@ -1 +0,0 @@
-doc-bad-section.json:5:1: unexpected '=' markup in definition documentation
diff --git a/tests/qapi-schema/doc-bad-section.json b/tests/qapi-schema/doc-bad-section.json
deleted file mode 100644
index 8175d95..0000000
--- a/tests/qapi-schema/doc-bad-section.json
+++ /dev/null
@@ -1,10 +0,0 @@
-# = section within an expression comment
-
-##
-# @Enum:
-# == No good here
-# @one: The _one_ {and only}
-#
-# @two is undocumented
-##
-{ 'enum': 'Enum', 'data': [ 'one', 'two' ] }
diff --git a/tests/qapi-schema/doc-good.json b/tests/qapi-schema/doc-good.json
index 14b808f..fac1342 100644
--- a/tests/qapi-schema/doc-good.json
+++ b/tests/qapi-schema/doc-good.json
@@ -8,7 +8,9 @@
'documentation-exceptions': [ 'Enum', 'Variant1', 'Alternate', 'cmd' ] } }
##
-# = Section
+# *******
+# Section
+# *******
##
##
@@ -16,7 +18,8 @@
##
##
-# == Subsection
+# Subsection
+# ==========
#
# *with emphasis*
# @var {in braces}
@@ -144,7 +147,8 @@
'if': { 'not': { 'any': [ 'IFONE', 'IFTWO' ] } } }
##
-# == Another subsection
+# Another subsection
+# ==================
##
##
diff --git a/tests/qapi-schema/doc-good.out b/tests/qapi-schema/doc-good.out
index dc8352e..04a5507 100644
--- a/tests/qapi-schema/doc-good.out
+++ b/tests/qapi-schema/doc-good.out
@@ -55,13 +55,16 @@ event EVT_BOXED Object
feature feat3
doc freeform
body=
-= Section
+*******
+Section
+*******
doc freeform
body=
Just text, no heading.
doc freeform
body=
-== Subsection
+Subsection
+==========
*with emphasis*
@var {in braces}
@@ -155,7 +158,8 @@ description starts on the same line
a feature
doc freeform
body=
-== Another subsection
+Another subsection
+==================
doc symbol=cmd
body=
diff --git a/tests/qapi-schema/doc-good.txt b/tests/qapi-schema/doc-good.txt
index 17a1d56..74b7368 100644
--- a/tests/qapi-schema/doc-good.txt
+++ b/tests/qapi-schema/doc-good.txt
@@ -1,6 +1,8 @@
Section
*******
+Just text, no heading.
+
Subsection
==========
@@ -35,249 +37,145 @@ Example:
-> in <- out Examples: - *verbatim* - {braces}
+Enum Enum
+ *Availability*: "IFCOND"
-"Enum" (Enum)
--------------
-
-
-Values
-~~~~~~
-
-"one" (**If: **"IFONE")
- The _one_ {and only}, description on the same line
-
-"two"
- Not documented
-
-
-Features
-~~~~~~~~
-
-"enum-feat"
- Also _one_ {and only}
-
-"enum-member-feat"
- a member feature
-
-"two" is undocumented
-
-
-If
-~~
-
-"IFCOND"
-
-
-"Base" (Object)
----------------
-
-
-Members
-~~~~~~~
-
-"base1": "Enum"
- description starts on a new line, minimally indented
-
-
-If
-~~
-
-"IFALL1 and IFALL2"
-
-
-"Variant1" (Object)
--------------------
-
-A paragraph
-
-Another paragraph
-
-"var1" is undocumented
+ Values:
+ * **one** -- The _one_ {and only}, description on the same line
+ * **two** -- Not documented
-Members
-~~~~~~~
+ Features:
+ * **enum-feat** -- Also _one_ {and only}
-"var1": "string" (**If: **"IFSTR")
- Not documented
+ * **enum-member-feat** -- a member feature
+ "two" is undocumented
-Features
-~~~~~~~~
+Object Base
+ *Availability*: "IFALL1 and IFALL2"
-"variant1-feat"
- a feature
+ Members:
+ * **base1** ("Enum") -- description starts on a new line,
+ minimally indented
-"member-feat"
- a member feature
+Object Variant1
+ A paragraph
-"Variant2" (Object)
--------------------
+ Another paragraph
+ "var1" is undocumented
-"Object" (Object)
------------------
+ Members:
+ * **var1** ("string") -- Not documented
+ Features:
+ * **variant1-feat** -- a feature
-Members
-~~~~~~~
+ * **member-feat** -- a member feature
-The members of "Base"
-The members of "Variant1" when "base1" is ""one""
-The members of "Variant2" when "base1" is ""two"" (**If: **"IFONE or
-IFTWO")
+Object Variant2
-Features
-~~~~~~~~
+Object Object
-"union-feat1"
- a feature
+ Members:
+ * The members of "Base".
+ * When "base1" is "one": The members of "Variant1".
-"Alternate" (Alternate)
------------------------
+ * When "base1" is "two": The members of "Variant2".
+ Features:
+ * **union-feat1** -- a feature
-Members
-~~~~~~~
+Alternate Alternate
+ *Availability*: "not (IFONE or IFTWO)"
-"i": "int"
- description starts on the same line remainder indented the same "b"
- is undocumented
+ Alternatives:
+ * **i** ("int") -- description starts on the same line remainder
+ indented the same "b" is undocumented
-"b": "boolean"
- Not documented
+ * **b** ("boolean") -- Not documented
-
-Features
-~~~~~~~~
-
-"alt-feat"
- a feature
-
-
-If
-~~
-
-"not (IFONE or IFTWO)"
+ Features:
+ * **alt-feat** -- a feature
Another subsection
==================
+Command cmd (Since: 2.10)
-"cmd" (Command)
----------------
-
-
-Arguments
-~~~~~~~~~
-
-"arg1": "int"
- description starts on a new line, indented
-
-"arg2": "string" (optional)
- description starts on the same line remainder indented differently
-
-"arg3": "boolean"
- Not documented
-
-
-Features
-~~~~~~~~
-
-"cmd-feat1"
- a feature
+ Arguments:
+ * **arg1** ("int") -- description starts on a new line, indented
-"cmd-feat2"
- another feature
-
-Note:
-
- "arg3" is undocumented
-
-
-Returns
-~~~~~~~
-
-"Object"
-
-
-Errors
-~~~~~~
-
-some
-
-Notes:
-
-* Lorem ipsum dolor sit amet
-
-* Ut enim ad minim veniam
-
-Duis aute irure dolor
+ * **arg2** ("string", *optional*) -- description starts on the
+ same line remainder indented differently
-Example: Ideal fast-food burger situation:
+ * **arg3** ("boolean") -- Not documented
- -> "in"
- <- "out"
+ Features:
+ * **cmd-feat1** -- a feature
-Examples:
+ * **cmd-feat2** -- another feature
- - Not a QMP code block
- - Merely a preformatted code block literal
- It isn't even an rST list.
- - *verbatim*
- - {braces}
+ Note:
-Note::
- Ceci n'est pas une note
+ "arg3" is undocumented
+ Return:
+ "Object" -- "Object"
-Since
-~~~~~
+ Errors:
+ some
-2.10
+ Notes:
+ * Lorem ipsum dolor sit amet
-"cmd-boxed" (Command)
----------------------
+ * Ut enim ad minim veniam
-If you're bored enough to read this, go see a video of boxed cats
+ Duis aute irure dolor
+ Example: Ideal fast-food burger situation:
-Arguments
-~~~~~~~~~
+ -> "in"
+ <- "out"
-The members of "Object"
+ Examples:
-Features
-~~~~~~~~
+ - Not a QMP code block
+ - Merely a preformatted code block literal
+ It isn't even an rST list.
+ - *verbatim*
+ - {braces}
-"cmd-feat1"
- a feature
+ Note::
+ Ceci n'est pas une note
-"cmd-feat2"
- another feature
+Command cmd-boxed
-Example::
+ If you're bored enough to read this, go see a video of boxed cats
- -> "this example"
+ Arguments:
+ * The members of "Object".
- <- ... has no title ...
+ Features:
+ * **cmd-feat1** -- a feature
+ * **cmd-feat2** -- another feature
-"EVT_BOXED" (Event)
--------------------
+ Example::
+ -> "this example"
-Arguments
-~~~~~~~~~
+ <- ... has no title ...
-The members of "Object"
+Event EVT_BOXED
-Features
-~~~~~~~~
+ Members:
+ * The members of "Object".
-"feat3"
- a feature
+ Features:
+ * **feat3** -- a feature
diff --git a/tests/qapi-schema/doc-non-first-section.err b/tests/qapi-schema/doc-non-first-section.err
deleted file mode 100644
index eeced2b..0000000
--- a/tests/qapi-schema/doc-non-first-section.err
+++ /dev/null
@@ -1 +0,0 @@
-doc-non-first-section.json:5:1: '=' heading must come first in a comment block
diff --git a/tests/qapi-schema/doc-non-first-section.json b/tests/qapi-schema/doc-non-first-section.json
deleted file mode 100644
index 1590876..0000000
--- a/tests/qapi-schema/doc-non-first-section.json
+++ /dev/null
@@ -1,6 +0,0 @@
-# = section must be first line
-
-##
-#
-# = Not first
-##
diff --git a/tests/qapi-schema/doc-non-first-section.out b/tests/qapi-schema/doc-non-first-section.out
deleted file mode 100644
index e69de29..0000000
--- a/tests/qapi-schema/doc-non-first-section.out
+++ /dev/null
diff --git a/tests/qapi-schema/meson.build b/tests/qapi-schema/meson.build
index 9577178..c47025d 100644
--- a/tests/qapi-schema/meson.build
+++ b/tests/qapi-schema/meson.build
@@ -61,7 +61,6 @@ schemas = [
'doc-bad-event-arg.json',
'doc-bad-feature.json',
'doc-bad-indent.json',
- 'doc-bad-section.json',
'doc-bad-symbol.json',
'doc-bad-union-member.json',
'doc-before-include.json',
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index 4be9302..cf7fb8a 100755
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -165,7 +165,7 @@ def test_and_diff(test_name, dir_name, update):
if actual_out == expected_out and actual_err == expected_err:
return 0
- print("%s %s" % (test_name, 'UPDATE' if update else 'FAIL'),
+ print("%s: %s" % (test_name, 'UPDATE' if update else 'FAIL'),
file=sys.stderr)
out_diff = difflib.unified_diff(expected_out, actual_out, outfp.name)
err_diff = difflib.unified_diff(expected_err, actual_err, errfp.name)
@@ -173,6 +173,9 @@ def test_and_diff(test_name, dir_name, update):
sys.stdout.writelines(err_diff)
if not update:
+ print(("\n%s: set QEMU_TEST_REGENERATE=1 to recreate reference output" +
+ "if the QAPI schema generator was intentionally changed") % test_name,
+ file=sys.stderr)
return 1
try:
@@ -197,7 +200,7 @@ def main(argv):
parser.add_argument('-d', '--dir', action='store', default='',
help="directory containing tests")
parser.add_argument('-u', '--update', action='store_true',
- default='QAPI_TEST_UPDATE' in os.environ,
+ default='QEMU_TEST_REGENERATE' in os.environ,
help="update expected test results")
parser.add_argument('tests', nargs='*', metavar='TEST', action='store')
args = parser.parse_args()
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
index e52484d..8fdbcc5 100644
--- a/tests/qemu-iotests/039.out
+++ b/tests/qemu-iotests/039.out
@@ -11,7 +11,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features [0]
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@@ -46,7 +46,7 @@ read 512/512 bytes at offset 0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features [0]
ERROR cluster 5 refcount=0 reference=1
Rebuilding refcount structure
@@ -60,7 +60,7 @@ incompatible_features []
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features []
No errors were found on the image.
@@ -79,7 +79,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features [0]
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@@ -89,7 +89,7 @@ Data may be corrupted, or further writes to the image may corrupt it.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features []
No errors were found on the image.
*** done
diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out
index 34e1b45..70c6275 100644
--- a/tests/qemu-iotests/049.out
+++ b/tests/qemu-iotests/049.out
@@ -98,8 +98,7 @@ qemu-img create -f qcow2 -o size=-1024 TEST_DIR/t.qcow2
qemu-img: TEST_DIR/t.qcow2: Value '-1024' is out of range for parameter 'size'
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- -1k
-qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
-qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
+qemu-img: Invalid image size specified: '-1k'
qemu-img create -f qcow2 -o size=-1k TEST_DIR/t.qcow2
qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
@@ -107,8 +106,7 @@ Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- 1kilobyte
-qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
-qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
+qemu-img: Invalid image size specified: '1kilobyte'
qemu-img create -f qcow2 -o size=1kilobyte TEST_DIR/t.qcow2
qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
@@ -116,8 +114,7 @@ Optional suffix k, M, G, T, P or E means kilo-, mega-, giga-, tera-, peta-
and exabytes, respectively.
qemu-img create -f qcow2 TEST_DIR/t.qcow2 -- foobar
-qemu-img: Invalid image size specified. You may use k, M, G, T, P or E suffixes for
-qemu-img: kilobytes, megabytes, gigabytes, terabytes, petabytes and exabytes.
+qemu-img: Invalid image size specified: 'foobar'
qemu-img create -f qcow2 -o size=foobar TEST_DIR/t.qcow2
qemu-img: TEST_DIR/t.qcow2: Parameter 'size' expects a non-negative number below 2^64
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 24c33ad..951c6bf 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -118,7 +118,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
magic 0x514649fb
version 3
backing_file_offset 0x0
@@ -304,7 +304,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
magic 0x514649fb
version 3
backing_file_offset 0x0
diff --git a/tests/qemu-iotests/106 b/tests/qemu-iotests/106
index ae0fc46..5554843 100755
--- a/tests/qemu-iotests/106
+++ b/tests/qemu-iotests/106
@@ -40,6 +40,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt raw
_supported_proto file fuse
_supported_os Linux
+_require_disk_usage
# in kB
CREATION_SIZE=128
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125
index 46279d6..708e7c5 100755
--- a/tests/qemu-iotests/125
+++ b/tests/qemu-iotests/125
@@ -35,7 +35,7 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
get_image_size_on_host()
{
- echo $(($(stat -c '%b * %B' "$TEST_IMG_FILE")))
+ disk_usage "$TEST_IMG_FILE"
}
# get standard environment and filters
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
index 86377c8..e19df5b 100644
--- a/tests/qemu-iotests/137.out
+++ b/tests/qemu-iotests/137.out
@@ -35,7 +35,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
-./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
+./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
OK: Dirty bit not set
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: Parameter 'lazy-refcounts' expects 'on' or 'off'
diff --git a/tests/qemu-iotests/147 b/tests/qemu-iotests/147
index 6d6f077..3e14bd3 100755
--- a/tests/qemu-iotests/147
+++ b/tests/qemu-iotests/147
@@ -277,6 +277,7 @@ class BuiltinNBD(NBDBlockdevAddBase):
} }
self.client_test(filename, flatten_sock_addr(address), 'nbd-export')
+ sockfd.close()
self._server_down()
diff --git a/tests/qemu-iotests/151 b/tests/qemu-iotests/151
index f2ff9c5..06ee358 100755
--- a/tests/qemu-iotests/151
+++ b/tests/qemu-iotests/151
@@ -263,6 +263,11 @@ class TestThrottledWithNbdExportBase(iotests.QMPTestCase):
break
except subprocess.TimeoutExpired:
self.vm.qtest(f'clock_step {1 * 1000 * 1000 * 1000}')
+ try:
+ p.kill()
+ p.stdout.close()
+ except:
+ pass
except IndexError:
pass
diff --git a/tests/qemu-iotests/153 b/tests/qemu-iotests/153
index 9bc3be8..1e02f6a 100755
--- a/tests/qemu-iotests/153
+++ b/tests/qemu-iotests/153
@@ -63,7 +63,7 @@ _supported_proto file
_run_cmd()
{
echo
- (echo "$@"; "$@" 2>&1 1>/dev/null) | _filter_testdir
+ (echo "$@"; "$@" 2>&1 1>/dev/null) | _filter_testdir | _filter_qemu_img
}
_do_run_qemu()
diff --git a/tests/qemu-iotests/153.out b/tests/qemu-iotests/153.out
index ff8e558..28e1a22 100644
--- a/tests/qemu-iotests/153.out
+++ b/tests/qemu-iotests/153.out
@@ -120,16 +120,16 @@ _qemu_img_wrapper compare -U TEST_DIR/t.qcow2 TEST_DIR/t.qcow2
_qemu_img_wrapper map -U TEST_DIR/t.qcow2
_qemu_img_wrapper amend -o size=32M -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img amend: invalid option -- 'U'
+Try 'qemu-img amend --help' for more information
_qemu_img_wrapper commit -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img commit: invalid option -- 'U'
+Try 'qemu-img commit --help' for more information
_qemu_img_wrapper resize -U TEST_DIR/t.qcow2 32M
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img resize: invalid option -- 'U'
+Try 'qemu-img resize --help' for more information
_qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base -F qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
@@ -244,16 +244,16 @@ _qemu_img_wrapper compare -U TEST_DIR/t.qcow2 TEST_DIR/t.qcow2
_qemu_img_wrapper map -U TEST_DIR/t.qcow2
_qemu_img_wrapper amend -o size=32M -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img amend: invalid option -- 'U'
+Try 'qemu-img amend --help' for more information
_qemu_img_wrapper commit -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img commit: invalid option -- 'U'
+Try 'qemu-img commit --help' for more information
_qemu_img_wrapper resize -U TEST_DIR/t.qcow2 32M
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img resize: invalid option -- 'U'
+Try 'qemu-img resize --help' for more information
_qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base -F qcow2
qemu-img: Could not open 'TEST_DIR/t.qcow2': Failed to get "write" lock
@@ -349,16 +349,16 @@ _qemu_img_wrapper compare -U TEST_DIR/t.qcow2 TEST_DIR/t.qcow2
_qemu_img_wrapper map -U TEST_DIR/t.qcow2
_qemu_img_wrapper amend -o size=32M -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img amend: invalid option -- 'U'
+Try 'qemu-img amend --help' for more information
_qemu_img_wrapper commit -U TEST_DIR/t.qcow2
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img commit: invalid option -- 'U'
+Try 'qemu-img commit --help' for more information
_qemu_img_wrapper resize -U TEST_DIR/t.qcow2 32M
-qemu-img: unrecognized option '-U'
-Try 'qemu-img --help' for more information
+qemu-img resize: invalid option -- 'U'
+Try 'qemu-img resize --help' for more information
_qemu_img_wrapper rebase -U TEST_DIR/t.qcow2 -b TEST_DIR/t.qcow2.base -F qcow2
diff --git a/tests/qemu-iotests/175 b/tests/qemu-iotests/175
index f74f053..bbbf550 100755
--- a/tests/qemu-iotests/175
+++ b/tests/qemu-iotests/175
@@ -77,6 +77,7 @@ _supported_os Linux
_default_cache_mode none
_supported_cache_modes none directsync
+_require_disk_usage
size=$((1 * 1024 * 1024))
diff --git a/tests/qemu-iotests/178 b/tests/qemu-iotests/178
index 8df241e..463c59a 100755
--- a/tests/qemu-iotests/178
+++ b/tests/qemu-iotests/178
@@ -58,7 +58,7 @@ $QEMU_IMG measure -f qcow2 # missing filename
$QEMU_IMG measure -l snap1 # missing filename
$QEMU_IMG measure -o , # invalid option list
$QEMU_IMG measure -l snapshot.foo=bar # invalid snapshot option
-$QEMU_IMG measure --output foo # invalid output format
+$QEMU_IMG measure --output foo 2>&1 | _filter_qemu_img # invalid output format
$QEMU_IMG measure --size -1 # invalid image size
$QEMU_IMG measure -O foo "$TEST_IMG" # unknown image file format
diff --git a/tests/qemu-iotests/178.out.qcow2 b/tests/qemu-iotests/178.out.qcow2
index fe193fd..61506b5 100644
--- a/tests/qemu-iotests/178.out.qcow2
+++ b/tests/qemu-iotests/178.out.qcow2
@@ -12,7 +12,8 @@ qemu-img: --image-opts, -f, and -l require a filename argument.
qemu-img: Invalid option list: ,
qemu-img: Invalid parameter 'snapshot.foo'
qemu-img: Failed in parsing snapshot param 'snapshot.foo=bar'
-qemu-img: --output must be used with human or json as argument.
+qemu-img: --output expects 'human' or 'json', not 'foo'
+Try 'qemu-img measure --help' for more information
qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
qemu-img: Unknown file format 'foo'
diff --git a/tests/qemu-iotests/178.out.raw b/tests/qemu-iotests/178.out.raw
index 445e460..6d994a4 100644
--- a/tests/qemu-iotests/178.out.raw
+++ b/tests/qemu-iotests/178.out.raw
@@ -12,7 +12,8 @@ qemu-img: --image-opts, -f, and -l require a filename argument.
qemu-img: Invalid option list: ,
qemu-img: Invalid parameter 'snapshot.foo'
qemu-img: Failed in parsing snapshot param 'snapshot.foo=bar'
-qemu-img: --output must be used with human or json as argument.
+qemu-img: --output expects 'human' or 'json', not 'foo'
+Try 'qemu-img measure --help' for more information
qemu-img: Invalid image size specified. Must be between 0 and 9223372036854775807.
qemu-img: Unknown file format 'foo'
diff --git a/tests/qemu-iotests/184.out b/tests/qemu-iotests/184.out
index 52692b6..ef99bb2 100644
--- a/tests/qemu-iotests/184.out
+++ b/tests/qemu-iotests/184.out
@@ -41,6 +41,12 @@ Testing:
},
"iops_wr": 0,
"ro": false,
+ "children": [
+ {
+ "node-name": "disk0",
+ "child": "file"
+ }
+ ],
"node-name": "throttle0",
"backing_file_depth": 1,
"drv": "throttle",
@@ -69,6 +75,8 @@ Testing:
},
"iops_wr": 0,
"ro": false,
+ "children": [
+ ],
"node-name": "disk0",
"backing_file_depth": 0,
"drv": "null-co",
diff --git a/tests/qemu-iotests/221 b/tests/qemu-iotests/221
index c463fd4..eba00b8 100755
--- a/tests/qemu-iotests/221
+++ b/tests/qemu-iotests/221
@@ -41,6 +41,7 @@ _supported_os Linux
_default_cache_mode writeback
_supported_cache_modes writeback writethrough unsafe
+_require_disk_usage
echo
echo "=== Check mapping of unaligned raw image ==="
diff --git a/tests/qemu-iotests/240 b/tests/qemu-iotests/240
index 9b281e1..f8af9ff 100755
--- a/tests/qemu-iotests/240
+++ b/tests/qemu-iotests/240
@@ -81,8 +81,6 @@ class TestCase(iotests.QMPTestCase):
self.vm.qmp_log('device_del', id='scsi-hd0')
self.vm.event_wait('DEVICE_DELETED')
- self.vm.qmp_log('device_add', id='scsi-hd1', driver='scsi-hd', drive='hd0', bus="scsi1.0")
-
self.vm.qmp_log('device_del', id='scsi-hd1')
self.vm.event_wait('DEVICE_DELETED')
self.vm.qmp_log('blockdev-del', node_name='hd0')
diff --git a/tests/qemu-iotests/240.out b/tests/qemu-iotests/240.out
index 89ed25e..10dcc42 100644
--- a/tests/qemu-iotests/240.out
+++ b/tests/qemu-iotests/240.out
@@ -46,10 +46,8 @@
{"execute": "device_add", "arguments": {"bus": "scsi0.0", "drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd0"}}
{"return": {}}
{"execute": "device_add", "arguments": {"bus": "scsi1.0", "drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd1"}}
-{"error": {"class": "GenericError", "desc": "Cannot change iothread of active block backend"}}
-{"execute": "device_del", "arguments": {"id": "scsi-hd0"}}
{"return": {}}
-{"execute": "device_add", "arguments": {"bus": "scsi1.0", "drive": "hd0", "driver": "scsi-hd", "id": "scsi-hd1"}}
+{"execute": "device_del", "arguments": {"id": "scsi-hd0"}}
{"return": {}}
{"execute": "device_del", "arguments": {"id": "scsi-hd1"}}
{"return": {}}
diff --git a/tests/qemu-iotests/253 b/tests/qemu-iotests/253
index 35039d2..6da85e6 100755
--- a/tests/qemu-iotests/253
+++ b/tests/qemu-iotests/253
@@ -41,6 +41,7 @@ _supported_os Linux
_default_cache_mode none
_supported_cache_modes none directsync
+_require_disk_usage
echo
echo "=== Check mapping of unaligned raw image ==="
diff --git a/tests/qemu-iotests/308 b/tests/qemu-iotests/308
index ea81dc4..6eced3a 100755
--- a/tests/qemu-iotests/308
+++ b/tests/qemu-iotests/308
@@ -51,6 +51,7 @@ _unsupported_fmt vpc
_supported_proto file # We create the FUSE export manually
_supported_os Linux # We need /dev/urandom
+_require_disk_usage
# $1: Export ID
# $2: Options (beyond the node-name and ID)
@@ -290,7 +291,7 @@ echo '--- Try growing non-growable export ---'
# Get the current size so we can write beyond the EOF
orig_len=$(get_proto_len "$EXT_MP" "$TEST_IMG")
-orig_disk_usage=$(stat -c '%b' "$TEST_IMG")
+orig_disk_usage=$(disk_usage "$TEST_IMG")
# Should fail (exports are non-growable by default)
# (Note that qemu-io can never write beyond the EOF, so we have to use
@@ -312,7 +313,7 @@ else
echo 'OK: Post-truncate image size is as expected'
fi
-new_disk_usage=$(stat -c '%b' "$TEST_IMG")
+new_disk_usage=$(disk_usage "$TEST_IMG")
if [ "$new_disk_usage" -gt "$orig_disk_usage" ]; then
echo 'OK: Disk usage grew with fallocate'
else
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 545f9ec..d9b7c1d 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -21,6 +21,7 @@ import sys
import argparse
import shutil
from pathlib import Path
+import warnings
from findtests import TestFinder
from testenv import TestEnv
@@ -137,6 +138,9 @@ def make_argparser() -> argparse.ArgumentParser:
if __name__ == '__main__':
+ warnings.simplefilter("default")
+ os.environ["PYTHONWARNINGS"] = "default"
+
args = make_argparser().parse_args()
env = TestEnv(source_dir=args.source_dir,
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index fc3c64b..511a55b 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -74,7 +74,7 @@ _filter_qemu_io()
{
_filter_win32 | \
gsed -e "s/[0-9]* ops\; [0-9/:. sec]* ([0-9/.inf]* [EPTGMKiBbytes]*\/sec and [0-9/.inf]* ops\/sec)/X ops\; XX:XX:XX.X (XXX YYY\/sec and XXX ops\/sec)/" \
- -e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\)/:\1/" \
+ -e "s/: line [0-9][0-9]*: *[0-9][0-9]*\( Aborted\| Killed\) \{2,\}/:\1 /" \
-e "s/qemu-io> //g"
}
@@ -86,6 +86,12 @@ _filter_qemu()
-e $'s#\r##' # QEMU monitor uses \r\n line endings
}
+# replace occurrences of QEMU_IMG_PROG with "qemu-img"
+_filter_qemu_img()
+{
+ sed -e "s#$QEMU_IMG_PROG#qemu-img#g"
+}
+
# replace problematic QMP output like timestamps
_filter_qmp()
{
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 237f746..e977cb4 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -996,6 +996,36 @@ _require_large_file()
rm "$FILENAME"
}
+# Check whether disk_usage can be reliably used.
+_require_disk_usage()
+{
+ local unusable=false
+ # ZFS triggers known failures on this front; it does not immediately
+ # allocate files, and then aggressively compresses writes even when full
+ # allocation was requested.
+ if [ -z "$TEST_IMG_FILE" ]; then
+ FILENAME="$TEST_IMG"
+ else
+ FILENAME="$TEST_IMG_FILE"
+ fi
+ if [ -e "FILENAME" ]; then
+ echo "unwilling to overwrite existing file"
+ exit 1
+ fi
+ $QEMU_IMG create -f raw "$FILENAME" 5M > /dev/null
+ if [ $(disk_usage "$FILENAME") -gt $((1024*1024)) ]; then
+ unusable=true
+ fi
+ $QEMU_IMG create -f raw -o preallocation=full "$FILENAME" 5M > /dev/null
+ if [ $(disk_usage "$FILENAME") -lt $((4*1024*1024)) ]; then
+ unusable=true
+ fi
+ rm -f "$FILENAME"
+ if $unusable; then
+ _notrun "file system on $TEST_DIR does not handle sparse files nicely"
+ fi
+}
+
# Check that a set of devices is available in the QEMU binary
#
_require_devices()
diff --git a/tests/qemu-iotests/testenv.py b/tests/qemu-iotests/testenv.py
index 6326e46..29caaa8 100644
--- a/tests/qemu-iotests/testenv.py
+++ b/tests/qemu-iotests/testenv.py
@@ -22,15 +22,12 @@ import tempfile
from pathlib import Path
import shutil
import collections
+import contextlib
import random
import subprocess
import glob
from typing import List, Dict, Any, Optional
-if sys.version_info >= (3, 9):
- from contextlib import AbstractContextManager as ContextManager
-else:
- from typing import ContextManager
DEF_GDB_OPTIONS = 'localhost:12345'
@@ -58,7 +55,7 @@ def get_default_machine(qemu_prog: str) -> str:
return default_machine
-class TestEnv(ContextManager['TestEnv']):
+class TestEnv(contextlib.AbstractContextManager['TestEnv']):
"""
Manage system environment for running tests
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index 2e236c8..14cc849 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -30,11 +30,6 @@ from multiprocessing import Pool
from typing import List, Optional, Any, Sequence, Dict
from testenv import TestEnv
-if sys.version_info >= (3, 9):
- from contextlib import AbstractContextManager as ContextManager
-else:
- from typing import ContextManager
-
def silent_unlink(path: Path) -> None:
try:
@@ -57,7 +52,7 @@ def file_diff(file1: str, file2: str) -> List[str]:
return res
-class LastElapsedTime(ContextManager['LastElapsedTime']):
+class LastElapsedTime(contextlib.AbstractContextManager['LastElapsedTime']):
""" Cache for elapsed time for tests, to show it during new test run
It is safe to use get() at any time. To use update(), you must either
@@ -112,7 +107,7 @@ class TestResult:
self.interrupted = interrupted
-class TestRunner(ContextManager['TestRunner']):
+class TestRunner(contextlib.AbstractContextManager['TestRunner']):
shared_self = None
@staticmethod
diff --git a/tests/qemu-iotests/tests/graph-changes-while-io b/tests/qemu-iotests/tests/graph-changes-while-io
index 194fda5..dca1167 100755
--- a/tests/qemu-iotests/tests/graph-changes-while-io
+++ b/tests/qemu-iotests/tests/graph-changes-while-io
@@ -27,6 +27,7 @@ from iotests import imgfmt, qemu_img, qemu_img_create, qemu_io, \
top = os.path.join(iotests.test_dir, 'top.img')
+mid = os.path.join(iotests.test_dir, 'mid.img')
nbd_sock = os.path.join(iotests.sock_dir, 'nbd.sock')
@@ -57,6 +58,16 @@ class TestGraphChangesWhileIO(QMPTestCase):
def tearDown(self) -> None:
self.qsd.stop()
+ os.remove(top)
+
+ def _wait_for_blockjob(self, status: str) -> None:
+ done = False
+ while not done:
+ for event in self.qsd.get_qmp().get_events(wait=10.0):
+ if event['event'] != 'JOB_STATUS_CHANGE':
+ continue
+ if event['data']['status'] == status:
+ done = True
def test_blockdev_add_while_io(self) -> None:
# Run qemu-img bench in the background
@@ -116,15 +127,92 @@ class TestGraphChangesWhileIO(QMPTestCase):
'device': 'job0',
})
- cancelled = False
- while not cancelled:
- for event in self.qsd.get_qmp().get_events(wait=10.0):
- if event['event'] != 'JOB_STATUS_CHANGE':
- continue
- if event['data']['status'] == 'null':
- cancelled = True
+ self._wait_for_blockjob('null')
+
+ bench_thr.join()
+
+ def test_remove_lower_snapshot_while_io(self) -> None:
+ # Run qemu-img bench in the background
+ bench_thr = Thread(target=do_qemu_img_bench, args=(100000, ))
+ bench_thr.start()
+
+ # While I/O is performed on 'node0' node, consequently add 2 snapshots
+ # on top of it, then remove (commit) them starting from lower one.
+ while bench_thr.is_alive():
+ # Recreate snapshot images on every iteration
+ qemu_img_create('-f', imgfmt, mid, '1G')
+ qemu_img_create('-f', imgfmt, top, '1G')
+
+ self.qsd.cmd('blockdev-add', {
+ 'driver': imgfmt,
+ 'node-name': 'mid',
+ 'file': {
+ 'driver': 'file',
+ 'filename': mid
+ }
+ })
+
+ self.qsd.cmd('blockdev-snapshot', {
+ 'node': 'node0',
+ 'overlay': 'mid',
+ })
+
+ self.qsd.cmd('blockdev-add', {
+ 'driver': imgfmt,
+ 'node-name': 'top',
+ 'file': {
+ 'driver': 'file',
+ 'filename': top
+ }
+ })
+
+ self.qsd.cmd('blockdev-snapshot', {
+ 'node': 'mid',
+ 'overlay': 'top',
+ })
+
+ self.qsd.cmd('block-commit', {
+ 'job-id': 'commit-mid',
+ 'device': 'top',
+ 'top-node': 'mid',
+ 'base-node': 'node0',
+ 'auto-finalize': True,
+ 'auto-dismiss': False,
+ })
+
+ self._wait_for_blockjob('concluded')
+ self.qsd.cmd('job-dismiss', {
+ 'id': 'commit-mid',
+ })
+
+ self.qsd.cmd('block-commit', {
+ 'job-id': 'commit-top',
+ 'device': 'top',
+ 'top-node': 'top',
+ 'base-node': 'node0',
+ 'auto-finalize': True,
+ 'auto-dismiss': False,
+ })
+
+ self._wait_for_blockjob('ready')
+ self.qsd.cmd('job-complete', {
+ 'id': 'commit-top',
+ })
+
+ self._wait_for_blockjob('concluded')
+ self.qsd.cmd('job-dismiss', {
+ 'id': 'commit-top',
+ })
+
+ self.qsd.cmd('blockdev-del', {
+ 'node-name': 'mid'
+ })
+ self.qsd.cmd('blockdev-del', {
+ 'node-name': 'top'
+ })
bench_thr.join()
+ os.remove(mid)
if __name__ == '__main__':
# Format must support raw backing files
diff --git a/tests/qemu-iotests/tests/graph-changes-while-io.out b/tests/qemu-iotests/tests/graph-changes-while-io.out
index fbc63e6..8d7e9967 100644
--- a/tests/qemu-iotests/tests/graph-changes-while-io.out
+++ b/tests/qemu-iotests/tests/graph-changes-while-io.out
@@ -1,5 +1,5 @@
-..
+...
----------------------------------------------------------------------
-Ran 2 tests
+Ran 3 tests
OK
diff --git a/tests/qemu-iotests/tests/mirror-sparse b/tests/qemu-iotests/tests/mirror-sparse
index 8c52a4e..ee7101b 100755
--- a/tests/qemu-iotests/tests/mirror-sparse
+++ b/tests/qemu-iotests/tests/mirror-sparse
@@ -40,6 +40,8 @@ cd ..
_supported_fmt qcow2 raw # Format of the source. dst is always raw file
_supported_proto file
_supported_os Linux
+_require_o_direct
+_require_disk_usage
echo
echo "=== Initial image setup ==="
@@ -96,13 +98,15 @@ _send_qemu_cmd $h1 '{"execute": "blockdev-del", "arguments":
{"node-name": "dst"}}' 'return' \
| _filter_block_job_offset | _filter_block_job_len
$QEMU_IMG compare -U -f $IMGFMT -F raw $TEST_IMG.base $TEST_IMG
+# Some filesystems can fudge allocations for various reasons; rather
+# than expecting precise 2M and 20M images, it is better to allow for slop.
result=$(disk_usage $TEST_IMG)
-if test $result -lt $((3*1024*1024)); then
+if test $result -lt $((4*1024*1024)); then
actual=sparse
-elif test $result = $((20*1024*1024)); then
+elif test $result -gt $((19*1024*1024)); then
actual=full
else
- actual=unknown
+ actual="unexpected size ($result)"
fi
echo "Destination is $actual; expected $expected"
}
diff --git a/tests/qemu-iotests/tests/qom-set-drive b/tests/qemu-iotests/tests/qom-set-drive
new file mode 100755
index 0000000..ec8ddac
--- /dev/null
+++ b/tests/qemu-iotests/tests/qom-set-drive
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+# group: quick
+#
+# Test how changing the 'drive' property via 'qom-set' behaves.
+#
+# Copyright (C) Proxmox Server Solutions GmbH
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import iotests
+from iotests import imgfmt, log, qemu_img_create, QMPTestCase
+
+image_size = 1 * 1024 * 1024
+images = [os.path.join(iotests.test_dir, f'{i}.img') for i in range(0, 4)]
+
+class TestQOMSetDrive(QMPTestCase):
+ def setUp(self) -> None:
+ for image in images:
+ qemu_img_create('-f', imgfmt, image, str(image_size))
+
+ self.vm = iotests.VM()
+ for i, image in enumerate(images):
+ self.vm.add_blockdev(self.vm.qmp_to_opts({
+ 'driver': imgfmt,
+ 'node-name': f'node{i}',
+ 'file': {
+ 'driver': 'file',
+ 'filename': image,
+ }
+ }))
+ self.vm.add_object('iothread,id=iothread0')
+ self.vm.add_device('virtio-scsi,iothread=iothread0')
+ self.vm.add_device('scsi-hd,id=iot,drive=node0')
+ self.vm.add_device('virtio-scsi')
+ self.vm.add_device('scsi-hd,id=no-iot,drive=node1')
+ self.vm.launch()
+
+ def tearDown(self) -> None:
+ self.vm.shutdown()
+ for image in images:
+ os.remove(image)
+
+ def test_qom_set_drive(self) -> None:
+ log(self.vm.qmp('qom-get', path='/machine/peripheral/iot',
+ property='drive'))
+ log(self.vm.qmp('qom-set', path='/machine/peripheral/iot',
+ property='drive', value='node2'))
+ log(self.vm.qmp('qom-get', path='/machine/peripheral/iot',
+ property='drive'))
+
+ log(self.vm.qmp('qom-get', path='/machine/peripheral/no-iot',
+ property='drive'))
+ log(self.vm.qmp('qom-set', path='/machine/peripheral/no-iot',
+ property='drive', value='node3'))
+ log(self.vm.qmp('qom-get', path='/machine/peripheral/no-iot',
+ property='drive'))
+
+if __name__ == '__main__':
+ iotests.activate_logging()
+ # LUKS would require special key-secret handling in add_blockdevs()
+ iotests.main(supported_fmts=['generic'],
+ unsupported_fmts=['luks'])
diff --git a/tests/qemu-iotests/tests/qom-set-drive.out b/tests/qemu-iotests/tests/qom-set-drive.out
new file mode 100644
index 0000000..7fc243d
--- /dev/null
+++ b/tests/qemu-iotests/tests/qom-set-drive.out
@@ -0,0 +1,11 @@
+{"return": "node0"}
+{"error": {"class": "GenericError", "desc": "Different aio context is not supported for new node"}}
+{"return": "node0"}
+{"return": "node1"}
+{"return": {}}
+{"return": "node3"}
+.
+----------------------------------------------------------------------
+Ran 1 tests
+
+OK
diff --git a/tests/qemu-iotests/tests/write-zeroes-unmap b/tests/qemu-iotests/tests/write-zeroes-unmap
index 7cfeeaf..f90fb8e 100755
--- a/tests/qemu-iotests/tests/write-zeroes-unmap
+++ b/tests/qemu-iotests/tests/write-zeroes-unmap
@@ -32,6 +32,7 @@ cd ..
_supported_fmt raw
_supported_proto file
_supported_os Linux
+_require_disk_usage
create_test_image() {
_make_test_img -f $IMGFMT 1m
diff --git a/tests/qtest/aspeed-hace-utils.c b/tests/qtest/aspeed-hace-utils.c
new file mode 100644
index 0000000..0f7f911
--- /dev/null
+++ b/tests/qtest/aspeed-hace-utils.c
@@ -0,0 +1,646 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
+
+/*
+ * Test vector is the ascii "abc"
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ * echo -n -e 'abc' | dd of=/tmp/test
+ * for hash in sha512sum sha384sum sha256sum md5sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector[3] = {0x61, 0x62, 0x63};
+
+static const uint8_t test_result_sha512[64] = {
+ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
+ 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+ 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
+ 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
+ 0xa5, 0x4c, 0xa4, 0x9f};
+
+static const uint8_t test_result_sha384[48] = {
+ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
+ 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+ 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
+ 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
+
+static const uint8_t test_result_sha256[32] = {
+ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+ 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+ 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+
+static const uint8_t test_result_md5[16] = {
+ 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
+ 0x28, 0xe1, 0x7f, 0x72};
+
+/*
+ * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
+ * into blocks of 3 characters as shown
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ * echo -n -e 'abcdefghijkl' | dd of=/tmp/test
+ * for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
+ *
+ */
+static const uint8_t test_vector_sg1[6] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
+static const uint8_t test_vector_sg2[3] = {0x67, 0x68, 0x69};
+static const uint8_t test_vector_sg3[3] = {0x6a, 0x6b, 0x6c};
+
+static const uint8_t test_result_sg_sha512[64] = {
+ 0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
+ 0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
+ 0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
+ 0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
+ 0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
+ 0xf8, 0x6d, 0xda, 0x2e};
+
+static const uint8_t test_result_sg_sha384[48] = {
+ 0x10, 0x3c, 0xa9, 0x6c, 0x06, 0xa1, 0xce, 0x79, 0x8f, 0x08, 0xf8, 0xef,
+ 0xf0, 0xdf, 0xb0, 0xcc, 0xdb, 0x56, 0x7d, 0x48, 0xb2, 0x85, 0xb2, 0x3d,
+ 0x0c, 0xd7, 0x73, 0x45, 0x46, 0x67, 0xa3, 0xc2, 0xfa, 0x5f, 0x1b, 0x58,
+ 0xd9, 0xcd, 0xf2, 0x32, 0x9b, 0xd9, 0x97, 0x97, 0x30, 0xbf, 0xaa, 0xff};
+
+static const uint8_t test_result_sg_sha256[32] = {
+ 0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
+ 0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
+ 0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
+
+/*
+ * The accumulative mode requires firmware to provide internal initial state
+ * and message padding (including length L at the end of padding).
+ *
+ * This test vector is a ascii text "abc" with padding message.
+ *
+ * Expected results were generated using command line utitiles:
+ *
+ * echo -n -e 'abc' | dd of=/tmp/test
+ * for hash in sha512sum sha384sum sha256sum; do $hash /tmp/test; done
+ */
+static const uint8_t test_vector_accum_512[128] = {
+ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
+static const uint8_t test_vector_accum_384[128] = {
+ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
+static const uint8_t test_vector_accum_256[64] = {
+ 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
+
+static const uint8_t test_result_accum_sha512[64] = {
+ 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
+ 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
+ 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
+ 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
+ 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
+ 0xa5, 0x4c, 0xa4, 0x9f};
+
+static const uint8_t test_result_accum_sha384[48] = {
+ 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, 0xb5, 0xa0, 0x3d, 0x69,
+ 0x9a, 0xc6, 0x50, 0x07, 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63,
+ 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, 0x80, 0x86, 0x07, 0x2b,
+ 0xa1, 0xe7, 0xcc, 0x23, 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7};
+
+static const uint8_t test_result_accum_sha256[32] = {
+ 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
+ 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
+ 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+
+static void write_regs(QTestState *s, uint32_t base, uint64_t src,
+ uint32_t length, uint64_t out, uint32_t method)
+{
+ qtest_writel(s, base + HACE_HASH_SRC, extract64(src, 0, 32));
+ qtest_writel(s, base + HACE_HASH_SRC_HI, extract64(src, 32, 32));
+ qtest_writel(s, base + HACE_HASH_DIGEST, extract64(out, 0, 32));
+ qtest_writel(s, base + HACE_HASH_DIGEST_HI, extract64(out, 32, 32));
+ qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
+ qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
+}
+
+void aspeed_test_md5(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+
+{
+ QTestState *s = qtest_init(machine);
+
+ uint64_t digest_addr = src_addr + 0x010000;
+ uint8_t digest[16] = {0};
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+ write_regs(s, base, src_addr, sizeof(test_vector),
+ digest_addr, HACE_ALGO_MD5);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_md5, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha256(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t digest_addr = src_addr + 0x10000;
+ uint8_t digest[32] = {0};
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+ write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+ HACE_ALGO_SHA256);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sha256, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha384(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t digest_addr = src_addr + 0x10000;
+ uint8_t digest[48] = {0};
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+ write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+ HACE_ALGO_SHA384);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sha384, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha512(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t digest_addr = src_addr + 0x10000;
+ uint8_t digest[64] = {0};
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
+
+ write_regs(s, base, src_addr, sizeof(test_vector), digest_addr,
+ HACE_ALGO_SHA512);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sha512, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t src_addr_1 = src_addr + 0x10000;
+ const uint64_t src_addr_2 = src_addr + 0x20000;
+ const uint64_t src_addr_3 = src_addr + 0x30000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[32] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_sg1)),
+ cpu_to_le32(src_addr_1) },
+ { cpu_to_le32(sizeof(test_vector_sg2)),
+ cpu_to_le32(src_addr_2) },
+ { cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+ cpu_to_le32(src_addr_3) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+ qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+ qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr,
+ (sizeof(test_vector_sg1)
+ + sizeof(test_vector_sg2)
+ + sizeof(test_vector_sg3)),
+ digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sg_sha256, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t src_addr_1 = src_addr + 0x10000;
+ const uint64_t src_addr_2 = src_addr + 0x20000;
+ const uint64_t src_addr_3 = src_addr + 0x30000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[48] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_sg1)),
+ cpu_to_le32(src_addr_1) },
+ { cpu_to_le32(sizeof(test_vector_sg2)),
+ cpu_to_le32(src_addr_2) },
+ { cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+ cpu_to_le32(src_addr_3) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+ qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+ qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr,
+ (sizeof(test_vector_sg1)
+ + sizeof(test_vector_sg2)
+ + sizeof(test_vector_sg3)),
+ digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sg_sha384, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t src_addr_1 = src_addr + 0x10000;
+ const uint64_t src_addr_2 = src_addr + 0x20000;
+ const uint64_t src_addr_3 = src_addr + 0x30000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[64] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_sg1)),
+ cpu_to_le32(src_addr_1) },
+ { cpu_to_le32(sizeof(test_vector_sg2)),
+ cpu_to_le32(src_addr_2) },
+ { cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
+ cpu_to_le32(src_addr_3) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
+ qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
+ qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr,
+ (sizeof(test_vector_sg1)
+ + sizeof(test_vector_sg2)
+ + sizeof(test_vector_sg3)),
+ digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_sg_sha512, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t buffer_addr = src_addr + 0x10000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[32] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
+ cpu_to_le32(buffer_addr) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, buffer_addr, test_vector_accum_256,
+ sizeof(test_vector_accum_256));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
+ digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_accum_sha256, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t buffer_addr = src_addr + 0x10000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[48] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_accum_384) | SG_LIST_LEN_LAST),
+ cpu_to_le32(buffer_addr) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, buffer_addr, test_vector_accum_384,
+ sizeof(test_vector_accum_384));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr, sizeof(test_vector_accum_384),
+ digest_addr, HACE_ALGO_SHA384 | HACE_SG_EN | HACE_ACCUM_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_accum_sha384, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr)
+{
+ QTestState *s = qtest_init(machine);
+
+ const uint64_t buffer_addr = src_addr + 0x10000;
+ const uint64_t digest_addr = src_addr + 0x40000;
+ uint8_t digest[64] = {0};
+ struct AspeedSgList array[] = {
+ { cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
+ cpu_to_le32(buffer_addr) },
+ };
+
+ /* Check engine is idle, no busy or irq bits set */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Write test vector into memory */
+ qtest_memwrite(s, buffer_addr, test_vector_accum_512,
+ sizeof(test_vector_accum_512));
+ qtest_memwrite(s, src_addr, array, sizeof(array));
+
+ write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
+ digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
+
+ /* Check hash IRQ status is asserted */
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
+
+ /* Clear IRQ status and check status is deasserted */
+ qtest_writel(s, base + HACE_STS, 0x00000200);
+ g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
+
+ /* Read computed digest from memory */
+ qtest_memread(s, digest_addr, digest, sizeof(digest));
+
+ /* Check result of computation */
+ g_assert_cmpmem(digest, sizeof(digest),
+ test_result_accum_sha512, sizeof(digest));
+
+ qtest_quit(s);
+}
+
+void aspeed_test_addresses(const char *machine, const uint32_t base,
+ const struct AspeedMasks *expected)
+{
+ QTestState *s = qtest_init(machine);
+
+ /*
+ * Check command mode is zero, meaning engine is in direct access mode,
+ * as this affects the masking behavior of the HASH_SRC register.
+ */
+ g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+ /* Check that the address masking is correct */
+ qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
+
+ qtest_writel(s, base + HACE_HASH_SRC_HI, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI),
+ ==, expected->src_hi);
+
+ qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==,
+ expected->dest);
+
+ qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==,
+ expected->dest_hi);
+
+ qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==,
+ expected->key);
+
+ qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==,
+ expected->key_hi);
+
+ qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==,
+ expected->len);
+
+ /* Reset to zero */
+ qtest_writel(s, base + HACE_HASH_SRC, 0);
+ qtest_writel(s, base + HACE_HASH_SRC_HI, 0);
+ qtest_writel(s, base + HACE_HASH_DIGEST, 0);
+ qtest_writel(s, base + HACE_HASH_DIGEST_HI, 0);
+ qtest_writel(s, base + HACE_HASH_KEY_BUFF, 0);
+ qtest_writel(s, base + HACE_HASH_KEY_BUFF_HI, 0);
+ qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
+
+ /* Check that all bits are now zero */
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_KEY_BUFF_HI), ==, 0);
+ g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+
+ qtest_quit(s);
+}
+
diff --git a/tests/qtest/aspeed-hace-utils.h b/tests/qtest/aspeed-hace-utils.h
new file mode 100644
index 0000000..c8b2ec4
--- /dev/null
+++ b/tests/qtest/aspeed-hace-utils.h
@@ -0,0 +1,84 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 IBM Corp.
+ */
+
+#ifndef TESTS_ASPEED_HACE_UTILS_H
+#define TESTS_ASPEED_HACE_UTILS_H
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+
+#define HACE_CMD 0x10
+#define HACE_SHA_BE_EN BIT(3)
+#define HACE_MD5_LE_EN BIT(2)
+#define HACE_ALGO_MD5 0
+#define HACE_ALGO_SHA1 BIT(5)
+#define HACE_ALGO_SHA224 BIT(6)
+#define HACE_ALGO_SHA256 (BIT(4) | BIT(6))
+#define HACE_ALGO_SHA512 (BIT(5) | BIT(6))
+#define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10))
+#define HACE_SG_EN BIT(18)
+#define HACE_ACCUM_EN BIT(8)
+
+#define HACE_STS 0x1c
+#define HACE_RSA_ISR BIT(13)
+#define HACE_CRYPTO_ISR BIT(12)
+#define HACE_HASH_ISR BIT(9)
+#define HACE_RSA_BUSY BIT(2)
+#define HACE_CRYPTO_BUSY BIT(1)
+#define HACE_HASH_BUSY BIT(0)
+#define HACE_HASH_SRC 0x20
+#define HACE_HASH_DIGEST 0x24
+#define HACE_HASH_KEY_BUFF 0x28
+#define HACE_HASH_DATA_LEN 0x2c
+#define HACE_HASH_CMD 0x30
+#define HACE_HASH_SRC_HI 0x90
+#define HACE_HASH_DIGEST_HI 0x94
+#define HACE_HASH_KEY_BUFF_HI 0x98
+
+/* Scatter-Gather Hash */
+#define SG_LIST_LEN_LAST BIT(31)
+struct AspeedSgList {
+ uint32_t len;
+ uint32_t addr;
+} __attribute__ ((__packed__));
+
+struct AspeedMasks {
+ uint32_t src;
+ uint32_t dest;
+ uint32_t key;
+ uint32_t len;
+ uint32_t src_hi;
+ uint32_t dest_hi;
+ uint32_t key_hi;
+};
+
+void aspeed_test_md5(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha256(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha384(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha512(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha256_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha384_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha512_sg(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha256_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha384_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_sha512_accum(const char *machine, const uint32_t base,
+ const uint64_t src_addr);
+void aspeed_test_addresses(const char *machine, const uint32_t base,
+ const struct AspeedMasks *expected);
+
+#endif /* TESTS_ASPEED_HACE_UTILS_H */
+
diff --git a/tests/qtest/aspeed_hace-test.c b/tests/qtest/aspeed_hace-test.c
index ce86a44..3877702 100644
--- a/tests/qtest/aspeed_hace-test.c
+++ b/tests/qtest/aspeed_hace-test.c
@@ -6,599 +6,222 @@
*/
#include "qemu/osdep.h"
-
#include "libqtest.h"
#include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
-#define HACE_CMD 0x10
-#define HACE_SHA_BE_EN BIT(3)
-#define HACE_MD5_LE_EN BIT(2)
-#define HACE_ALGO_MD5 0
-#define HACE_ALGO_SHA1 BIT(5)
-#define HACE_ALGO_SHA224 BIT(6)
-#define HACE_ALGO_SHA256 (BIT(4) | BIT(6))
-#define HACE_ALGO_SHA512 (BIT(5) | BIT(6))
-#define HACE_ALGO_SHA384 (BIT(5) | BIT(6) | BIT(10))
-#define HACE_SG_EN BIT(18)
-#define HACE_ACCUM_EN BIT(8)
-
-#define HACE_STS 0x1c
-#define HACE_RSA_ISR BIT(13)
-#define HACE_CRYPTO_ISR BIT(12)
-#define HACE_HASH_ISR BIT(9)
-#define HACE_RSA_BUSY BIT(2)
-#define HACE_CRYPTO_BUSY BIT(1)
-#define HACE_HASH_BUSY BIT(0)
-#define HACE_HASH_SRC 0x20
-#define HACE_HASH_DIGEST 0x24
-#define HACE_HASH_KEY_BUFF 0x28
-#define HACE_HASH_DATA_LEN 0x2c
-#define HACE_HASH_CMD 0x30
-/* Scatter-Gather Hash */
-#define SG_LIST_LEN_LAST BIT(31)
-struct AspeedSgList {
- uint32_t len;
- uint32_t addr;
-} __attribute__ ((__packed__));
-
-/*
- * Test vector is the ascii "abc"
- *
- * Expected results were generated using command line utitiles:
- *
- * echo -n -e 'abc' | dd of=/tmp/test
- * for hash in sha512sum sha256sum md5sum; do $hash /tmp/test; done
- *
- */
-static const uint8_t test_vector[] = {0x61, 0x62, 0x63};
-
-static const uint8_t test_result_sha512[] = {
- 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
- 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
- 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
- 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
- 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
- 0xa5, 0x4c, 0xa4, 0x9f};
+static const struct AspeedMasks ast1030_masks = {
+ .src = 0x7fffffff,
+ .dest = 0x7ffffff8,
+ .key = 0x7ffffff8,
+ .len = 0x0fffffff,
+};
-static const uint8_t test_result_sha256[] = {
- 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
- 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
- 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
+static const struct AspeedMasks ast2600_masks = {
+ .src = 0x7fffffff,
+ .dest = 0x7ffffff8,
+ .key = 0x7ffffff8,
+ .len = 0x0fffffff,
+};
-static const uint8_t test_result_md5[] = {
- 0x90, 0x01, 0x50, 0x98, 0x3c, 0xd2, 0x4f, 0xb0, 0xd6, 0x96, 0x3f, 0x7d,
- 0x28, 0xe1, 0x7f, 0x72};
+static const struct AspeedMasks ast2500_masks = {
+ .src = 0x3fffffff,
+ .dest = 0x3ffffff8,
+ .key = 0x3fffffc0,
+ .len = 0x0fffffff,
+};
-/*
- * The Scatter-Gather Test vector is the ascii "abc" "def" "ghi", broken
- * into blocks of 3 characters as shown
- *
- * Expected results were generated using command line utitiles:
- *
- * echo -n -e 'abcdefghijkl' | dd of=/tmp/test
- * for hash in sha512sum sha256sum; do $hash /tmp/test; done
- *
- */
-static const uint8_t test_vector_sg1[] = {0x61, 0x62, 0x63, 0x64, 0x65, 0x66};
-static const uint8_t test_vector_sg2[] = {0x67, 0x68, 0x69};
-static const uint8_t test_vector_sg3[] = {0x6a, 0x6b, 0x6c};
-
-static const uint8_t test_result_sg_sha512[] = {
- 0x17, 0x80, 0x7c, 0x72, 0x8e, 0xe3, 0xba, 0x35, 0xe7, 0xcf, 0x7a, 0xf8,
- 0x23, 0x11, 0x6d, 0x26, 0xe4, 0x1e, 0x5d, 0x4d, 0x6c, 0x2f, 0xf1, 0xf3,
- 0x72, 0x0d, 0x3d, 0x96, 0xaa, 0xcb, 0x6f, 0x69, 0xde, 0x64, 0x2e, 0x63,
- 0xd5, 0xb7, 0x3f, 0xc3, 0x96, 0xc1, 0x2b, 0xe3, 0x8b, 0x2b, 0xd5, 0xd8,
- 0x84, 0x25, 0x7c, 0x32, 0xc8, 0xf6, 0xd0, 0x85, 0x4a, 0xe6, 0xb5, 0x40,
- 0xf8, 0x6d, 0xda, 0x2e};
-
-static const uint8_t test_result_sg_sha256[] = {
- 0xd6, 0x82, 0xed, 0x4c, 0xa4, 0xd9, 0x89, 0xc1, 0x34, 0xec, 0x94, 0xf1,
- 0x55, 0x1e, 0x1e, 0xc5, 0x80, 0xdd, 0x6d, 0x5a, 0x6e, 0xcd, 0xe9, 0xf3,
- 0xd3, 0x5e, 0x6e, 0x4a, 0x71, 0x7f, 0xbd, 0xe4};
+static const struct AspeedMasks ast2400_masks = {
+ .src = 0x0fffffff,
+ .dest = 0x0ffffff8,
+ .key = 0x0fffffc0,
+ .len = 0x0fffffff,
+};
-/*
- * The accumulative mode requires firmware to provide internal initial state
- * and message padding (including length L at the end of padding).
- *
- * This test vector is a ascii text "abc" with padding message.
- *
- * Expected results were generated using command line utitiles:
- *
- * echo -n -e 'abc' | dd of=/tmp/test
- * for hash in sha512sum sha256sum; do $hash /tmp/test; done
- */
-static const uint8_t test_vector_accum_512[] = {
- 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
-
-static const uint8_t test_vector_accum_256[] = {
- 0x61, 0x62, 0x63, 0x80, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18};
-
-static const uint8_t test_result_accum_sha512[] = {
- 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, 0xcc, 0x41, 0x73, 0x49,
- 0xae, 0x20, 0x41, 0x31, 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2,
- 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, 0x21, 0x92, 0x99, 0x2a,
- 0x27, 0x4f, 0xc1, 0xa8, 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd,
- 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, 0x2a, 0x9a, 0xc9, 0x4f,
- 0xa5, 0x4c, 0xa4, 0x9f};
-
-static const uint8_t test_result_accum_sha256[] = {
- 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, 0x41, 0x41, 0x40, 0xde,
- 0x5d, 0xae, 0x22, 0x23, 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c,
- 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad};
-
-static void write_regs(QTestState *s, uint32_t base, uint32_t src,
- uint32_t length, uint32_t out, uint32_t method)
+/* ast1030 */
+static void test_md5_ast1030(void)
{
- qtest_writel(s, base + HACE_HASH_SRC, src);
- qtest_writel(s, base + HACE_HASH_DIGEST, out);
- qtest_writel(s, base + HACE_HASH_DATA_LEN, length);
- qtest_writel(s, base + HACE_HASH_CMD, HACE_SHA_BE_EN | method);
+ aspeed_test_md5("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_md5(const char *machine, const uint32_t base,
- const uint32_t src_addr)
-
+static void test_sha256_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- uint32_t digest_addr = src_addr + 0x01000000;
- uint8_t digest[16] = {0};
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
- write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_MD5);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_md5, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha256("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha256(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha256_sg_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t digest_addr = src_addr + 0x1000000;
- uint8_t digest[32] = {0};
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
- write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA256);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_sha256, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha256_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha512(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha384_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t digest_addr = src_addr + 0x1000000;
- uint8_t digest[64] = {0};
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, src_addr, test_vector, sizeof(test_vector));
-
- write_regs(s, base, src_addr, sizeof(test_vector), digest_addr, HACE_ALGO_SHA512);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_sha512, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha384("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha256_sg(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha384_sg_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t src_addr_1 = src_addr + 0x1000000;
- const uint32_t src_addr_2 = src_addr + 0x2000000;
- const uint32_t src_addr_3 = src_addr + 0x3000000;
- const uint32_t digest_addr = src_addr + 0x4000000;
- uint8_t digest[32] = {0};
- struct AspeedSgList array[] = {
- { cpu_to_le32(sizeof(test_vector_sg1)),
- cpu_to_le32(src_addr_1) },
- { cpu_to_le32(sizeof(test_vector_sg2)),
- cpu_to_le32(src_addr_2) },
- { cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
- cpu_to_le32(src_addr_3) },
- };
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
- qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
- qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
- qtest_memwrite(s, src_addr, array, sizeof(array));
-
- write_regs(s, base, src_addr,
- (sizeof(test_vector_sg1)
- + sizeof(test_vector_sg2)
- + sizeof(test_vector_sg3)),
- digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_sg_sha256, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha384_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha512_sg(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha512_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t src_addr_1 = src_addr + 0x1000000;
- const uint32_t src_addr_2 = src_addr + 0x2000000;
- const uint32_t src_addr_3 = src_addr + 0x3000000;
- const uint32_t digest_addr = src_addr + 0x4000000;
- uint8_t digest[64] = {0};
- struct AspeedSgList array[] = {
- { cpu_to_le32(sizeof(test_vector_sg1)),
- cpu_to_le32(src_addr_1) },
- { cpu_to_le32(sizeof(test_vector_sg2)),
- cpu_to_le32(src_addr_2) },
- { cpu_to_le32(sizeof(test_vector_sg3) | SG_LIST_LEN_LAST),
- cpu_to_le32(src_addr_3) },
- };
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, src_addr_1, test_vector_sg1, sizeof(test_vector_sg1));
- qtest_memwrite(s, src_addr_2, test_vector_sg2, sizeof(test_vector_sg2));
- qtest_memwrite(s, src_addr_3, test_vector_sg3, sizeof(test_vector_sg3));
- qtest_memwrite(s, src_addr, array, sizeof(array));
-
- write_regs(s, base, src_addr,
- (sizeof(test_vector_sg1)
- + sizeof(test_vector_sg2)
- + sizeof(test_vector_sg3)),
- digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_sg_sha512, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha512("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha256_accum(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha512_sg_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t buffer_addr = src_addr + 0x1000000;
- const uint32_t digest_addr = src_addr + 0x4000000;
- uint8_t digest[32] = {0};
- struct AspeedSgList array[] = {
- { cpu_to_le32(sizeof(test_vector_accum_256) | SG_LIST_LEN_LAST),
- cpu_to_le32(buffer_addr) },
- };
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, buffer_addr, test_vector_accum_256,
- sizeof(test_vector_accum_256));
- qtest_memwrite(s, src_addr, array, sizeof(array));
-
- write_regs(s, base, src_addr, sizeof(test_vector_accum_256),
- digest_addr, HACE_ALGO_SHA256 | HACE_SG_EN | HACE_ACCUM_EN);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_accum_sha256, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha512_sg("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-static void test_sha512_accum(const char *machine, const uint32_t base,
- const uint32_t src_addr)
+static void test_sha256_accum_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- const uint32_t buffer_addr = src_addr + 0x1000000;
- const uint32_t digest_addr = src_addr + 0x4000000;
- uint8_t digest[64] = {0};
- struct AspeedSgList array[] = {
- { cpu_to_le32(sizeof(test_vector_accum_512) | SG_LIST_LEN_LAST),
- cpu_to_le32(buffer_addr) },
- };
-
- /* Check engine is idle, no busy or irq bits set */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Write test vector into memory */
- qtest_memwrite(s, buffer_addr, test_vector_accum_512,
- sizeof(test_vector_accum_512));
- qtest_memwrite(s, src_addr, array, sizeof(array));
-
- write_regs(s, base, src_addr, sizeof(test_vector_accum_512),
- digest_addr, HACE_ALGO_SHA512 | HACE_SG_EN | HACE_ACCUM_EN);
-
- /* Check hash IRQ status is asserted */
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0x00000200);
-
- /* Clear IRQ status and check status is deasserted */
- qtest_writel(s, base + HACE_STS, 0x00000200);
- g_assert_cmphex(qtest_readl(s, base + HACE_STS), ==, 0);
-
- /* Read computed digest from memory */
- qtest_memread(s, digest_addr, digest, sizeof(digest));
-
- /* Check result of computation */
- g_assert_cmpmem(digest, sizeof(digest),
- test_result_accum_sha512, sizeof(digest));
-
- qtest_quit(s);
+ aspeed_test_sha256_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
}
-struct masks {
- uint32_t src;
- uint32_t dest;
- uint32_t len;
-};
-
-static const struct masks ast2600_masks = {
- .src = 0x7fffffff,
- .dest = 0x7ffffff8,
- .len = 0x0fffffff,
-};
-
-static const struct masks ast2500_masks = {
- .src = 0x3fffffff,
- .dest = 0x3ffffff8,
- .len = 0x0fffffff,
-};
-
-static const struct masks ast2400_masks = {
- .src = 0x0fffffff,
- .dest = 0x0ffffff8,
- .len = 0x0fffffff,
-};
-
-static void test_addresses(const char *machine, const uint32_t base,
- const struct masks *expected)
+static void test_sha384_accum_ast1030(void)
{
- QTestState *s = qtest_init(machine);
-
- /*
- * Check command mode is zero, meaning engine is in direct access mode,
- * as this affects the masking behavior of the HASH_SRC register.
- */
- g_assert_cmphex(qtest_readl(s, base + HACE_CMD), ==, 0);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
-
-
- /* Check that the address masking is correct */
- qtest_writel(s, base + HACE_HASH_SRC, 0xffffffff);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, expected->src);
-
- qtest_writel(s, base + HACE_HASH_DIGEST, 0xffffffff);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, expected->dest);
-
- qtest_writel(s, base + HACE_HASH_DATA_LEN, 0xffffffff);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, expected->len);
-
- /* Reset to zero */
- qtest_writel(s, base + HACE_HASH_SRC, 0);
- qtest_writel(s, base + HACE_HASH_DIGEST, 0);
- qtest_writel(s, base + HACE_HASH_DATA_LEN, 0);
+ aspeed_test_sha384_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
- /* Check that all bits are now zero */
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_SRC), ==, 0);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DIGEST), ==, 0);
- g_assert_cmphex(qtest_readl(s, base + HACE_HASH_DATA_LEN), ==, 0);
+static void test_sha512_accum_ast1030(void)
+{
+ aspeed_test_sha512_accum("-machine ast1030-evb", 0x7e6d0000, 0x00000000);
+}
- qtest_quit(s);
+static void test_addresses_ast1030(void)
+{
+ aspeed_test_addresses("-machine ast1030-evb", 0x7e6d0000, &ast1030_masks);
}
/* ast2600 */
static void test_md5_ast2600(void)
{
- test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_md5("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha256_ast2600(void)
{
- test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha256("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha256_sg_ast2600(void)
{
- test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha256_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha384_ast2600(void)
+{
+ aspeed_test_sha384("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha384_sg_ast2600(void)
+{
+ aspeed_test_sha384_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha512_ast2600(void)
{
- test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha512("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha512_sg_ast2600(void)
{
- test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha512_sg("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha256_accum_ast2600(void)
{
- test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha256_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+}
+
+static void test_sha384_accum_ast2600(void)
+{
+ aspeed_test_sha384_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_sha512_accum_ast2600(void)
{
- test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
+ aspeed_test_sha512_accum("-machine ast2600-evb", 0x1e6d0000, 0x80000000);
}
static void test_addresses_ast2600(void)
{
- test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
+ aspeed_test_addresses("-machine ast2600-evb", 0x1e6d0000, &ast2600_masks);
}
/* ast2500 */
static void test_md5_ast2500(void)
{
- test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+ aspeed_test_md5("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
}
static void test_sha256_ast2500(void)
{
- test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+ aspeed_test_sha256("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
}
static void test_sha512_ast2500(void)
{
- test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
+ aspeed_test_sha512("-machine ast2500-evb", 0x1e6e3000, 0x80000000);
}
static void test_addresses_ast2500(void)
{
- test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
+ aspeed_test_addresses("-machine ast2500-evb", 0x1e6e3000, &ast2500_masks);
}
/* ast2400 */
static void test_md5_ast2400(void)
{
- test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+ aspeed_test_md5("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
}
static void test_sha256_ast2400(void)
{
- test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+ aspeed_test_sha256("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
}
static void test_sha512_ast2400(void)
{
- test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
+ aspeed_test_sha512("-machine palmetto-bmc", 0x1e6e3000, 0x40000000);
}
static void test_addresses_ast2400(void)
{
- test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
+ aspeed_test_addresses("-machine palmetto-bmc", 0x1e6e3000, &ast2400_masks);
}
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
+ qtest_add_func("ast1030/hace/addresses", test_addresses_ast1030);
+ qtest_add_func("ast1030/hace/sha512", test_sha512_ast1030);
+ qtest_add_func("ast1030/hace/sha384", test_sha384_ast1030);
+ qtest_add_func("ast1030/hace/sha256", test_sha256_ast1030);
+ qtest_add_func("ast1030/hace/md5", test_md5_ast1030);
+
+ qtest_add_func("ast1030/hace/sha512_sg", test_sha512_sg_ast1030);
+ qtest_add_func("ast1030/hace/sha384_sg", test_sha384_sg_ast1030);
+ qtest_add_func("ast1030/hace/sha256_sg", test_sha256_sg_ast1030);
+
+ qtest_add_func("ast1030/hace/sha512_accum", test_sha512_accum_ast1030);
+ qtest_add_func("ast1030/hace/sha384_accum", test_sha384_accum_ast1030);
+ qtest_add_func("ast1030/hace/sha256_accum", test_sha256_accum_ast1030);
+
qtest_add_func("ast2600/hace/addresses", test_addresses_ast2600);
qtest_add_func("ast2600/hace/sha512", test_sha512_ast2600);
+ qtest_add_func("ast2600/hace/sha384", test_sha384_ast2600);
qtest_add_func("ast2600/hace/sha256", test_sha256_ast2600);
qtest_add_func("ast2600/hace/md5", test_md5_ast2600);
qtest_add_func("ast2600/hace/sha512_sg", test_sha512_sg_ast2600);
+ qtest_add_func("ast2600/hace/sha384_sg", test_sha384_sg_ast2600);
qtest_add_func("ast2600/hace/sha256_sg", test_sha256_sg_ast2600);
qtest_add_func("ast2600/hace/sha512_accum", test_sha512_accum_ast2600);
+ qtest_add_func("ast2600/hace/sha384_accum", test_sha384_accum_ast2600);
qtest_add_func("ast2600/hace/sha256_accum", test_sha256_accum_ast2600);
qtest_add_func("ast2500/hace/addresses", test_addresses_ast2500);
diff --git a/tests/qtest/aspeed_scu-test.c b/tests/qtest/aspeed_scu-test.c
new file mode 100644
index 0000000..ca09f91
--- /dev/null
+++ b/tests/qtest/aspeed_scu-test.c
@@ -0,0 +1,231 @@
+/*
+ * QTest testcase for the ASPEED AST2500 and AST2600 SCU.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2025 Tan Siewert
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest-single.h"
+
+/*
+ * SCU base, as well as protection key are
+ * the same on AST2500 and 2600.
+ */
+#define AST_SCU_BASE 0x1E6E2000
+#define AST_SCU_PROT_LOCK_STATE 0x0
+#define AST_SCU_PROT_LOCK_VALUE 0x2
+#define AST_SCU_PROT_UNLOCK_STATE 0x1
+#define AST_SCU_PROT_UNLOCK_VALUE 0x1688A8A8
+
+#define AST2500_MACHINE "-machine ast2500-evb"
+#define AST2500_SCU_PROT_REG 0x00
+#define AST2500_SCU_MISC_2_CONTROL_REG 0x4C
+
+#define AST2600_MACHINE "-machine ast2600-evb"
+/* AST2600 has two protection registers */
+#define AST2600_SCU_PROT_REG 0x000
+#define AST2600_SCU_PROT_REG2 0x010
+#define AST2600_SCU_MISC_2_CONTROL_REG 0x0C4
+
+#define TEST_LOCK_ARBITRARY_VALUE 0xABCDEFAB
+
+/**
+ * Assert that a given register matches an expected value.
+ *
+ * Reads the register and checks if its value equals the expected value.
+ *
+ * @param *s - QTest machine state
+ * @param reg - Address of the register to be checked
+ * @param expected - Expected register value
+ */
+static inline void assert_register_eq(QTestState *s,
+ uint32_t reg,
+ uint32_t expected)
+{
+ uint32_t value = qtest_readl(s, reg);
+ g_assert_cmphex(value, ==, expected);
+}
+
+/**
+ * Assert that a given register does not match a specific value.
+ *
+ * Reads the register and checks that its value is not equal to the
+ * provided value.
+ *
+ * @param *s - QTest machine state
+ * @param reg - Address of the register to be checked
+ * @param not_expected - Value the register must not contain
+ */
+static inline void assert_register_neq(QTestState *s,
+ uint32_t reg,
+ uint32_t not_expected)
+{
+ uint32_t value = qtest_readl(s, reg);
+ g_assert_cmphex(value, !=, not_expected);
+}
+
+/**
+ * Test whether the SCU can be locked and unlocked correctly.
+ *
+ * When testing multiple registers, this function assumes that writing
+ * to the first register also affects the others. However, writing to
+ * any other register only affects itself.
+ *
+ * @param *machine - input machine configuration, passed directly
+ * to QTest
+ * @param regs[] - List of registers to be checked
+ * @param regc - amount of arguments for registers to be checked
+ */
+static void test_protection_register(const char *machine,
+ const uint32_t regs[],
+ const int regc)
+{
+ QTestState *s = qtest_init(machine);
+
+ for (int i = 0; i < regc; i++) {
+ uint32_t reg = regs[i];
+
+ qtest_writel(s, reg, AST_SCU_PROT_UNLOCK_VALUE);
+ assert_register_eq(s, reg, AST_SCU_PROT_UNLOCK_STATE);
+
+ /**
+ * Check that other registers are unlocked too, if more
+ * than one is available.
+ */
+ if (regc > 1 && i == 0) {
+ /* Initialise at 1 instead of 0 to skip first */
+ for (int j = 1; j < regc; j++) {
+ uint32_t add_reg = regs[j];
+ assert_register_eq(s, add_reg, AST_SCU_PROT_UNLOCK_STATE);
+ }
+ }
+
+ /* Lock the register again */
+ qtest_writel(s, reg, AST_SCU_PROT_LOCK_VALUE);
+ assert_register_eq(s, reg, AST_SCU_PROT_LOCK_STATE);
+
+ /* And the same for locked state */
+ if (regc > 1 && i == 0) {
+ /* Initialise at 1 instead of 0 to skip first */
+ for (int j = 1; j < regc; j++) {
+ uint32_t add_reg = regs[j];
+ assert_register_eq(s, add_reg, AST_SCU_PROT_LOCK_STATE);
+ }
+ }
+ }
+
+ qtest_quit(s);
+}
+
+static void test_2500_protection_register(void)
+{
+ uint32_t regs[] = { AST_SCU_BASE + AST2500_SCU_PROT_REG };
+
+ test_protection_register(AST2500_MACHINE,
+ regs,
+ ARRAY_SIZE(regs));
+}
+
+static void test_2600_protection_register(void)
+{
+ /**
+ * The AST2600 has two protection registers, both
+ * being required to be unlocked to do any operation.
+ *
+ * Modifying SCU000 also modifies SCU010, but modifying
+ * SCU010 only will keep SCU000 untouched.
+ */
+ uint32_t regs[] = { AST_SCU_BASE + AST2600_SCU_PROT_REG,
+ AST_SCU_BASE + AST2600_SCU_PROT_REG2 };
+
+ test_protection_register(AST2600_MACHINE,
+ regs,
+ ARRAY_SIZE(regs));
+}
+
+/**
+ * Test if SCU register writes are correctly allowed or blocked
+ * depending on the protection register state.
+ *
+ * The test first locks the protection register and verifies that
+ * writes to the target SCU register are rejected. It then unlocks
+ * the protection register and confirms that the written value is
+ * retained when unlocked.
+ *
+ * @param *machine - input machine configuration, passed directly
+ * to QTest
+ * @param protection_register - first SCU protection key register
+ * (only one for keeping it simple)
+ * @param test_register - Register to be used for writing arbitrary
+ * values
+ */
+static void test_write_permission_lock_state(const char *machine,
+ const uint32_t protection_register,
+ const uint32_t test_register)
+{
+ QTestState *s = qtest_init(machine);
+
+ /* Arbitrary value to lock provided SCU protection register */
+ qtest_writel(s, protection_register, AST_SCU_PROT_LOCK_VALUE);
+
+ /* Ensure that the SCU is really locked */
+ assert_register_eq(s, protection_register, AST_SCU_PROT_LOCK_STATE);
+
+ /* Write a known arbitrary value to test that the write is blocked */
+ qtest_writel(s, test_register, TEST_LOCK_ARBITRARY_VALUE);
+
+ /* We do not want to have the written value to be saved */
+ assert_register_neq(s, test_register, TEST_LOCK_ARBITRARY_VALUE);
+
+ /**
+ * Unlock the SCU and verify that it can be written to.
+ * Assumes that the first SCU protection register is sufficient to
+ * unlock all protection registers, if multiple are present.
+ */
+ qtest_writel(s, protection_register, AST_SCU_PROT_UNLOCK_VALUE);
+ assert_register_eq(s, protection_register, AST_SCU_PROT_UNLOCK_STATE);
+
+ /* Write a known arbitrary value to test that the write works */
+ qtest_writel(s, test_register, TEST_LOCK_ARBITRARY_VALUE);
+
+ /* Ensure that the written value is retained */
+ assert_register_eq(s, test_register, TEST_LOCK_ARBITRARY_VALUE);
+
+ qtest_quit(s);
+}
+
+static void test_2500_write_permission_lock_state(void)
+{
+ test_write_permission_lock_state(
+ AST2500_MACHINE,
+ AST_SCU_BASE + AST2500_SCU_PROT_REG,
+ AST_SCU_BASE + AST2500_SCU_MISC_2_CONTROL_REG
+ );
+}
+
+static void test_2600_write_permission_lock_state(void)
+{
+ test_write_permission_lock_state(
+ AST2600_MACHINE,
+ AST_SCU_BASE + AST2600_SCU_PROT_REG,
+ AST_SCU_BASE + AST2600_SCU_MISC_2_CONTROL_REG
+ );
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("/ast2500/scu/protection_register",
+ test_2500_protection_register);
+ qtest_add_func("/ast2600/scu/protection_register",
+ test_2600_protection_register);
+
+ qtest_add_func("/ast2500/scu/write_permission_lock_state",
+ test_2500_write_permission_lock_state);
+ qtest_add_func("/ast2600/scu/write_permission_lock_state",
+ test_2600_write_permission_lock_state);
+
+ return g_test_run();
+}
diff --git a/tests/qtest/aspeed_smc-test.c b/tests/qtest/aspeed_smc-test.c
index 4e13893..52a00e6 100644
--- a/tests/qtest/aspeed_smc-test.c
+++ b/tests/qtest/aspeed_smc-test.c
@@ -228,5 +228,10 @@ int main(int argc, char **argv)
unlink(ast2500_evb_data.tmp_path);
unlink(ast2600_evb_data.tmp_path);
unlink(ast1030_evb_data.tmp_path);
+ g_free(palmetto_data.tmp_path);
+ g_free(ast2500_evb_data.tmp_path);
+ g_free(ast2600_evb_data.tmp_path);
+ g_free(ast1030_evb_data.tmp_path);
+
return ret;
}
diff --git a/tests/qtest/ast2700-hace-test.c b/tests/qtest/ast2700-hace-test.c
new file mode 100644
index 0000000..a400e29
--- /dev/null
+++ b/tests/qtest/ast2700-hace-test.c
@@ -0,0 +1,98 @@
+/*
+ * QTest testcase for the ASPEED Hash and Crypto Engine
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (C) 2025 ASPEED Technology Inc.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qemu/bitops.h"
+#include "aspeed-hace-utils.h"
+
+static const struct AspeedMasks as2700_masks = {
+ .src = 0x7fffffff,
+ .dest = 0x7ffffff8,
+ .key = 0x7ffffff8,
+ .len = 0x0fffffff,
+ .src_hi = 0x00000003,
+ .dest_hi = 0x00000003,
+ .key_hi = 0x00000003,
+};
+
+/* ast2700 */
+static void test_md5_ast2700(void)
+{
+ aspeed_test_md5("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_ast2700(void)
+{
+ aspeed_test_sha256("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_sg_ast2700(void)
+{
+ aspeed_test_sha256_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_ast2700(void)
+{
+ aspeed_test_sha384("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_sg_ast2700(void)
+{
+ aspeed_test_sha384_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_ast2700(void)
+{
+ aspeed_test_sha512("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_sg_ast2700(void)
+{
+ aspeed_test_sha512_sg("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha256_accum_ast2700(void)
+{
+ aspeed_test_sha256_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha384_accum_ast2700(void)
+{
+ aspeed_test_sha384_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_sha512_accum_ast2700(void)
+{
+ aspeed_test_sha512_accum("-machine ast2700a1-evb", 0x12070000, 0x400000000);
+}
+
+static void test_addresses_ast2700(void)
+{
+ aspeed_test_addresses("-machine ast2700a1-evb", 0x12070000, &as2700_masks);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("ast2700/hace/addresses", test_addresses_ast2700);
+ qtest_add_func("ast2700/hace/sha512", test_sha512_ast2700);
+ qtest_add_func("ast2700/hace/sha384", test_sha384_ast2700);
+ qtest_add_func("ast2700/hace/sha256", test_sha256_ast2700);
+ qtest_add_func("ast2700/hace/md5", test_md5_ast2700);
+
+ qtest_add_func("ast2700/hace/sha512_sg", test_sha512_sg_ast2700);
+ qtest_add_func("ast2700/hace/sha384_sg", test_sha384_sg_ast2700);
+ qtest_add_func("ast2700/hace/sha256_sg", test_sha256_sg_ast2700);
+
+ qtest_add_func("ast2700/hace/sha512_accum", test_sha512_accum_ast2700);
+ qtest_add_func("ast2700/hace/sha384_accum", test_sha384_accum_ast2700);
+ qtest_add_func("ast2700/hace/sha256_accum", test_sha256_accum_ast2700);
+
+ return g_test_run();
+}
diff --git a/tests/qtest/ast2700-smc-test.c b/tests/qtest/ast2700-smc-test.c
index d1c4856..62d538d 100644
--- a/tests/qtest/ast2700-smc-test.c
+++ b/tests/qtest/ast2700-smc-test.c
@@ -67,5 +67,6 @@ int main(int argc, char **argv)
qtest_quit(ast2700_evb_data.s);
unlink(ast2700_evb_data.tmp_path);
+ g_free(ast2700_evb_data.tmp_path);
return ret;
}
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index 0a333ec..6b892ef 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -1622,7 +1622,7 @@ static void test_acpi_aarch64_virt_tcg_memhp(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 256ULL * 1024 * 1024,
+ .scan_len = 256ULL * MiB,
};
data.variant = ".memhp";
@@ -1643,6 +1643,54 @@ static void test_acpi_aarch64_virt_tcg_memhp(void)
}
+static void test_acpi_aarch64_virt_acpi_pci_hotplug(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 256ULL * MiB,
+ .variant = ".acpipcihp",
+ };
+
+ /* Use ACPI PCI Hotplug */
+ test_acpi_one(" -global acpi-ged.acpi-pci-hotplug-with-bridge-support=on"
+ " -cpu cortex-a57"
+ " -device pcie-root-port,id=pcie.1,bus=pcie.0,chassis=0,slot=1,addr=7.0"
+ " -device pci-testdev,bus=pcie.1",
+ &data);
+
+ free_test_data(&data);
+}
+
+static void test_acpi_aarch64_virt_pcie_root_port_hpoff(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 256ULL * MiB,
+ .variant = ".hpoffacpiindex",
+ };
+
+ /* turn hotplug off on the pcie-root-port and use static acpi-index*/
+ test_acpi_one(" -device pcie-root-port,id=pcie.1,chassis=0,"
+ "slot=1,hotplug=off,addr=7.0"
+ " -device pci-testdev,bus=pcie.1,acpi-index=12"
+ " -cpu cortex-a57",
+ &data);
+
+ free_test_data(&data);
+}
+
static void test_acpi_microvm_prepare(test_data *data)
{
data->machine = "microvm";
@@ -1717,7 +1765,7 @@ static void test_acpi_riscv64_virt_tcg_numamem(void)
.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
.ram_start = 0x80000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
data.variant = ".numamem";
@@ -1743,7 +1791,7 @@ static void test_acpi_aarch64_virt_tcg_numamem(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
data.variant = ".numamem";
@@ -1765,7 +1813,7 @@ static void test_acpi_aarch64_virt_tcg_pxb(void)
.uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
/*
* While using -cdrom, the cdrom would auto plugged into pxb-pcie,
@@ -1789,6 +1837,44 @@ static void test_acpi_aarch64_virt_tcg_pxb(void)
free_test_data(&data);
}
+static void test_acpi_aarch64_virt_tcg_acpi_spcr(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * 1024 * 1024,
+ .variant = ".acpispcr",
+ };
+
+ test_acpi_one("-cpu cortex-a57 "
+ " -machine spcr=off", &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_riscv64_virt_tcg_acpi_spcr(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "riscv64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-riscv-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
+ .ram_start = 0x80000000ULL,
+ .scan_len = 128ULL * 1024 * 1024,
+ .variant = ".acpispcr",
+ };
+
+ test_acpi_one("-cpu rva22s64 "
+ "-machine spcr=off", &data);
+ free_test_data(&data);
+}
+
static void test_acpi_tcg_acpi_hmat(const char *machine, const char *arch)
{
test_data data = {};
@@ -1841,7 +1927,7 @@ static void test_acpi_aarch64_virt_tcg_acpi_hmat(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
data.variant = ".acpihmatvirt";
@@ -2095,7 +2181,7 @@ static void test_acpi_riscv64_virt_tcg(void)
.uefi_fl2 = "pc-bios/edk2-riscv-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2",
.ram_start = 0x80000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
/*
@@ -2117,12 +2203,12 @@ static void test_acpi_aarch64_virt_tcg(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
data.smbios_cpu_max_speed = 2900;
data.smbios_cpu_curr_speed = 2700;
- test_acpi_one("-cpu cortex-a57 "
+ test_acpi_one("-cpu cortex-a57 -machine ras=on "
"-smbios type=4,max-speed=2900,current-speed=2700", &data);
free_test_data(&data);
}
@@ -2138,7 +2224,7 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
test_acpi_one("-cpu cortex-a57 "
@@ -2146,6 +2232,25 @@ static void test_acpi_aarch64_virt_tcg_topology(void)
free_test_data(&data);
}
+static void test_acpi_aarch64_virt_tcg_its_off(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .variant = ".its_off",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * 1024 * 1024,
+ };
+
+ test_acpi_one("-cpu cortex-a57 "
+ "-M gic-version=3,iommu=smmuv3,its=off", &data);
+ free_test_data(&data);
+}
+
static void test_acpi_q35_viot(void)
{
test_data data = {
@@ -2218,12 +2323,13 @@ static void test_acpi_aarch64_virt_viot(void)
test_data data = {
.machine = "virt",
.arch = "aarch64",
+ .variant = ".viot",
.tcg_only = true,
.uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
test_acpi_one("-cpu cortex-a57 "
@@ -2231,6 +2337,86 @@ static void test_acpi_aarch64_virt_viot(void)
free_test_data(&data);
}
+static void test_acpi_aarch64_virt_smmuv3_legacy(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * MiB,
+ };
+
+ /*
+ * cdrom is plugged into scsi controller to avoid conflict
+ * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb() for
+ * details.
+ *
+ * The setup includes three PCIe root complexes, one of which has
+ * bypass_iommu enabled. The generated IORT table contains a single
+ * SMMUv3 node and a Root Complex node with three ID mappings. Two
+ * of the ID mappings have output references pointing to the SMMUv3
+ * node and the remaining one points to ITS.
+ */
+ data.variant = ".smmuv3-legacy";
+ test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1"
+ " -device virtio-scsi-pci,id=scsi0,bus=pci.1"
+ " -drive file="
+ "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2,"
+ "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on"
+ " -device scsi-cd,bus=scsi0.0,scsi-id=0,"
+ "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1"
+ " -cpu cortex-a57"
+ " -M iommu=smmuv3"
+ " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10"
+ " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20,bypass_iommu=on",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_aarch64_virt_smmuv3_dev(void)
+{
+ test_data data = {
+ .machine = "virt",
+ .arch = "aarch64",
+ .tcg_only = true,
+ .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd",
+ .uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
+ .ram_start = 0x40000000ULL,
+ .scan_len = 128ULL * MiB,
+ };
+
+ /*
+ * cdrom is plugged into scsi controller to avoid conflict
+ * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb()
+ * for details.
+ *
+ * The setup includes three PCie root complexes, two of which are
+ * connected to separate SMMUv3 devices. The resulting IORT table
+ * contains two SMMUv3 nodes and a Root Complex node with ID mappings
+ * of which two of the ID mappings have output references pointing
+ * to two different SMMUv3 nodes and the remaining ones pointing to
+ * ITS.
+ */
+ data.variant = ".smmuv3-dev";
+ test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1"
+ " -device virtio-scsi-pci,id=scsi0,bus=pci.1"
+ " -drive file="
+ "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2,"
+ "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on"
+ " -device scsi-cd,bus=scsi0.0,scsi-id=0,"
+ "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1"
+ " -cpu cortex-a57"
+ " -device arm-smmuv3,primary-bus=pcie.0,id=smmuv3.0"
+ " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10"
+ " -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1"
+ " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20",
+ &data);
+ free_test_data(&data);
+}
+
#ifndef _WIN32
# define DEV_NULL "/dev/null"
#else
@@ -2407,7 +2593,7 @@ static void test_acpi_aarch64_virt_oem_fields(void)
.uefi_fl2 = "pc-bios/edk2-arm-vars.fd",
.cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2",
.ram_start = 0x40000000ULL,
- .scan_len = 128ULL * 1024 * 1024,
+ .scan_len = 128ULL * MiB,
};
char *args;
@@ -2420,6 +2606,74 @@ static void test_acpi_aarch64_virt_oem_fields(void)
g_free(args);
}
+#define LOONGARCH64_INIT_TEST_DATA(data) \
+ test_data data = { \
+ .machine = "virt", \
+ .arch = "loongarch64", \
+ .tcg_only = true, \
+ .uefi_fl1 = "pc-bios/edk2-loongarch64-code.fd", \
+ .uefi_fl2 = "pc-bios/edk2-loongarch64-vars.fd", \
+ .cd = "tests/data/uefi-boot-images/" \
+ "bios-tables-test.loongarch64.iso.qcow2", \
+ .ram_start = 0, \
+ .scan_len = 128ULL * MiB, \
+ }
+
+static void test_acpi_loongarch64_virt(void)
+{
+ LOONGARCH64_INIT_TEST_DATA(data);
+
+ test_acpi_one("-cpu la464 ", &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_loongarch64_virt_topology(void)
+{
+ LOONGARCH64_INIT_TEST_DATA(data);
+
+ data.variant = ".topology";
+ test_acpi_one("-cpu la464 -smp sockets=1,cores=2,threads=2", &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_loongarch64_virt_numamem(void)
+{
+ LOONGARCH64_INIT_TEST_DATA(data);
+
+ data.variant = ".numamem";
+ test_acpi_one(" -cpu la464 -m 128"
+ " -object memory-backend-ram,id=ram0,size=64M"
+ " -object memory-backend-ram,id=ram1,size=64M"
+ " -numa node,memdev=ram0 -numa node,memdev=ram1"
+ " -numa dist,src=0,dst=1,val=21",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_loongarch64_virt_memhp(void)
+{
+ LOONGARCH64_INIT_TEST_DATA(data);
+
+ data.variant = ".memhp";
+ test_acpi_one(" -cpu la464 -m 128,slots=2,maxmem=256M"
+ " -object memory-backend-ram,id=ram0,size=128M",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_loongarch64_virt_oem_fields(void)
+{
+ LOONGARCH64_INIT_TEST_DATA(data);
+ char *args;
+
+ args = test_acpi_create_args(&data, "-cpu la464 "OEM_TEST_ARGS);
+ data.qts = qtest_init(args);
+ test_acpi_load_tables(&data);
+ test_oem_fields(&data);
+ qtest_quit(data.qts);
+ free_test_data(&data);
+ g_free(args);
+}
int main(int argc, char *argv[])
{
@@ -2577,21 +2831,48 @@ int main(int argc, char *argv[])
test_acpi_aarch64_virt_tcg_acpi_hmat);
qtest_add_func("acpi/virt/topology",
test_acpi_aarch64_virt_tcg_topology);
+ qtest_add_func("acpi/virt/its_off",
+ test_acpi_aarch64_virt_tcg_its_off);
qtest_add_func("acpi/virt/numamem",
test_acpi_aarch64_virt_tcg_numamem);
qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp);
+ qtest_add_func("acpi/virt/acpipcihp",
+ test_acpi_aarch64_virt_acpi_pci_hotplug);
+ qtest_add_func("acpi/virt/hpoffacpiindex",
+ test_acpi_aarch64_virt_pcie_root_port_hpoff);
qtest_add_func("acpi/virt/pxb", test_acpi_aarch64_virt_tcg_pxb);
qtest_add_func("acpi/virt/oem-fields",
test_acpi_aarch64_virt_oem_fields);
+ qtest_add_func("acpi/virt/acpispcr",
+ test_acpi_aarch64_virt_tcg_acpi_spcr);
if (qtest_has_device("virtio-iommu-pci")) {
qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot);
}
+ qtest_add_func("acpi/virt/smmuv3-legacy",
+ test_acpi_aarch64_virt_smmuv3_legacy);
+ if (qtest_has_device("arm-smmuv3")) {
+ qtest_add_func("acpi/virt/smmuv3-dev",
+ test_acpi_aarch64_virt_smmuv3_dev);
+ }
}
} else if (strcmp(arch, "riscv64") == 0) {
if (has_tcg && qtest_has_device("virtio-blk-pci")) {
qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg);
qtest_add_func("acpi/virt/numamem",
test_acpi_riscv64_virt_tcg_numamem);
+ qtest_add_func("acpi/virt/acpispcr",
+ test_acpi_riscv64_virt_tcg_acpi_spcr);
+ }
+ } else if (strcmp(arch, "loongarch64") == 0) {
+ if (has_tcg && qtest_has_machine("virt")) {
+ qtest_add_func("acpi/virt", test_acpi_loongarch64_virt);
+ qtest_add_func("acpi/virt/topology",
+ test_acpi_loongarch64_virt_topology);
+ qtest_add_func("acpi/virt/numamem",
+ test_acpi_loongarch64_virt_numamem);
+ qtest_add_func("acpi/virt/memhp", test_acpi_loongarch64_virt_memhp);
+ qtest_add_func("acpi/virt/oem-fields",
+ test_acpi_loongarch64_virt_oem_fields);
}
}
ret = g_test_run();
diff --git a/tests/qtest/cpu-plug-test.c b/tests/qtest/cpu-plug-test.c
index 44d7046..0aa4ccc 100644
--- a/tests/qtest/cpu-plug-test.c
+++ b/tests/qtest/cpu-plug-test.c
@@ -190,7 +190,7 @@ int main(int argc, char **argv)
qtest_cb_for_every_machine(add_pseries_test_case, g_test_quick());
} else if (g_str_equal(arch, "s390x")) {
qtest_cb_for_every_machine(add_s390x_test_case, g_test_quick());
- } else if (g_str_equal(arch, "loongarch64")) {
+ } else if (g_str_equal(arch, "loongarch64") && qtest_has_machine("virt")) {
add_loongarch_test_case("virt");
}
diff --git a/tests/qtest/cxl-test.c b/tests/qtest/cxl-test.c
index a600331..8fb7e58 100644
--- a/tests/qtest/cxl-test.c
+++ b/tests/qtest/cxl-test.c
@@ -19,6 +19,12 @@
"-device pxb-cxl,id=cxl.1,bus=pcie.0,bus_nr=53 " \
"-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=4G "
+#define QEMU_VIRT_2PXB_CMD \
+ "-machine virt,cxl=on -cpu max " \
+ "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " \
+ "-device pxb-cxl,id=cxl.1,bus=pcie.0,bus_nr=53 " \
+ "-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=4G "
+
#define QEMU_RP \
"-device cxl-rp,id=rp0,bus=cxl.0,chassis=0,slot=0 "
@@ -197,25 +203,51 @@ static void cxl_2pxb_4rp_4t3d(void)
qtest_end();
rmdir(tmpfs);
}
+
+static void cxl_virt_2pxb_4rp_4t3d(void)
+{
+ g_autoptr(GString) cmdline = g_string_new(NULL);
+ g_autofree const char *tmpfs = NULL;
+
+ tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL);
+
+ g_string_printf(cmdline, QEMU_VIRT_2PXB_CMD QEMU_4RP QEMU_4T3D,
+ tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, tmpfs,
+ tmpfs, tmpfs);
+
+ qtest_start(cmdline->str);
+ qtest_end();
+ rmdir(tmpfs);
+}
#endif /* CONFIG_POSIX */
int main(int argc, char **argv)
{
- g_test_init(&argc, &argv, NULL);
+ const char *arch = qtest_get_arch();
- qtest_add_func("/pci/cxl/basic_hostbridge", cxl_basic_hb);
- qtest_add_func("/pci/cxl/basic_pxb", cxl_basic_pxb);
- qtest_add_func("/pci/cxl/pxb_with_window", cxl_pxb_with_window);
- qtest_add_func("/pci/cxl/pxb_x2_with_window", cxl_2pxb_with_window);
- qtest_add_func("/pci/cxl/rp", cxl_root_port);
- qtest_add_func("/pci/cxl/rp_x2", cxl_2root_port);
+ g_test_init(&argc, &argv, NULL);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("/pci/cxl/basic_hostbridge", cxl_basic_hb);
+ qtest_add_func("/pci/cxl/basic_pxb", cxl_basic_pxb);
+ qtest_add_func("/pci/cxl/pxb_with_window", cxl_pxb_with_window);
+ qtest_add_func("/pci/cxl/pxb_x2_with_window", cxl_2pxb_with_window);
+ qtest_add_func("/pci/cxl/rp", cxl_root_port);
+ qtest_add_func("/pci/cxl/rp_x2", cxl_2root_port);
#ifdef CONFIG_POSIX
- qtest_add_func("/pci/cxl/type3_device", cxl_t3d_deprecated);
- qtest_add_func("/pci/cxl/type3_device_pmem", cxl_t3d_persistent);
- qtest_add_func("/pci/cxl/type3_device_vmem", cxl_t3d_volatile);
- qtest_add_func("/pci/cxl/type3_device_vmem_lsa", cxl_t3d_volatile_lsa);
- qtest_add_func("/pci/cxl/rp_x2_type3_x2", cxl_1pxb_2rp_2t3d);
- qtest_add_func("/pci/cxl/pxb_x2_root_port_x4_type3_x4", cxl_2pxb_4rp_4t3d);
+ qtest_add_func("/pci/cxl/type3_device", cxl_t3d_deprecated);
+ qtest_add_func("/pci/cxl/type3_device_pmem", cxl_t3d_persistent);
+ qtest_add_func("/pci/cxl/type3_device_vmem", cxl_t3d_volatile);
+ qtest_add_func("/pci/cxl/type3_device_vmem_lsa", cxl_t3d_volatile_lsa);
+ qtest_add_func("/pci/cxl/rp_x2_type3_x2", cxl_1pxb_2rp_2t3d);
+ qtest_add_func("/pci/cxl/pxb_x2_root_port_x4_type3_x4",
+ cxl_2pxb_4rp_4t3d);
#endif
+ } else if (strcmp(arch, "aarch64") == 0) {
+#ifdef CONFIG_POSIX
+ qtest_add_func("/pci/cxl/virt/pxb_x2_root_port_x4_type3_x4",
+ cxl_virt_2pxb_4rp_4t3d);
+#endif
+ }
+
return g_test_run();
}
diff --git a/tests/qtest/fuzz/virtio_net_fuzz.c b/tests/qtest/fuzz/virtio_net_fuzz.c
index e239875..e9b13d3 100644
--- a/tests/qtest/fuzz/virtio_net_fuzz.c
+++ b/tests/qtest/fuzz/virtio_net_fuzz.c
@@ -132,7 +132,7 @@ static void *virtio_net_test_setup_socket(GString *cmd_line, void *arg)
{
int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sockfds);
g_assert_cmpint(ret, !=, -1);
- g_unix_set_fd_nonblocking(sockfds[0], true, NULL);
+ qemu_set_blocking(sockfds[0], false, &error_abort);
sockfds_initialized = true;
g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ",
sockfds[1]);
diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c
index f40c4ec..ab3ef6f 100644
--- a/tests/qtest/libqos/igb.c
+++ b/tests/qtest/libqos/igb.c
@@ -104,10 +104,10 @@ static void igb_pci_start_hw(QOSGraphObject *obj)
e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0);
e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0);
e1000e_macreg_write(&d->e1000e, E1000_RA,
- le32_to_cpu(*(uint32_t *)address));
+ ldl_le_p(address));
e1000e_macreg_write(&d->e1000e, E1000_RA + 4,
E1000_RAH_AV | E1000_RAH_POOL_1 |
- le16_to_cpu(*(uint16_t *)(address + 4)));
+ lduw_le_p(address + 4));
/* Set supported receive descriptor mode */
e1000e_macreg_write(&d->e1000e,
diff --git a/tests/qtest/libqos/virtio.c b/tests/qtest/libqos/virtio.c
index 5a709d0..010ff40 100644
--- a/tests/qtest/libqos/virtio.c
+++ b/tests/qtest/libqos/virtio.c
@@ -265,8 +265,9 @@ void qvring_init(QTestState *qts, const QGuestAllocator *alloc, QVirtQueue *vq,
/* vq->avail->flags */
qvirtio_writew(vq->vdev, qts, vq->avail, 0);
- /* vq->avail->idx */
- qvirtio_writew(vq->vdev, qts, vq->avail + 2, 0);
+
+ qvirtqueue_set_avail_idx(qts, vq->vdev, vq, 0);
+
/* vq->avail->used_event */
qvirtio_writew(vq->vdev, qts, vq->avail + 4 + (2 * vq->size), 0);
@@ -388,6 +389,13 @@ uint32_t qvirtqueue_add_indirect(QTestState *qts, QVirtQueue *vq,
return vq->free_head++; /* Return and increase, in this order */
}
+void qvirtqueue_set_avail_idx(QTestState *qts, QVirtioDevice *d,
+ QVirtQueue *vq, uint16_t idx)
+{
+ /* vq->avail->idx */
+ qvirtio_writew(d, qts, vq->avail + 2, idx);
+}
+
void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq,
uint32_t free_head)
{
@@ -400,8 +408,8 @@ void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq,
/* vq->avail->ring[idx % vq->size] */
qvirtio_writew(d, qts, vq->avail + 4 + (2 * (idx % vq->size)), free_head);
- /* vq->avail->idx */
- qvirtio_writew(d, qts, vq->avail + 2, idx + 1);
+
+ qvirtqueue_set_avail_idx(qts, d, vq, idx + 1);
/* Must read after idx is updated */
flags = qvirtio_readw(d, qts, vq->used);
diff --git a/tests/qtest/libqos/virtio.h b/tests/qtest/libqos/virtio.h
index 7adc7cb..e238f17 100644
--- a/tests/qtest/libqos/virtio.h
+++ b/tests/qtest/libqos/virtio.h
@@ -143,6 +143,8 @@ uint32_t qvirtqueue_add(QTestState *qts, QVirtQueue *vq, uint64_t data,
uint32_t len, bool write, bool next);
uint32_t qvirtqueue_add_indirect(QTestState *qts, QVirtQueue *vq,
QVRingIndirectDesc *indirect);
+void qvirtqueue_set_avail_idx(QTestState *qts, QVirtioDevice *d,
+ QVirtQueue *vq, uint16_t idx);
void qvirtqueue_kick(QTestState *qts, QVirtioDevice *d, QVirtQueue *vq,
uint32_t free_head);
bool qvirtqueue_get_buf(QTestState *qts, QVirtQueue *vq, uint32_t *desc_idx,
diff --git a/tests/qtest/libqtest.c b/tests/qtest/libqtest.c
index 94526b7..933d085 100644
--- a/tests/qtest/libqtest.c
+++ b/tests/qtest/libqtest.c
@@ -357,7 +357,7 @@ void qtest_remove_abrt_handler(void *data)
}
}
-static const char *qtest_qemu_binary(const char *var)
+const char *qtest_qemu_binary(const char *var)
{
const char *qemu_bin;
@@ -409,30 +409,30 @@ static pid_t qtest_create_process(char *cmd)
}
#endif /* _WIN32 */
-static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
- const char *fmt, ...)
+static QTestState *qtest_create_test_state(int pid)
{
- va_list ap;
QTestState *s = g_new0(QTestState, 1);
- const char *trace = g_getenv("QTEST_TRACE");
- g_autofree char *tracearg = trace ?
- g_strdup_printf("-trace %s ", trace) : g_strdup("");
- g_autoptr(GString) command = g_string_new("");
-
- va_start(ap, fmt);
- g_string_append_printf(command, CMD_EXEC "%s %s", qemu_bin, tracearg);
- g_string_append_vprintf(command, fmt, ap);
- va_end(ap);
+ s->qemu_pid = pid;
qtest_add_abrt_handler(kill_qemu_hook_func, s);
+ return s;
+}
+
+static QTestState *qtest_spawn_qemu(const char *qemu_bin, const char *args,
+ void *opaque)
+{
+ int pid;
+ g_autoptr(GString) command = g_string_new("");
+
+ g_string_printf(command, CMD_EXEC "%s %s", qemu_bin, args);
if (!silence_spawn_log) {
g_test_message("starting QEMU: %s", command->str);
}
#ifndef _WIN32
- s->qemu_pid = fork();
- if (s->qemu_pid == 0) {
+ pid = fork();
+ if (pid == 0) {
#ifdef __linux__
/*
* Although we register a ABRT handler to kill off QEMU
@@ -455,10 +455,10 @@ static QTestState *G_GNUC_PRINTF(2, 3) qtest_spawn_qemu(const char *qemu_bin,
exit(1);
}
#else
- s->qemu_pid = qtest_create_process(command->str);
+ pid = qtest_create_process(command->str);
#endif /* _WIN32 */
- return s;
+ return qtest_create_test_state(pid);
}
static char *qtest_socket_path(const char *suffix)
@@ -466,14 +466,48 @@ static char *qtest_socket_path(const char *suffix)
return g_strdup_printf("%s/qtest-%d.%s", g_get_tmp_dir(), getpid(), suffix);
}
+gchar *qtest_qemu_args(const char *extra_args)
+{
+ g_autofree gchar *socket_path = qtest_socket_path("sock");
+ g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ const char *trace = g_getenv("QTEST_TRACE");
+ g_autofree char *tracearg = trace ? g_strdup_printf("-trace %s ", trace) :
+ g_strdup("");
+ gchar *args = g_strdup_printf(
+ "%s"
+ "-qtest unix:%s "
+ "-qtest-log %s "
+ "-chardev socket,path=%s,id=char0 "
+ "-mon chardev=char0,mode=control "
+ "-display none "
+ "-audio none "
+ "%s"
+ " -accel qtest",
+
+ tracearg,
+ socket_path,
+ getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
+ qmp_socket_path,
+ extra_args ?: "");
+
+ return args;
+}
+
+typedef QTestState *(*qtest_qemu_spawn_func)(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque);
+
static QTestState *qtest_init_internal(const char *qemu_bin,
const char *extra_args,
- bool do_connect)
+ bool do_connect,
+ qtest_qemu_spawn_func spawn,
+ void *opaque)
{
QTestState *s;
int sock, qmpsock, i;
g_autofree gchar *socket_path = qtest_socket_path("sock");
g_autofree gchar *qmp_socket_path = qtest_socket_path("qmp");
+ g_autofree gchar *args = qtest_qemu_args(extra_args);
/*
* It's possible that if an earlier test run crashed it might
@@ -488,19 +522,7 @@ static QTestState *qtest_init_internal(const char *qemu_bin,
sock = init_socket(socket_path);
qmpsock = init_socket(qmp_socket_path);
- s = qtest_spawn_qemu(qemu_bin,
- "-qtest unix:%s "
- "-qtest-log %s "
- "-chardev socket,path=%s,id=char0 "
- "-mon chardev=char0,mode=control "
- "-display none "
- "-audio none "
- "%s"
- " -accel qtest",
- socket_path,
- getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL,
- qmp_socket_path,
- extra_args ?: "");
+ s = spawn(qemu_bin, args, opaque);
qtest_client_set_rx_handler(s, qtest_client_socket_recv_line);
qtest_client_set_tx_handler(s, qtest_client_socket_send);
@@ -555,7 +577,8 @@ void qtest_connect(QTestState *s)
QTestState *qtest_init_without_qmp_handshake(const char *extra_args)
{
- return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true);
+ return qtest_init_internal(qtest_qemu_binary(NULL), extra_args, true,
+ qtest_spawn_qemu, NULL);
}
void qtest_qmp_handshake(QTestState *s, QList *capabilities)
@@ -578,7 +601,7 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
QList *capabilities, bool do_connect)
{
QTestState *s = qtest_init_internal(qtest_qemu_binary(var), extra_args,
- do_connect);
+ do_connect, qtest_spawn_qemu, NULL);
if (do_connect) {
qtest_qmp_handshake(s, capabilities);
@@ -592,6 +615,25 @@ QTestState *qtest_init_ext(const char *var, const char *extra_args,
return s;
}
+static QTestState *qtest_attach_qemu(const char *qemu_bin,
+ const char *extra_args,
+ void *opaque)
+{
+ int pid = *(int *)opaque;
+ return qtest_create_test_state(pid);
+}
+
+QTestState *qtest_init_after_exec(QTestState *qts)
+{
+ void *opaque = (void *)&qts->qemu_pid;
+ QTestState *s;
+
+ s = qtest_init_internal(NULL, NULL, true, qtest_attach_qemu, opaque);
+ qts->qemu_pid = -1;
+ qtest_qmp_handshake(s, NULL);
+ return s;
+}
+
QTestState *qtest_init(const char *extra_args)
{
return qtest_init_ext(NULL, extra_args, NULL, true);
@@ -1630,7 +1672,8 @@ static void qtest_free_machine_list(struct MachInfo *machines)
static struct MachInfo *qtest_get_machines(const char *var)
{
static struct MachInfo *machines;
- static char *qemu_var;
+ static char *qemu_bin;
+ const char *new_qemu_bin;
QDict *response, *minfo;
QList *list;
const QListEntry *p;
@@ -1639,9 +1682,10 @@ static struct MachInfo *qtest_get_machines(const char *var)
QTestState *qts;
int idx;
- if (g_strcmp0(qemu_var, var)) {
- g_free(qemu_var);
- qemu_var = g_strdup(var);
+ new_qemu_bin = qtest_qemu_binary(var);
+ if (g_strcmp0(qemu_bin, new_qemu_bin)) {
+ g_free(qemu_bin);
+ qemu_bin = g_strdup(new_qemu_bin);
/* new qemu, clear the cache */
qtest_free_machine_list(machines);
@@ -1654,7 +1698,7 @@ static struct MachInfo *qtest_get_machines(const char *var)
silence_spawn_log = !g_test_verbose();
- qts = qtest_init_ext(qemu_var, "-machine none", NULL, true);
+ qts = qtest_init_ext(var, "-machine none", NULL, true);
response = qtest_qmp(qts, "{ 'execute': 'query-machines' }");
g_assert(response);
list = qdict_get_qlist(response, "return");
diff --git a/tests/qtest/libqtest.h b/tests/qtest/libqtest.h
index b3f2e7f..9c118c8 100644
--- a/tests/qtest/libqtest.h
+++ b/tests/qtest/libqtest.h
@@ -48,6 +48,31 @@ QTestState *qtest_initf(const char *fmt, ...) G_GNUC_PRINTF(1, 2);
QTestState *qtest_vinitf(const char *fmt, va_list ap) G_GNUC_PRINTF(1, 0);
/**
+ * qtest_qemu_binary:
+ * @var: environment variable name
+ *
+ * Look up @var and return its value as the qemu binary path.
+ * If @var is NULL, look up the default var name.
+ */
+const char *qtest_qemu_binary(const char *var);
+
+/**
+ * qtest_init_after_exec:
+ * @qts: the previous QEMU state
+ *
+ * Return a test state representing new QEMU after @qts exec's it.
+ */
+QTestState *qtest_init_after_exec(QTestState *qts);
+
+/**
+ * qtest_qemu_args:
+ * @extra_args: Other arguments to pass to QEMU.
+ *
+ * Return the command line used to start QEMU, sans binary.
+ */
+gchar *qtest_qemu_args(const char *extra_args);
+
+/**
* qtest_init:
* @extra_args: other arguments to pass to QEMU. CAUTION: these
* arguments are subject to word splitting and shell evaluation.
@@ -977,7 +1002,7 @@ void qtest_qmp_fds_assert_success(QTestState *qts, int *fds, size_t nfds,
* @cb: Pointer to the callback function
* @skip_old_versioned: true if versioned old machine types should be skipped
*
- * Call a callback function for every name of all available machines.
+ * Call a callback function for every name of all available machines.
*/
void qtest_cb_for_every_machine(void (*cb)(const char *machine),
bool skip_old_versioned);
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 7daf619..669d07c 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -148,6 +148,7 @@ qtests_hppa = \
qtests_loongarch64 = qtests_filter + \
(config_all_devices.has_key('CONFIG_LOONGARCH_VIRT') ? ['numa-test'] : []) + \
+ (unpack_edk2_blobs ? ['bios-tables-test'] : []) + \
['boot-serial-test',
'cpu-plug-test']
@@ -208,15 +209,18 @@ qtests_npcm7xx = \
'npcm7xx_sdhci-test',
'npcm7xx_smbus-test',
'npcm7xx_timer-test',
- 'npcm7xx_watchdog_timer-test',
- 'npcm_gmac-test'] + \
+ 'npcm7xx_watchdog_timer-test'] + \
(slirp.found() ? ['npcm7xx_emc-test'] : [])
+qtests_npcm8xx = \
+ ['npcm_gmac-test']
qtests_aspeed = \
- ['aspeed_hace-test',
- 'aspeed_smc-test',
- 'aspeed_gpio-test']
+ ['aspeed_gpio-test',
+ 'aspeed_hace-test',
+ 'aspeed_scu-test',
+ 'aspeed_smc-test']
qtests_aspeed64 = \
['ast2700-gpio-test',
+ 'ast2700-hace-test',
'ast2700-smc-test']
qtests_stm32l4x5 = \
@@ -258,6 +262,8 @@ qtests_aarch64 = \
(config_all_accel.has_key('CONFIG_TCG') and \
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
(config_all_devices.has_key('CONFIG_ASPEED_SOC') ? qtests_aspeed64 : []) + \
+ (config_all_devices.has_key('CONFIG_NPCM8XX') ? qtests_npcm8xx : []) + \
+ qtests_cxl + \
['arm-cpu-features',
'numa-test',
'boot-serial-test',
@@ -361,6 +367,10 @@ if gnutls.found()
endif
qtests = {
+ 'aspeed_hace-test': files('aspeed-hace-utils.c', 'aspeed_hace-test.c'),
+ 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
+ 'ast2700-hace-test': files('aspeed-hace-utils.c', 'ast2700-hace-test.c'),
+ 'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
'bios-tables-test': [io, 'boot-sector.c', 'acpi-utils.c', 'tpm-emu.c'],
'cdrom-test': files('boot-sector.c'),
'dbus-vmstate-test': files('migration/migration-qmp.c',
@@ -382,8 +392,6 @@ qtests = {
'virtio-net-failover': migration_files,
'vmgenid-test': files('boot-sector.c', 'acpi-utils.c'),
'netdev-socket': files('netdev-socket.c', '../unit/socket-helpers.c'),
- 'aspeed_smc-test': files('aspeed-smc-utils.c', 'aspeed_smc-test.c'),
- 'ast2700-smc-test': files('aspeed-smc-utils.c', 'ast2700-smc-test.c'),
}
if vnc.found()
diff --git a/tests/qtest/migration-helpers.c b/tests/qtest/migration-helpers.c
deleted file mode 100644
index b08b49b..0000000
--- a/tests/qtest/migration-helpers.c
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * QTest migration helpers
- *
- * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
- * based on the vhost-user-test.c that is:
- * Copyright (c) 2014 Virtual Open Systems Sarl.
- *
- * This work is licensed under the terms of the GNU GPL, version 2 or later.
- * See the COPYING file in the top-level directory.
- *
- */
-
-#include "qemu/osdep.h"
-#include "qemu/ctype.h"
-#include "qobject/qjson.h"
-#include "qapi/qapi-visit-sockets.h"
-#include "qapi/qobject-input-visitor.h"
-#include "qapi/error.h"
-#include "qobject/qlist.h"
-#include "qemu/cutils.h"
-#include "qemu/memalign.h"
-
-#include "migration-helpers.h"
-
-/*
- * Number of seconds we wait when looking for migration
- * status changes, to avoid test suite hanging forever
- * when things go wrong. Needs to be higher enough to
- * avoid false positives on loaded hosts.
- */
-#define MIGRATION_STATUS_WAIT_TIMEOUT 120
-
-static char *SocketAddress_to_str(SocketAddress *addr)
-{
- switch (addr->type) {
- case SOCKET_ADDRESS_TYPE_INET:
- return g_strdup_printf("tcp:%s:%s",
- addr->u.inet.host,
- addr->u.inet.port);
- case SOCKET_ADDRESS_TYPE_UNIX:
- return g_strdup_printf("unix:%s",
- addr->u.q_unix.path);
- case SOCKET_ADDRESS_TYPE_FD:
- return g_strdup_printf("fd:%s", addr->u.fd.str);
- case SOCKET_ADDRESS_TYPE_VSOCK:
- return g_strdup_printf("vsock:%s:%s",
- addr->u.vsock.cid,
- addr->u.vsock.port);
- default:
- return g_strdup("unknown address type");
- }
-}
-
-static QDict *SocketAddress_to_qdict(SocketAddress *addr)
-{
- QDict *dict = qdict_new();
-
- switch (addr->type) {
- case SOCKET_ADDRESS_TYPE_INET:
- qdict_put_str(dict, "type", "inet");
- qdict_put_str(dict, "host", addr->u.inet.host);
- qdict_put_str(dict, "port", addr->u.inet.port);
- break;
- case SOCKET_ADDRESS_TYPE_UNIX:
- qdict_put_str(dict, "type", "unix");
- qdict_put_str(dict, "path", addr->u.q_unix.path);
- break;
- case SOCKET_ADDRESS_TYPE_FD:
- qdict_put_str(dict, "type", "fd");
- qdict_put_str(dict, "str", addr->u.fd.str);
- break;
- case SOCKET_ADDRESS_TYPE_VSOCK:
- qdict_put_str(dict, "type", "vsock");
- qdict_put_str(dict, "cid", addr->u.vsock.cid);
- qdict_put_str(dict, "port", addr->u.vsock.port);
- break;
- default:
- g_assert_not_reached();
- }
-
- return dict;
-}
-
-static SocketAddressList *migrate_get_socket_address(QTestState *who)
-{
- QDict *rsp;
- SocketAddressList *addrs;
- Visitor *iv = NULL;
- QObject *object;
-
- rsp = migrate_query(who);
- object = qdict_get(rsp, "socket-address");
-
- iv = qobject_input_visitor_new(object);
- visit_type_SocketAddressList(iv, NULL, &addrs, &error_abort);
- visit_free(iv);
-
- qobject_unref(rsp);
- return addrs;
-}
-
-static char *
-migrate_get_connect_uri(QTestState *who)
-{
- SocketAddressList *addrs;
- char *connect_uri;
-
- addrs = migrate_get_socket_address(who);
- connect_uri = SocketAddress_to_str(addrs->value);
-
- qapi_free_SocketAddressList(addrs);
- return connect_uri;
-}
-
-static QDict *
-migrate_get_connect_qdict(QTestState *who)
-{
- SocketAddressList *addrs;
- QDict *connect_qdict;
-
- addrs = migrate_get_socket_address(who);
- connect_qdict = SocketAddress_to_qdict(addrs->value);
-
- qapi_free_SocketAddressList(addrs);
- return connect_qdict;
-}
-
-static void migrate_set_ports(QTestState *to, QList *channel_list)
-{
- QDict *addr;
- QListEntry *entry;
- const char *addr_port = NULL;
-
- addr = migrate_get_connect_qdict(to);
-
- QLIST_FOREACH_ENTRY(channel_list, entry) {
- QDict *channel = qobject_to(QDict, qlist_entry_obj(entry));
- QDict *addrdict = qdict_get_qdict(channel, "addr");
-
- if (qdict_haskey(addrdict, "port") &&
- qdict_haskey(addr, "port") &&
- (strcmp(qdict_get_str(addrdict, "port"), "0") == 0)) {
- addr_port = qdict_get_str(addr, "port");
- qdict_put_str(addrdict, "port", addr_port);
- }
- }
-
- qobject_unref(addr);
-}
-
-bool migrate_watch_for_events(QTestState *who, const char *name,
- QDict *event, void *opaque)
-{
- QTestMigrationState *state = opaque;
-
- if (g_str_equal(name, "STOP")) {
- state->stop_seen = true;
- return true;
- } else if (g_str_equal(name, "SUSPEND")) {
- state->suspend_seen = true;
- return true;
- } else if (g_str_equal(name, "RESUME")) {
- state->resume_seen = true;
- return true;
- }
-
- return false;
-}
-
-void migrate_qmp_fail(QTestState *who, const char *uri,
- const char *channels, const char *fmt, ...)
-{
- va_list ap;
- QDict *args, *err;
-
- va_start(ap, fmt);
- args = qdict_from_vjsonf_nofail(fmt, ap);
- va_end(ap);
-
- g_assert(!qdict_haskey(args, "uri"));
- if (uri) {
- qdict_put_str(args, "uri", uri);
- }
-
- g_assert(!qdict_haskey(args, "channels"));
- if (channels) {
- QObject *channels_obj = qobject_from_json(channels, &error_abort);
- qdict_put_obj(args, "channels", channels_obj);
- }
-
- err = qtest_qmp_assert_failure_ref(
- who, "{ 'execute': 'migrate', 'arguments': %p}", args);
-
- g_assert(qdict_haskey(err, "desc"));
-
- qobject_unref(err);
-}
-
-/*
- * Send QMP command "migrate".
- * Arguments are built from @fmt... (formatted like
- * qobject_from_jsonf_nofail()) with "uri": @uri spliced in.
- */
-void migrate_qmp(QTestState *who, QTestState *to, const char *uri,
- const char *channels, const char *fmt, ...)
-{
- va_list ap;
- QDict *args;
- g_autofree char *connect_uri = NULL;
-
- va_start(ap, fmt);
- args = qdict_from_vjsonf_nofail(fmt, ap);
- va_end(ap);
-
- g_assert(!qdict_haskey(args, "uri"));
- if (uri) {
- qdict_put_str(args, "uri", uri);
- } else if (!channels) {
- connect_uri = migrate_get_connect_uri(to);
- qdict_put_str(args, "uri", connect_uri);
- }
-
- g_assert(!qdict_haskey(args, "channels"));
- if (channels) {
- QObject *channels_obj = qobject_from_json(channels, &error_abort);
- QList *channel_list = qobject_to(QList, channels_obj);
- migrate_set_ports(to, channel_list);
- qdict_put_obj(args, "channels", channels_obj);
- }
-
- qtest_qmp_assert_success(who,
- "{ 'execute': 'migrate', 'arguments': %p}", args);
-}
-
-void migrate_set_capability(QTestState *who, const char *capability,
- bool value)
-{
- qtest_qmp_assert_success(who,
- "{ 'execute': 'migrate-set-capabilities',"
- "'arguments': { "
- "'capabilities': [ { "
- "'capability': %s, 'state': %i } ] } }",
- capability, value);
-}
-
-void migrate_incoming_qmp(QTestState *to, const char *uri, const char *fmt, ...)
-{
- va_list ap;
- QDict *args, *rsp;
-
- va_start(ap, fmt);
- args = qdict_from_vjsonf_nofail(fmt, ap);
- va_end(ap);
-
- g_assert(!qdict_haskey(args, "uri"));
- qdict_put_str(args, "uri", uri);
-
- /* This function relies on the event to work, make sure it's enabled */
- migrate_set_capability(to, "events", true);
-
- rsp = qtest_qmp(to, "{ 'execute': 'migrate-incoming', 'arguments': %p}",
- args);
-
- if (!qdict_haskey(rsp, "return")) {
- g_autoptr(GString) s = qobject_to_json_pretty(QOBJECT(rsp), true);
- g_test_message("%s", s->str);
- }
-
- g_assert(qdict_haskey(rsp, "return"));
- qobject_unref(rsp);
-
- migration_event_wait(to, "setup");
-}
-
-/*
- * Note: caller is responsible to free the returned object via
- * qobject_unref() after use
- */
-QDict *migrate_query(QTestState *who)
-{
- return qtest_qmp_assert_success_ref(who, "{ 'execute': 'query-migrate' }");
-}
-
-QDict *migrate_query_not_failed(QTestState *who)
-{
- const char *status;
- QDict *rsp = migrate_query(who);
- status = qdict_get_str(rsp, "status");
- if (g_str_equal(status, "failed")) {
- g_printerr("query-migrate shows failed migration: %s\n",
- qdict_get_str(rsp, "error-desc"));
- }
- g_assert(!g_str_equal(status, "failed"));
- return rsp;
-}
-
-/*
- * Note: caller is responsible to free the returned object via
- * g_free() after use
- */
-static gchar *migrate_query_status(QTestState *who)
-{
- QDict *rsp_return = migrate_query(who);
- gchar *status = g_strdup(qdict_get_str(rsp_return, "status"));
-
- g_assert(status);
- qobject_unref(rsp_return);
-
- return status;
-}
-
-static bool check_migration_status(QTestState *who, const char *goal,
- const char **ungoals)
-{
- bool ready;
- char *current_status;
- const char **ungoal;
-
- current_status = migrate_query_status(who);
- ready = strcmp(current_status, goal) == 0;
- if (!ungoals) {
- g_assert_cmpstr(current_status, !=, "failed");
- /*
- * If looking for a state other than completed,
- * completion of migration would cause the test to
- * hang.
- */
- if (strcmp(goal, "completed") != 0) {
- g_assert_cmpstr(current_status, !=, "completed");
- }
- } else {
- for (ungoal = ungoals; *ungoal; ungoal++) {
- g_assert_cmpstr(current_status, !=, *ungoal);
- }
- }
- g_free(current_status);
- return ready;
-}
-
-void wait_for_migration_status(QTestState *who,
- const char *goal, const char **ungoals)
-{
- g_test_timer_start();
- while (!check_migration_status(who, goal, ungoals)) {
- usleep(1000);
-
- g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT);
- }
-}
-
-void wait_for_migration_complete(QTestState *who)
-{
- wait_for_migration_status(who, "completed", NULL);
-}
-
-void wait_for_migration_fail(QTestState *from, bool allow_active)
-{
- g_test_timer_start();
- QDict *rsp_return;
- char *status;
- bool failed;
-
- do {
- status = migrate_query_status(from);
- bool result = !strcmp(status, "setup") || !strcmp(status, "failed") ||
- (allow_active && !strcmp(status, "active"));
- if (!result) {
- fprintf(stderr, "%s: unexpected status status=%s allow_active=%d\n",
- __func__, status, allow_active);
- }
- g_assert(result);
- failed = !strcmp(status, "failed");
- g_free(status);
-
- g_assert(g_test_timer_elapsed() < MIGRATION_STATUS_WAIT_TIMEOUT);
- } while (!failed);
-
- /* Is the machine currently running? */
- rsp_return = qtest_qmp_assert_success_ref(from,
- "{ 'execute': 'query-status' }");
- g_assert(qdict_haskey(rsp_return, "running"));
- g_assert(qdict_get_bool(rsp_return, "running"));
- qobject_unref(rsp_return);
-}
-
-char *find_common_machine_version(const char *mtype, const char *var1,
- const char *var2)
-{
- g_autofree char *type1 = qtest_resolve_machine_alias(var1, mtype);
- g_autofree char *type2 = qtest_resolve_machine_alias(var2, mtype);
-
- g_assert(type1 && type2);
-
- if (g_str_equal(type1, type2)) {
- /* either can be used */
- return g_strdup(type1);
- }
-
- if (qtest_has_machine_with_env(var2, type1)) {
- return g_strdup(type1);
- }
-
- if (qtest_has_machine_with_env(var1, type2)) {
- return g_strdup(type2);
- }
-
- g_test_message("No common machine version for machine type '%s' between "
- "binaries %s and %s", mtype, getenv(var1), getenv(var2));
- g_assert_not_reached();
-}
-
-char *resolve_machine_version(const char *alias, const char *var1,
- const char *var2)
-{
- const char *mname = g_getenv("QTEST_QEMU_MACHINE_TYPE");
- g_autofree char *machine_name = NULL;
-
- if (mname) {
- const char *dash = strrchr(mname, '-');
- const char *dot = strrchr(mname, '.');
-
- machine_name = g_strdup(mname);
-
- if (dash && dot) {
- assert(qtest_has_machine(machine_name));
- return g_steal_pointer(&machine_name);
- }
- /* else: probably an alias, let it be resolved below */
- } else {
- /* use the hardcoded alias */
- machine_name = g_strdup(alias);
- }
-
- return find_common_machine_version(machine_name, var1, var2);
-}
-
-typedef struct {
- char *name;
- void (*func)(void);
-} MigrationTest;
-
-static void migration_test_destroy(gpointer data)
-{
- MigrationTest *test = (MigrationTest *)data;
-
- g_free(test->name);
- g_free(test);
-}
-
-static void migration_test_wrapper(const void *data)
-{
- MigrationTest *test = (MigrationTest *)data;
-
- g_test_message("Running /%s%s", qtest_get_arch(), test->name);
- test->func();
-}
-
-void migration_test_add(const char *path, void (*fn)(void))
-{
- MigrationTest *test = g_new0(MigrationTest, 1);
-
- test->func = fn;
- test->name = g_strdup(path);
-
- qtest_add_data_func_full(path, test, migration_test_wrapper,
- migration_test_destroy);
-}
-
-#ifdef O_DIRECT
-/*
- * Probe for O_DIRECT support on the filesystem. Since this is used
- * for tests, be conservative, if anything fails, assume it's
- * unsupported.
- */
-bool probe_o_direct_support(const char *tmpfs)
-{
- g_autofree char *filename = g_strdup_printf("%s/probe-o-direct", tmpfs);
- int fd, flags = O_CREAT | O_RDWR | O_TRUNC | O_DIRECT;
- void *buf;
- ssize_t ret, len;
- uint64_t offset;
-
- fd = open(filename, flags, 0660);
- if (fd < 0) {
- unlink(filename);
- return false;
- }
-
- /*
- * Using 1MB alignment as conservative choice to satisfy any
- * plausible architecture default page size, and/or filesystem
- * alignment restrictions.
- */
- len = 0x100000;
- offset = 0x100000;
-
- buf = qemu_try_memalign(len, len);
- g_assert(buf);
-
- ret = pwrite(fd, buf, len, offset);
- unlink(filename);
- g_free(buf);
-
- if (ret < 0) {
- return false;
- }
-
- return true;
-}
-#endif
-
-/*
- * Wait for a "MIGRATION" event. This is what Libvirt uses to track
- * migration status changes.
- */
-void migration_event_wait(QTestState *s, const char *target)
-{
- QDict *response, *data;
- const char *status;
- bool found;
-
- do {
- response = qtest_qmp_eventwait_ref(s, "MIGRATION");
- data = qdict_get_qdict(response, "data");
- g_assert(data);
- status = qdict_get_str(data, "status");
- found = (strcmp(status, target) == 0);
- qobject_unref(response);
- } while (!found);
-}
diff --git a/tests/qtest/migration/bootfile.c b/tests/qtest/migration/bootfile.c
index fac059d..479c432 100644
--- a/tests/qtest/migration/bootfile.c
+++ b/tests/qtest/migration/bootfile.c
@@ -68,3 +68,8 @@ char *bootfile_create(const char *arch, const char *dir, bool suspend_me)
return bootpath;
}
+
+char *bootfile_get(void)
+{
+ return bootpath;
+}
diff --git a/tests/qtest/migration/bootfile.h b/tests/qtest/migration/bootfile.h
index 6d6a673..96e784b 100644
--- a/tests/qtest/migration/bootfile.h
+++ b/tests/qtest/migration/bootfile.h
@@ -35,5 +35,6 @@
void bootfile_delete(void);
char *bootfile_create(const char *arch, const char *dir, bool suspend_me);
+char *bootfile_get(void);
#endif /* BOOTFILE_H */
diff --git a/tests/qtest/migration/compression-tests.c b/tests/qtest/migration/compression-tests.c
index 41e79f0..b827665 100644
--- a/tests/qtest/migration/compression-tests.c
+++ b/tests/qtest/migration/compression-tests.c
@@ -42,6 +42,20 @@ static void test_multifd_tcp_zstd(void)
};
test_precopy_common(&args);
}
+
+static void test_multifd_postcopy_tcp_zstd(void)
+{
+ MigrateCommon args = {
+ .listen_uri = "defer",
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true,
+ },
+ .start_hook = migrate_hook_start_precopy_tcp_multifd_zstd,
+ };
+
+ test_precopy_common(&args);
+}
#endif /* CONFIG_ZSTD */
#ifdef CONFIG_QATZIP
@@ -184,6 +198,10 @@ void migration_test_add_compression(MigrationTestEnv *env)
#ifdef CONFIG_ZSTD
migration_test_add("/migration/multifd/tcp/plain/zstd",
test_multifd_tcp_zstd);
+ if (env->has_uffd) {
+ migration_test_add("/migration/multifd+postcopy/tcp/plain/zstd",
+ test_multifd_postcopy_tcp_zstd);
+ }
#endif
#ifdef CONFIG_QATZIP
diff --git a/tests/qtest/migration/cpr-tests.c b/tests/qtest/migration/cpr-tests.c
index 5536e14..9388ad6 100644
--- a/tests/qtest/migration/cpr-tests.c
+++ b/tests/qtest/migration/cpr-tests.c
@@ -60,13 +60,12 @@ static void test_mode_transfer_common(bool incoming_defer)
g_autofree char *cpr_path = g_strdup_printf("%s/cpr.sock", tmpfs);
g_autofree char *mig_path = g_strdup_printf("%s/migsocket", tmpfs);
g_autofree char *uri = g_strdup_printf("unix:%s", mig_path);
+ g_autofree char *opts_target = NULL;
const char *opts = "-machine aux-ram-share=on -nodefaults";
g_autofree const char *cpr_channel = g_strdup_printf(
"cpr,addr.transport=socket,addr.type=unix,addr.path=%s",
cpr_path);
- g_autofree char *opts_target = g_strdup_printf("-incoming %s %s",
- cpr_channel, opts);
g_autofree char *connect_channels = g_strdup_printf(
"[ { 'channel-type': 'main',"
@@ -75,6 +74,17 @@ static void test_mode_transfer_common(bool incoming_defer)
" 'path': '%s' } } ]",
mig_path);
+ /*
+ * Set up a UNIX domain socket for the CPR channel before
+ * launching the destination VM, to avoid timing issues
+ * during connection setup.
+ */
+ int cpr_sockfd = qtest_socket_server(cpr_path);
+ g_assert(cpr_sockfd >= 0);
+
+ opts_target = g_strdup_printf("-incoming cpr,addr.transport=socket,"
+ "addr.type=fd,addr.str=%d %s",
+ cpr_sockfd, opts);
MigrateCommon args = {
.start.opts_source = opts,
.start.opts_target = opts_target,
@@ -87,7 +97,10 @@ static void test_mode_transfer_common(bool incoming_defer)
.start_hook = test_mode_transfer_start,
};
- test_precopy_common(&args);
+ if (test_precopy_common(&args) < 0) {
+ close(cpr_sockfd);
+ unlink(cpr_path);
+ }
}
static void test_mode_transfer(void)
@@ -100,6 +113,138 @@ static void test_mode_transfer_defer(void)
test_mode_transfer_common(true);
}
+static void set_cpr_exec_args(QTestState *who, MigrateCommon *args)
+{
+ g_autofree char *qtest_from_args = NULL;
+ g_autofree char *from_args = NULL;
+ g_autofree char *to_args = NULL;
+ g_autofree char *exec_args = NULL;
+ g_auto(GStrv) argv = NULL;
+ char *from_str, *src, *dst;
+ int ret;
+
+ /*
+ * hide_stderr appends "2>/dev/null" to the command line, but cpr-exec
+ * passes the command-line words to execv, not to the shell, so suppress it
+ * here. fd 2 was already bound in the source VM, and execv preserves it.
+ */
+ g_assert(args->start.hide_stderr == false);
+
+ ret = migrate_args(&from_args, &to_args, args->listen_uri, &args->start);
+ g_assert(!ret);
+ qtest_from_args = qtest_qemu_args(from_args);
+
+ /*
+ * The generated args may have been formatted using "%s %s" with empty
+ * strings, which can produce consecutive spaces, which g_strsplit would
+ * convert into empty strings. Ditto for leading and trailing space.
+ * De-dup spaces to avoid that.
+ */
+
+ from_str = src = dst = g_strstrip(qtest_from_args);
+ do {
+ if (*src != ' ' || src[-1] != ' ') {
+ *dst++ = *src;
+ }
+ } while (*src++);
+
+ exec_args = g_strconcat(qtest_qemu_binary(migration_get_env()->qemu_dst),
+ " -incoming defer ", from_str, NULL);
+ argv = g_strsplit(exec_args, " ", -1);
+ migrate_set_parameter_strv(who, "cpr-exec-command", argv);
+}
+
+static void wait_for_migration_event(QTestState *who, const char *waitfor)
+{
+ QDict *rsp, *data;
+ char *status;
+ bool done = false;
+
+ while (!done) {
+ rsp = qtest_qmp_eventwait_ref(who, "MIGRATION");
+ g_assert(qdict_haskey(rsp, "data"));
+ data = qdict_get_qdict(rsp, "data");
+ g_assert(qdict_haskey(data, "status"));
+ status = g_strdup(qdict_get_str(data, "status"));
+ g_assert(strcmp(status, "failed"));
+ done = !strcmp(status, waitfor);
+ qobject_unref(rsp);
+ }
+}
+
+static void test_cpr_exec(MigrateCommon *args)
+{
+ QTestState *from, *to;
+ void *data_hook = NULL;
+ g_autofree char *connect_uri = g_strdup(args->connect_uri);
+ g_autofree char *filename = g_strdup_printf("%s/%s", tmpfs,
+ FILE_TEST_FILENAME);
+
+ if (migrate_start(&from, NULL, args->listen_uri, &args->start)) {
+ return;
+ }
+
+ /* Source and dest never run concurrently */
+ g_assert_false(args->live);
+
+ if (args->start_hook) {
+ data_hook = args->start_hook(from, NULL);
+ }
+
+ wait_for_serial("src_serial");
+ set_cpr_exec_args(from, args);
+ migrate_set_capability(from, "events", true);
+ migrate_qmp(from, NULL, connect_uri, NULL, "{}");
+ wait_for_migration_event(from, "completed");
+
+ to = qtest_init_after_exec(from);
+
+ qtest_qmp_assert_success(to, "{ 'execute': 'migrate-incoming',"
+ " 'arguments': { "
+ " 'channels': [ { 'channel-type': 'main',"
+ " 'addr': { 'transport': 'file',"
+ " 'filename': %s,"
+ " 'offset': 0 } } ] } }",
+ filename);
+ wait_for_migration_complete(to);
+
+ wait_for_resume(to, get_dst());
+ /* Device on target is still named src_serial because args do not change */
+ wait_for_serial("src_serial");
+
+ if (args->end_hook) {
+ args->end_hook(from, to, data_hook);
+ }
+
+ migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
+}
+
+static void *test_mode_exec_start(QTestState *from, QTestState *to)
+{
+ assert(!to);
+ migrate_set_parameter_str(from, "mode", "cpr-exec");
+ return NULL;
+}
+
+static void test_mode_exec(void)
+{
+ g_autofree char *uri = g_strdup_printf("file:%s/%s", tmpfs,
+ FILE_TEST_FILENAME);
+ g_autofree char *listen_uri = g_strdup_printf("defer");
+
+ MigrateCommon args = {
+ .start.only_source = true,
+ .start.opts_source = "-machine aux-ram-share=on -nodefaults",
+ .start.memory_backend = "-object memory-backend-memfd,id=pc.ram,size=%s"
+ " -machine memory-backend=pc.ram",
+ .connect_uri = uri,
+ .listen_uri = listen_uri,
+ .start_hook = test_mode_exec_start,
+ };
+
+ test_cpr_exec(&args);
+}
+
void migration_test_add_cpr(MigrationTestEnv *env)
{
tmpfs = env->tmpfs;
@@ -122,5 +267,6 @@ void migration_test_add_cpr(MigrationTestEnv *env)
migration_test_add("/migration/mode/transfer", test_mode_transfer);
migration_test_add("/migration/mode/transfer/defer",
test_mode_transfer_defer);
+ migration_test_add("/migration/mode/exec", test_mode_exec);
}
}
diff --git a/tests/qtest/migration/framework.c b/tests/qtest/migration/framework.c
index 407c902..a9be9c2 100644
--- a/tests/qtest/migration/framework.c
+++ b/tests/qtest/migration/framework.c
@@ -234,7 +234,7 @@ static void migrate_start_set_capabilities(QTestState *from, QTestState *to,
* to mimic as closer as that.
*/
migrate_set_capability(from, "events", true);
- if (!args->defer_target_connect) {
+ if (!args->defer_target_connect && to) {
migrate_set_capability(to, "events", true);
}
@@ -246,20 +246,26 @@ static void migrate_start_set_capabilities(QTestState *from, QTestState *to,
if (args->caps[MIGRATION_CAPABILITY_MULTIFD]) {
migrate_set_parameter_int(from, "multifd-channels",
MULTIFD_TEST_CHANNELS);
- migrate_set_parameter_int(to, "multifd-channels",
- MULTIFD_TEST_CHANNELS);
+ if (to) {
+ migrate_set_parameter_int(to, "multifd-channels",
+ MULTIFD_TEST_CHANNELS);
+ }
}
return;
}
-int migrate_start(QTestState **from, QTestState **to, const char *uri,
- MigrateStart *args)
+static char *test_shmem_path(void)
+{
+ return g_strdup_printf("/dev/shm/qemu-%d", getpid());
+}
+
+int migrate_args(char **from, char **to, const char *uri, MigrateStart *args)
{
/* options for source and target */
g_autofree gchar *arch_opts = NULL;
- g_autofree gchar *cmd_source = NULL;
- g_autofree gchar *cmd_target = NULL;
+ gchar *cmd_source = NULL;
+ gchar *cmd_target = NULL;
const gchar *ignore_stderr;
g_autofree char *shmem_opts = NULL;
g_autofree char *shmem_path = NULL;
@@ -268,23 +274,10 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
const char *memory_size;
const char *machine_alias, *machine_opts = "";
g_autofree char *machine = NULL;
- const char *bootpath;
- g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
+ const char *bootpath = bootfile_get();
g_autofree char *memory_backend = NULL;
const char *events;
- if (args->use_shmem) {
- if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
- g_test_skip("/dev/shm is not supported");
- return -1;
- }
- }
-
- dst_state = (QTestMigrationState) { };
- src_state = (QTestMigrationState) { };
- bootpath = bootfile_create(arch, tmpfs, args->suspend_me);
- src_state.suspend_me = args->suspend_me;
-
if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
memory_size = "150M";
@@ -340,7 +333,7 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
}
if (args->use_shmem) {
- shmem_path = g_strdup_printf("/dev/shm/qemu-%d", getpid());
+ shmem_path = test_shmem_path();
shmem_opts = g_strdup_printf(
"-object memory-backend-file,id=mem0,size=%s"
",mem-path=%s,share=on -numa node,memdev=mem0",
@@ -381,12 +374,6 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
shmem_opts ? shmem_opts : "",
args->opts_source ? args->opts_source : "",
ignore_stderr);
- if (!args->only_target) {
- *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
- qtest_qmp_set_event_callback(*from,
- migrate_watch_for_events,
- &src_state);
- }
/*
* If the monitor connection is deferred, enable events on the command line
@@ -410,21 +397,62 @@ int migrate_start(QTestState **from, QTestState **to, const char *uri,
shmem_opts ? shmem_opts : "",
args->opts_target ? args->opts_target : "",
ignore_stderr);
- *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
- !args->defer_target_connect);
- qtest_qmp_set_event_callback(*to,
- migrate_watch_for_events,
- &dst_state);
+
+ *from = cmd_source;
+ *to = cmd_target;
+ return 0;
+}
+
+int migrate_start(QTestState **from, QTestState **to, const char *uri,
+ MigrateStart *args)
+{
+ g_autofree gchar *cmd_source = NULL;
+ g_autofree gchar *cmd_target = NULL;
+ g_autoptr(QList) capabilities = migrate_start_get_qmp_capabilities(args);
+
+ if (args->use_shmem) {
+ if (!g_file_test("/dev/shm", G_FILE_TEST_IS_DIR)) {
+ g_test_skip("/dev/shm is not supported");
+ return -1;
+ }
+ }
+
+ dst_state = (QTestMigrationState) { };
+ src_state = (QTestMigrationState) { };
+ bootfile_create(qtest_get_arch(), tmpfs, args->suspend_me);
+ src_state.suspend_me = args->suspend_me;
+
+ if (migrate_args(&cmd_source, &cmd_target, uri, args)) {
+ return -1;
+ }
+
+ if (!args->only_target) {
+ *from = qtest_init_ext(QEMU_ENV_SRC, cmd_source, capabilities, true);
+ qtest_qmp_set_event_callback(*from,
+ migrate_watch_for_events,
+ &src_state);
+ }
+
+ if (!args->only_source) {
+ *to = qtest_init_ext(QEMU_ENV_DST, cmd_target, capabilities,
+ !args->defer_target_connect);
+ qtest_qmp_set_event_callback(*to,
+ migrate_watch_for_events,
+ &dst_state);
+ }
/*
* Remove shmem file immediately to avoid memory leak in test failed case.
* It's valid because QEMU has already opened this file
*/
if (args->use_shmem) {
+ g_autofree char *shmem_path = test_shmem_path();
unlink(shmem_path);
}
- migrate_start_set_capabilities(*from, *to, args);
+ migrate_start_set_capabilities(*from,
+ args->only_source ? NULL : *to,
+ args);
return 0;
}
@@ -736,7 +764,7 @@ void test_postcopy_recovery_common(MigrateCommon *args)
migrate_postcopy_complete(from, to, args);
}
-void test_precopy_common(MigrateCommon *args)
+int test_precopy_common(MigrateCommon *args)
{
QTestState *from, *to;
void *data_hook = NULL;
@@ -746,7 +774,7 @@ void test_precopy_common(MigrateCommon *args)
g_assert(!args->cpr_channel || args->connect_channels);
if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
- return;
+ return -1;
}
if (args->start_hook) {
@@ -869,6 +897,8 @@ finish:
}
migrate_end(from, to, args->result == MIG_TEST_SUCCEED);
+
+ return 0;
}
static void file_dirty_offset_region(void)
@@ -994,6 +1024,11 @@ QTestMigrationState *get_src(void)
return &src_state;
}
+QTestMigrationState *get_dst(void)
+{
+ return &dst_state;
+}
+
MigrationTestEnv *migration_get_env(void)
{
static MigrationTestEnv *env;
diff --git a/tests/qtest/migration/framework.h b/tests/qtest/migration/framework.h
index 01e425e..9bb584a 100644
--- a/tests/qtest/migration/framework.h
+++ b/tests/qtest/migration/framework.h
@@ -103,6 +103,8 @@ typedef struct {
*/
bool hide_stderr;
bool use_shmem;
+ /* only launch the source process */
+ bool only_source;
/* only launch the target process */
bool only_target;
/* Use dirty ring if true; dirty logging otherwise */
@@ -221,13 +223,15 @@ typedef struct {
void wait_for_serial(const char *side);
void migrate_prepare_for_dirty_mem(QTestState *from);
void migrate_wait_for_dirty_mem(QTestState *from, QTestState *to);
+
+int migrate_args(char **from, char **to, const char *uri, MigrateStart *args);
int migrate_start(QTestState **from, QTestState **to, const char *uri,
MigrateStart *args);
void migrate_end(QTestState *from, QTestState *to, bool test_dest);
void test_postcopy_common(MigrateCommon *args);
void test_postcopy_recovery_common(MigrateCommon *args);
-void test_precopy_common(MigrateCommon *args);
+int test_precopy_common(MigrateCommon *args);
void test_file_common(MigrateCommon *args, bool stop_src);
void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
QTestState *to,
@@ -235,6 +239,7 @@ void *migrate_hook_start_precopy_tcp_multifd_common(QTestState *from,
typedef struct QTestMigrationState QTestMigrationState;
QTestMigrationState *get_src(void);
+QTestMigrationState *get_dst(void);
#ifdef CONFIG_GNUTLS
void migration_test_add_tls(MigrationTestEnv *env);
diff --git a/tests/qtest/migration/migration-qmp.c b/tests/qtest/migration/migration-qmp.c
index fb59741..c803fce 100644
--- a/tests/qtest/migration/migration-qmp.c
+++ b/tests/qtest/migration/migration-qmp.c
@@ -358,6 +358,11 @@ void read_blocktime(QTestState *who)
rsp_return = migrate_query_not_failed(who);
g_assert(qdict_haskey(rsp_return, "postcopy-blocktime"));
+ g_assert(qdict_haskey(rsp_return, "postcopy-vcpu-blocktime"));
+ g_assert(qdict_haskey(rsp_return, "postcopy-latency"));
+ g_assert(qdict_haskey(rsp_return, "postcopy-latency-dist"));
+ g_assert(qdict_haskey(rsp_return, "postcopy-vcpu-latency"));
+ g_assert(qdict_haskey(rsp_return, "postcopy-non-vcpu-latency"));
qobject_unref(rsp_return);
}
@@ -437,6 +442,22 @@ void migrate_set_parameter_str(QTestState *who, const char *parameter,
migrate_check_parameter_str(who, parameter, value);
}
+void migrate_set_parameter_strv(QTestState *who, const char *parameter,
+ char **strv)
+{
+ g_autofree char *args = g_strjoinv("\",\"", strv);
+ g_autoptr(GString) value = g_string_new("");
+ g_autofree char *command = NULL;
+
+ g_string_printf(value, "\"%s\"", args);
+
+ command = g_strdup_printf("{ 'execute': 'migrate-set-parameters',"
+ "'arguments': { %%s: [ %s ]}}",
+ value->str);
+
+ qtest_qmp_assert_success(who, command, parameter);
+}
+
static long long migrate_get_parameter_bool(QTestState *who,
const char *parameter)
{
diff --git a/tests/qtest/migration/migration-qmp.h b/tests/qtest/migration/migration-qmp.h
index faa8181..44482d2 100644
--- a/tests/qtest/migration/migration-qmp.h
+++ b/tests/qtest/migration/migration-qmp.h
@@ -34,6 +34,8 @@ void read_blocktime(QTestState *who);
void wait_for_migration_pass(QTestState *who, QTestMigrationState *src_state);
void migrate_set_parameter_str(QTestState *who, const char *parameter,
const char *value);
+void migrate_set_parameter_strv(QTestState *who, const char *parameter,
+ char **strv);
void migrate_set_parameter_bool(QTestState *who, const char *parameter,
int value);
void migrate_ensure_non_converge(QTestState *who);
diff --git a/tests/qtest/migration/postcopy-tests.c b/tests/qtest/migration/postcopy-tests.c
index 483e3ff..3773525 100644
--- a/tests/qtest/migration/postcopy-tests.c
+++ b/tests/qtest/migration/postcopy-tests.c
@@ -94,6 +94,29 @@ static void migration_test_add_postcopy_smoke(MigrationTestEnv *env)
}
}
+static void test_multifd_postcopy(void)
+{
+ MigrateCommon args = {
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ },
+ };
+
+ test_postcopy_common(&args);
+}
+
+static void test_multifd_postcopy_preempt(void)
+{
+ MigrateCommon args = {
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
+ },
+ };
+
+ test_postcopy_common(&args);
+}
+
void migration_test_add_postcopy(MigrationTestEnv *env)
{
migration_test_add_postcopy_smoke(env);
@@ -114,6 +137,10 @@ void migration_test_add_postcopy(MigrationTestEnv *env)
"/migration/postcopy/recovery/double-failures/reconnect",
test_postcopy_recovery_fail_reconnect);
+ migration_test_add("/migration/multifd+postcopy/plain",
+ test_multifd_postcopy);
+ migration_test_add("/migration/multifd+postcopy/preempt/plain",
+ test_multifd_postcopy_preempt);
if (env->is_x86) {
migration_test_add("/migration/postcopy/suspend",
test_postcopy_suspend);
diff --git a/tests/qtest/migration/precopy-tests.c b/tests/qtest/migration/precopy-tests.c
index 87b0a7e..bb38292 100644
--- a/tests/qtest/migration/precopy-tests.c
+++ b/tests/qtest/migration/precopy-tests.c
@@ -101,13 +101,43 @@ static void test_precopy_unix_dirty_ring(void)
#ifdef CONFIG_RDMA
+#include <sys/resource.h>
+
+/*
+ * During migration over RDMA, it will try to pin portions of guest memory,
+ * typically exceeding 100MB in this test, while the remainder will be
+ * transmitted as compressed zero pages.
+ *
+ * REQUIRED_MEMLOCK_SZ indicates the minimal mlock size in the current context.
+ */
+#define REQUIRED_MEMLOCK_SZ (128 << 20) /* 128MB */
+
+/* check 'ulimit -l' */
+static bool mlock_check(void)
+{
+ uid_t uid;
+ struct rlimit rlim;
+
+ uid = getuid();
+ if (uid == 0) {
+ return true;
+ }
+
+ if (getrlimit(RLIMIT_MEMLOCK, &rlim) != 0) {
+ return false;
+ }
+
+ return rlim.rlim_cur >= REQUIRED_MEMLOCK_SZ;
+}
+
#define RDMA_MIGRATION_HELPER "scripts/rdma-migration-helper.sh"
-static int new_rdma_link(char *buffer)
+static int new_rdma_link(char *buffer, bool ipv6)
{
char cmd[256];
bool verbose = g_getenv("QTEST_LOG");
- snprintf(cmd, sizeof(cmd), "%s detect %s", RDMA_MIGRATION_HELPER,
+ snprintf(cmd, sizeof(cmd), "IP_FAMILY=%s %s detect %s",
+ ipv6 ? "ipv6" : "ipv4", RDMA_MIGRATION_HELPER,
verbose ? "" : "2>/dev/null");
FILE *pipe = popen(cmd, "r");
@@ -132,11 +162,16 @@ static int new_rdma_link(char *buffer)
return -1;
}
-static void test_precopy_rdma_plain(void)
+static void __test_precopy_rdma_plain(bool ipv6)
{
char buffer[128] = {};
- if (new_rdma_link(buffer)) {
+ if (!mlock_check()) {
+ g_test_skip("'ulimit -l' is too small, require >=128M");
+ return;
+ }
+
+ if (new_rdma_link(buffer, ipv6)) {
g_test_skip("No rdma link available\n"
"# To enable the test:\n"
"# Run \'" RDMA_MIGRATION_HELPER " setup\' with root to "
@@ -159,6 +194,16 @@ static void test_precopy_rdma_plain(void)
test_precopy_common(&args);
}
+
+static void test_precopy_rdma_plain(void)
+{
+ __test_precopy_rdma_plain(false);
+}
+
+static void test_precopy_rdma_plain_ipv6(void)
+{
+ __test_precopy_rdma_plain(true);
+}
#endif
static void test_precopy_tcp_plain(void)
@@ -524,7 +569,7 @@ static void test_multifd_tcp_channels_none(void)
*
* And see that it works
*/
-static void test_multifd_tcp_cancel(void)
+static void test_multifd_tcp_cancel(bool postcopy_ram)
{
MigrateStart args = {
.hide_stderr = true,
@@ -538,6 +583,11 @@ static void test_multifd_tcp_cancel(void)
migrate_ensure_non_converge(from);
migrate_prepare_for_dirty_mem(from);
+ if (postcopy_ram) {
+ migrate_set_capability(from, "postcopy-ram", true);
+ migrate_set_capability(to, "postcopy-ram", true);
+ }
+
migrate_set_parameter_int(from, "multifd-channels", 16);
migrate_set_parameter_int(to, "multifd-channels", 16);
@@ -579,6 +629,10 @@ static void test_multifd_tcp_cancel(void)
return;
}
+ if (postcopy_ram) {
+ migrate_set_capability(to2, "postcopy-ram", true);
+ }
+
migrate_set_parameter_int(to2, "multifd-channels", 16);
migrate_set_capability(to2, "multifd", true);
@@ -602,6 +656,16 @@ static void test_multifd_tcp_cancel(void)
migrate_end(from, to2, true);
}
+static void test_multifd_precopy_tcp_cancel(void)
+{
+ test_multifd_tcp_cancel(false);
+}
+
+static void test_multifd_postcopy_tcp_cancel(void)
+{
+ test_multifd_tcp_cancel(true);
+}
+
static void test_cancel_src_after_failed(QTestState *from, QTestState *to,
const char *uri, const char *phase)
{
@@ -1188,10 +1252,17 @@ static void migration_test_add_precopy_smoke(MigrationTestEnv *env)
migration_test_add("/migration/multifd/tcp/uri/plain/none",
test_multifd_tcp_uri_none);
migration_test_add("/migration/multifd/tcp/plain/cancel",
- test_multifd_tcp_cancel);
+ test_multifd_precopy_tcp_cancel);
+ if (env->has_uffd) {
+ migration_test_add("/migration/multifd+postcopy/tcp/plain/cancel",
+ test_multifd_postcopy_tcp_cancel);
+ }
+
#ifdef CONFIG_RDMA
migration_test_add("/migration/precopy/rdma/plain",
test_precopy_rdma_plain);
+ migration_test_add("/migration/precopy/rdma/plain/ipv6",
+ test_precopy_rdma_plain_ipv6);
#endif
}
diff --git a/tests/qtest/migration/tls-tests.c b/tests/qtest/migration/tls-tests.c
index 72f44de..21e9fec 100644
--- a/tests/qtest/migration/tls-tests.c
+++ b/tests/qtest/migration/tls-tests.c
@@ -395,6 +395,19 @@ static void test_postcopy_recovery_tls_psk(void)
test_postcopy_recovery_common(&args);
}
+static void test_multifd_postcopy_recovery_tls_psk(void)
+{
+ MigrateCommon args = {
+ .start_hook = migrate_hook_start_tls_psk_match,
+ .end_hook = migrate_hook_end_tls_psk,
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ },
+ };
+
+ test_postcopy_recovery_common(&args);
+}
+
/* This contains preempt+recovery+tls test altogether */
static void test_postcopy_preempt_all(void)
{
@@ -409,6 +422,20 @@ static void test_postcopy_preempt_all(void)
test_postcopy_recovery_common(&args);
}
+static void test_multifd_postcopy_preempt_recovery_tls_psk(void)
+{
+ MigrateCommon args = {
+ .start_hook = migrate_hook_start_tls_psk_match,
+ .end_hook = migrate_hook_end_tls_psk,
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_PREEMPT] = true,
+ },
+ };
+
+ test_postcopy_recovery_common(&args);
+}
+
static void test_precopy_unix_tls_psk(void)
{
g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
@@ -657,6 +684,21 @@ static void test_multifd_tcp_tls_psk_mismatch(void)
test_precopy_common(&args);
}
+static void test_multifd_postcopy_tcp_tls_psk_match(void)
+{
+ MigrateCommon args = {
+ .start = {
+ .caps[MIGRATION_CAPABILITY_MULTIFD] = true,
+ .caps[MIGRATION_CAPABILITY_POSTCOPY_RAM] = true,
+ },
+ .listen_uri = "defer",
+ .start_hook = migrate_hook_start_multifd_tcp_tls_psk_match,
+ .end_hook = migrate_hook_end_tls_psk,
+ };
+
+ test_precopy_common(&args);
+}
+
#ifdef CONFIG_TASN1
static void test_multifd_tcp_tls_x509_default_host(void)
{
@@ -774,6 +816,11 @@ void migration_test_add_tls(MigrationTestEnv *env)
test_postcopy_preempt_tls_psk);
migration_test_add("/migration/postcopy/preempt/recovery/tls/psk",
test_postcopy_preempt_all);
+ migration_test_add("/migration/multifd+postcopy/recovery/tls/psk",
+ test_multifd_postcopy_recovery_tls_psk);
+ migration_test_add(
+ "/migration/multifd+postcopy/preempt/recovery/tls/psk",
+ test_multifd_postcopy_preempt_recovery_tls_psk);
}
#ifdef CONFIG_TASN1
migration_test_add("/migration/precopy/unix/tls/x509/default-host",
@@ -805,6 +852,10 @@ void migration_test_add_tls(MigrationTestEnv *env)
test_multifd_tcp_tls_psk_match);
migration_test_add("/migration/multifd/tcp/tls/psk/mismatch",
test_multifd_tcp_tls_psk_mismatch);
+ if (env->has_uffd) {
+ migration_test_add("/migration/multifd+postcopy/tcp/tls/psk/match",
+ test_multifd_postcopy_tcp_tls_psk_match);
+ }
#ifdef CONFIG_TASN1
migration_test_add("/migration/multifd/tcp/tls/x509/default-host",
test_multifd_tcp_tls_x509_default_host);
diff --git a/tests/qtest/npcm_gmac-test.c b/tests/qtest/npcm_gmac-test.c
index c28b471..1317da2 100644
--- a/tests/qtest/npcm_gmac-test.c
+++ b/tests/qtest/npcm_gmac-test.c
@@ -36,7 +36,7 @@ typedef struct TestData {
const GMACModule *module;
} TestData;
-/* Values extracted from hw/arm/npcm7xx.c */
+/* Values extracted from hw/arm/npcm8xx.c */
static const GMACModule gmac_module_list[] = {
{
.irq = 14,
@@ -46,6 +46,14 @@ static const GMACModule gmac_module_list[] = {
.irq = 15,
.base_addr = 0xf0804000
},
+ {
+ .irq = 16,
+ .base_addr = 0xf0806000
+ },
+ {
+ .irq = 17,
+ .base_addr = 0xf0808000
+ }
};
/* Returns the index of the GMAC module. */
@@ -174,18 +182,32 @@ static uint32_t gmac_read(QTestState *qts, const GMACModule *mod,
return qtest_readl(qts, mod->base_addr + regno);
}
+static uint16_t pcs_read(QTestState *qts, const GMACModule *mod,
+ NPCMRegister regno)
+{
+ uint32_t write_value = (regno & 0x3ffe00) >> 9;
+ qtest_writel(qts, PCS_BASE_ADDRESS + NPCM_PCS_IND_AC_BA, write_value);
+ uint32_t read_offset = regno & 0x1ff;
+ return qtest_readl(qts, PCS_BASE_ADDRESS + read_offset);
+}
+
/* Check that GMAC registers are reset to default value */
static void test_init(gconstpointer test_data)
{
const TestData *td = test_data;
const GMACModule *mod = td->module;
- QTestState *qts = qtest_init("-machine npcm750-evb");
+ QTestState *qts = qtest_init("-machine npcm845-evb");
#define CHECK_REG32(regno, value) \
do { \
g_assert_cmphex(gmac_read(qts, mod, (regno)), ==, (value)); \
} while (0)
+#define CHECK_REG_PCS(regno, value) \
+ do { \
+ g_assert_cmphex(pcs_read(qts, mod, (regno)), ==, (value)); \
+ } while (0)
+
CHECK_REG32(NPCM_DMA_BUS_MODE, 0x00020100);
CHECK_REG32(NPCM_DMA_XMT_POLL_DEMAND, 0);
CHECK_REG32(NPCM_DMA_RCV_POLL_DEMAND, 0);
@@ -235,6 +257,63 @@ static void test_init(gconstpointer test_data)
CHECK_REG32(NPCM_GMAC_PTP_TAR, 0);
CHECK_REG32(NPCM_GMAC_PTP_TTSR, 0);
+ if (mod->base_addr == 0xf0802000) {
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID1, 0x699e);
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_ID2, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_CTL_STS, 0x8000);
+
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_CTRL, 0x1140);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_STS, 0x0109);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID1, 0x699e);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_DEV_ID2, 0x0ced0);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_ADV, 0x0020);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_LP_BABL, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_AN_EXPN, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_MII_EXT_STS, 0xc000);
+
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_ABL, 0x0003);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_LWR, 0x0038);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MAX_DLY_UPR, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_LWR, 0x0038);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_TX_MIN_DLY_UPR, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_LWR, 0x0058);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MAX_DLY_UPR, 0);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_LWR, 0x0048);
+ CHECK_REG_PCS(NPCM_PCS_SR_TIM_SYNC_RX_MIN_DLY_UPR, 0);
+
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MMD_DIG_CTRL1, 0x2400);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_CTRL, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_AN_INTR_STS, 0x000a);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_TC, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DBG_CTRL, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL0, 0x899c);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_TXTIMER, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_RXTIMER, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_LINK_TIMER_CTRL, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_EEE_MCTRL1, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_STS, 0x0010);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_ICG_ERRCNT1, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MISC_STS, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_RX_LSTS, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_BSTCTRL0, 0x00a);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_LVLCTRL0, 0x007f);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL0, 0x0001);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_GENCTRL1, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_TX_STS, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL0, 0x0100);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_GENCTRL1, 0x1100);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_RX_LOS_CTRL0, 0x000e);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL0, 0x0100);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_CTRL1, 0x0032);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MPLL_STS, 0x0001);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL2, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_LVL_CTRL, 0x0019);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL0, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_MP_MISC_CTRL1, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_CTRL2, 0);
+ CHECK_REG_PCS(NPCM_PCS_VR_MII_DIG_ERRCNT_SEL, 0);
+ }
+
qtest_quit(qts);
}
@@ -242,7 +321,7 @@ static void gmac_add_test(const char *name, const TestData* td,
GTestDataFunc fn)
{
g_autofree char *full_name = g_strdup_printf(
- "npcm7xx_gmac/gmac[%d]/%s", gmac_module_index(td->module), name);
+ "npcm8xx_gmac/gmac[%d]/%s", gmac_module_index(td->module), name);
qtest_add_data_func(full_name, td, fn);
}
diff --git a/tests/qtest/qmp-cmd-test.c b/tests/qtest/qmp-cmd-test.c
index 15c8824..cf71876 100644
--- a/tests/qtest/qmp-cmd-test.c
+++ b/tests/qtest/qmp-cmd-test.c
@@ -51,7 +51,6 @@ static int query_error_class(const char *cmd)
{ "x-query-usb", ERROR_CLASS_GENERIC_ERROR },
/* Only valid with accel=tcg */
{ "x-query-jit", ERROR_CLASS_GENERIC_ERROR },
- { "x-query-opcount", ERROR_CLASS_GENERIC_ERROR },
{ "xen-event-list", ERROR_CLASS_GENERIC_ERROR },
{ NULL, -1 }
};
@@ -100,6 +99,7 @@ static bool query_is_ignored(const char *cmd)
/* Success depends on target arch: */
"query-cpu-definitions", /* arm, i386, ppc, s390x */
"query-gic-capabilities", /* arm */
+ "query-s390x-cpu-polarization", /* s390x */
/* Success depends on target-specific build configuration: */
"query-pci", /* CONFIG_PCI */
"x-query-virtio", /* CONFIG_VIRTIO */
diff --git a/tests/qtest/qom-test.c b/tests/qtest/qom-test.c
index 27d70bc..2da9918 100644
--- a/tests/qtest/qom-test.c
+++ b/tests/qtest/qom-test.c
@@ -11,11 +11,119 @@
#include "qobject/qdict.h"
#include "qobject/qlist.h"
+#include "qobject/qstring.h"
#include "qemu/cutils.h"
#include "libqtest.h"
+#define RAM_NAME "node0"
+#define RAM_SIZE 65536
+
static int verbosity_level;
+/*
+ * Verify that the /object/RAM_NAME 'size' property is RAM_SIZE.
+ */
+static void test_list_get_value(QTestState *qts)
+{
+ QDict *args = qdict_new();
+ g_autoptr(QDict) response = NULL;
+ g_autoptr(QList) paths = qlist_new();
+ QListEntry *entry, *prop_entry;
+ const char *prop_name;
+ QList *properties, *return_list;
+ QDict *obj;
+
+ qlist_append_str(paths, "/objects/" RAM_NAME);
+ qdict_put_obj(args, "paths", QOBJECT(qlist_copy(paths)));
+ response = qtest_qmp(qts, "{ 'execute': 'qom-list-get',"
+ " 'arguments': %p }", args);
+ g_assert(response);
+ g_assert(qdict_haskey(response, "return"));
+ return_list = qobject_to(QList, qdict_get(response, "return"));
+
+ entry = QTAILQ_FIRST(&return_list->head);
+ obj = qobject_to(QDict, qlist_entry_obj(entry));
+ g_assert(qdict_haskey(obj, "properties"));
+ properties = qobject_to(QList, qdict_get(obj, "properties"));
+
+ QLIST_FOREACH_ENTRY(properties, prop_entry) {
+ QDict *prop = qobject_to(QDict, qlist_entry_obj(prop_entry));
+
+ g_assert(qdict_haskey(prop, "name"));
+ g_assert(qdict_haskey(prop, "value"));
+
+ prop_name = qdict_get_str(prop, "name");
+ if (!strcmp(prop_name, "type")) {
+ g_assert_cmpstr(qdict_get_str(prop, "value"), ==,
+ "memory-backend-ram");
+
+ } else if (!strcmp(prop_name, "size")) {
+ g_assert_cmpint(qdict_get_int(prop, "value"), ==, RAM_SIZE);
+ }
+ }
+}
+
+static void test_list_get(QTestState *qts, QList *paths)
+{
+ QListEntry *entry, *prop_entry, *path_entry;
+ g_autoptr(QDict) response = NULL;
+ QDict *args = qdict_new();
+ QDict *prop;
+ QList *return_list;
+
+ if (verbosity_level >= 2) {
+ g_test_message("Obtaining properties for paths:");
+ QLIST_FOREACH_ENTRY(paths, path_entry) {
+ QString *qstr = qobject_to(QString, qlist_entry_obj(path_entry));
+ g_test_message(" %s", qstring_get_str(qstr));
+ }
+ }
+
+ qdict_put_obj(args, "paths", QOBJECT(qlist_copy(paths)));
+ response = qtest_qmp(qts, "{ 'execute': 'qom-list-get',"
+ " 'arguments': %p }", args);
+ g_assert(response);
+ g_assert(qdict_haskey(response, "return"));
+ return_list = qobject_to(QList, qdict_get(response, "return"));
+ g_assert(!qlist_empty(return_list));
+
+ path_entry = QTAILQ_FIRST(&paths->head);
+ QLIST_FOREACH_ENTRY(return_list, entry) {
+ QDict *obj = qobject_to(QDict, qlist_entry_obj(entry));
+ g_assert(qdict_haskey(obj, "properties"));
+ QList *properties = qobject_to(QList, qdict_get(obj, "properties"));
+ bool has_child = false;
+
+ QLIST_FOREACH_ENTRY(properties, prop_entry) {
+ prop = qobject_to(QDict, qlist_entry_obj(prop_entry));
+ g_assert(qdict_haskey(prop, "name"));
+ g_assert(qdict_haskey(prop, "type"));
+ has_child |= strstart(qdict_get_str(prop, "type"), "child<", NULL);
+ }
+
+ if (has_child) {
+ /* build a list of child paths */
+ QString *qstr = qobject_to(QString, qlist_entry_obj(path_entry));
+ const char *path = qstring_get_str(qstr);
+ g_autoptr(QList) child_paths = qlist_new();
+
+ QLIST_FOREACH_ENTRY(properties, prop_entry) {
+ prop = qobject_to(QDict, qlist_entry_obj(prop_entry));
+ if (strstart(qdict_get_str(prop, "type"), "child<", NULL)) {
+ g_autofree char *child_path = g_strdup_printf(
+ "%s/%s", path, qdict_get_str(prop, "name"));
+ qlist_append_str(child_paths, child_path);
+ }
+ }
+
+ /* fetch props for all children with one qom-list-get call */
+ test_list_get(qts, child_paths);
+ }
+
+ path_entry = QTAILQ_NEXT(path_entry, next);
+ }
+}
+
static void test_properties(QTestState *qts, const char *path, bool recurse)
{
char *child_path;
@@ -72,7 +180,7 @@ static void test_properties(QTestState *qts, const char *path, bool recurse)
links = g_slist_delete_link(links, links);
}
while (children) {
- test_properties(qts, children->data, true);
+ test_properties(qts, children->data, g_test_slow());
g_free(children->data);
children = g_slist_delete_link(children, children);
}
@@ -85,8 +193,10 @@ static void test_machine(gconstpointer data)
const char *machine = data;
QDict *response;
QTestState *qts;
+ g_autoptr(QList) paths = qlist_new();
- qts = qtest_initf("-machine %s", machine);
+ qts = qtest_initf("-machine %s -object memory-backend-ram,id=%s,size=%d",
+ machine, RAM_NAME, RAM_SIZE);
if (g_test_slow()) {
/* Make sure we can get the machine class properties: */
@@ -101,9 +211,9 @@ static void test_machine(gconstpointer data)
test_properties(qts, "/machine", true);
- response = qtest_qmp(qts, "{ 'execute': 'quit' }");
- g_assert(qdict_haskey(response, "return"));
- qobject_unref(response);
+ qlist_append_str(paths, "/");
+ test_list_get(qts, paths);
+ test_list_get_value(qts);
qtest_quit(qts);
g_free((void *)machine);
diff --git a/tests/qtest/qos-test.c b/tests/qtest/qos-test.c
index abfd4b9..00f39f3 100644
--- a/tests/qtest/qos-test.c
+++ b/tests/qtest/qos-test.c
@@ -328,11 +328,6 @@ static void walk_path(QOSGraphNode *orig_path, int len)
int main(int argc, char **argv, char** envp)
{
g_test_init(&argc, &argv, NULL);
-
- if (g_test_subprocess()) {
- qos_printf("qos_test running single test in subprocess\n");
- }
-
if (g_test_verbose()) {
qos_printf("ENVIRONMENT VARIABLES: {\n");
for (char **env = envp; *env != 0; env++) {
diff --git a/tests/qtest/riscv-csr-test.c b/tests/qtest/riscv-csr-test.c
index ff5c29e..bb1b0ff 100644
--- a/tests/qtest/riscv-csr-test.c
+++ b/tests/qtest/riscv-csr-test.c
@@ -50,7 +50,9 @@ int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
- qtest_add_func("/cpu/csr", run_test_csr);
+ if (qtest_has_machine("virt")) {
+ qtest_add_func("/cpu/csr", run_test_csr);
+ }
return g_test_run();
}
diff --git a/tests/qtest/test-x86-cpuid-compat.c b/tests/qtest/test-x86-cpuid-compat.c
index c9de47b..456e2af 100644
--- a/tests/qtest/test-x86-cpuid-compat.c
+++ b/tests/qtest/test-x86-cpuid-compat.c
@@ -365,20 +365,6 @@ int main(int argc, char **argv)
"level", 10);
}
- /*
- * xlevel doesn't have any feature that triggers auto-level
- * code on old machine-types. Just check that the compat code
- * is working correctly:
- */
- if (qtest_has_machine("pc-i440fx-2.4")) {
- add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-off",
- "SandyBridge", NULL, "pc-i440fx-2.4",
- "xlevel", 0x80000008);
- add_cpuid_test("x86/cpuid/xlevel-compat/pc-i440fx-2.4/npt-on",
- "SandyBridge", "svm=on,npt=on", "pc-i440fx-2.4",
- "xlevel", 0x80000008);
- }
-
/* Test feature parsing */
add_feature_test("x86/cpuid/features/plus",
"486", "+arat",
diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
index 75cb3e4..609ff24 100644
--- a/tests/qtest/vhost-user-test.c
+++ b/tests/qtest/vhost-user-test.c
@@ -26,7 +26,6 @@
#include "libqos/virtio-pci.h"
#include "libqos/malloc-pc.h"
-#include "libqos/qgraph_internal.h"
#include "hw/virtio/virtio-net.h"
#include "standard-headers/linux/vhost_types.h"
@@ -331,7 +330,6 @@ static int chr_can_read(void *opaque)
static void chr_read(void *opaque, const uint8_t *buf, int size)
{
- g_autoptr(GError) err = NULL;
TestServer *s = opaque;
CharBackend *chr = &s->chr;
VhostUserMsg msg;
@@ -345,7 +343,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
}
if (size != VHOST_USER_HDR_SIZE) {
- qos_printf("%s: Wrong message size received %d\n", __func__, size);
+ g_test_message("Wrong message size received %d", size);
return;
}
@@ -356,8 +354,8 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
p += VHOST_USER_HDR_SIZE;
size = qemu_chr_fe_read_all(chr, p, msg.size);
if (size != msg.size) {
- qos_printf("%s: Wrong message size received %d != %d\n",
- __func__, size, msg.size);
+ g_test_message("Wrong message size received %d != %d",
+ size, msg.size);
goto out;
}
}
@@ -393,7 +391,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
* We don't need to do anything here, the remote is just
* letting us know it is in charge. Just log it.
*/
- qos_printf("set_owner: start of session\n");
+ g_test_message("set_owner: start of session");
break;
case VHOST_USER_GET_PROTOCOL_FEATURES:
@@ -419,7 +417,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
* the remote end to send this. There is no handshake reply so
* just log the details for debugging.
*/
- qos_printf("set_protocol_features: 0x%"PRIx64 "\n", msg.payload.u64);
+ g_test_message("set_protocol_features: 0x%"PRIx64, msg.payload.u64);
break;
/*
@@ -427,11 +425,11 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
* address of the vrings but we can simply report them.
*/
case VHOST_USER_SET_VRING_NUM:
- qos_printf("set_vring_num: %d/%d\n",
+ g_test_message("set_vring_num: %d/%d",
msg.payload.state.index, msg.payload.state.num);
break;
case VHOST_USER_SET_VRING_ADDR:
- qos_printf("set_vring_addr: 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64"\n",
+ g_test_message("set_vring_addr: 0x%"PRIx64"/0x%"PRIx64"/0x%"PRIx64,
msg.payload.addr.avail_user_addr,
msg.payload.addr.desc_user_addr,
msg.payload.addr.used_user_addr);
@@ -464,7 +462,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
case VHOST_USER_SET_VRING_CALL:
/* consume the fd */
if (!qemu_chr_fe_get_msgfds(chr, &fd, 1) && fd < 0) {
- qos_printf("call fd: %d, do not set non-blocking\n", fd);
+ g_test_message("call fd: %d, do not set non-blocking", fd);
break;
}
/*
@@ -472,8 +470,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
* The receive function forces it to be blocking,
* so revert it back to non-blocking.
*/
- g_unix_set_fd_nonblocking(fd, true, &err);
- g_assert_no_error(err);
+ qemu_set_blocking(fd, false, &error_abort);
break;
case VHOST_USER_SET_LOG_BASE:
@@ -510,12 +507,12 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
* fully functioning vhost-user we would enable/disable the
* vring monitoring.
*/
- qos_printf("set_vring(%d)=%s\n", msg.payload.state.index,
+ g_test_message("set_vring(%d)=%s", msg.payload.state.index,
msg.payload.state.num ? "enabled" : "disabled");
break;
default:
- qos_printf("vhost-user: un-handled message: %d\n", msg.request);
+ g_test_message("vhost-user: un-handled message: %d", msg.request);
break;
}
@@ -539,7 +536,7 @@ static const char *init_hugepagefs(void)
}
if (access(path, R_OK | W_OK | X_OK)) {
- qos_printf("access on path (%s): %s", path, strerror(errno));
+ g_test_message("access on path (%s): %s", path, strerror(errno));
g_test_fail();
return NULL;
}
@@ -549,13 +546,13 @@ static const char *init_hugepagefs(void)
} while (ret != 0 && errno == EINTR);
if (ret != 0) {
- qos_printf("statfs on path (%s): %s", path, strerror(errno));
+ g_test_message("statfs on path (%s): %s", path, strerror(errno));
g_test_fail();
return NULL;
}
if (fs.f_type != HUGETLBFS_MAGIC) {
- qos_printf("Warning: path not on HugeTLBFS: %s", path);
+ g_test_message("Warning: path not on HugeTLBFS: %s", path);
g_test_fail();
return NULL;
}
diff --git a/tests/qtest/virtio-scsi-test.c b/tests/qtest/virtio-scsi-test.c
index db10d57..e2350c5 100644
--- a/tests/qtest/virtio-scsi-test.c
+++ b/tests/qtest/virtio-scsi-test.c
@@ -311,6 +311,31 @@ fail:
unlink(tmp_path);
}
+static void test_iothread_virtio_error(void *obj, void *data,
+ QGuestAllocator *t_alloc)
+{
+ QVirtioSCSIPCI *scsi_pci = obj;
+ QVirtioSCSI *scsi = &scsi_pci->scsi;
+ QVirtioSCSIQueues *vs;
+ QVirtQueue *vq;
+
+ alloc = t_alloc;
+ vs = qvirtio_scsi_init(scsi->vdev);
+ vq = vs->vq[2];
+
+ /* Move avail.idx out of bounds to trigger virtio_error() */
+ qvirtqueue_set_avail_idx(global_qtest, scsi->vdev, vq, vq->size * 2);
+ scsi->vdev->bus->virtqueue_kick(scsi->vdev, vq);
+
+ /*
+ * Reset the device out of the error state. If QEMU hangs or crashes then
+ * this will fail.
+ */
+ qvirtio_reset(scsi->vdev);
+
+ qvirtio_scsi_pci_free(vs);
+}
+
static void *virtio_scsi_hotplug_setup(GString *cmd_line, void *arg)
{
g_string_append(cmd_line,
@@ -383,6 +408,13 @@ static void register_virtio_scsi_test(void)
};
qos_add_test("iothread-attach-node", "virtio-scsi-pci",
test_iothread_attach_node, &opts);
+
+ opts.before = virtio_scsi_setup_iothread;
+ opts.edge = (QOSGraphEdgeOptions) {
+ .extra_device_opts = "iothread=thread0",
+ };
+ qos_add_test("iothread-virtio-error", "virtio-scsi-pci",
+ test_iothread_virtio_error, &opts);
}
libqos_init(register_virtio_scsi_test);
diff --git a/tests/qtest/vmgenid-test.c b/tests/qtest/vmgenid-test.c
index e613374..33e96b7 100644
--- a/tests/qtest/vmgenid-test.c
+++ b/tests/qtest/vmgenid-test.c
@@ -61,7 +61,7 @@ static uint32_t acpi_find_vgia(QTestState *qts)
/* The GUID is written at a fixed offset into the fw_cfg file
* in order to implement the "OVMF SDT Header probe suppressor"
- * see docs/specs/vmgenid.txt for more details
+ * see docs/specs/vmgenid.rst for more details
*/
guid_offset = le32_to_cpu(vgia_val) + VMGENID_GUID_OFFSET;
g_free(table_aml);
diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target
index 95ff76e..af72903 100644
--- a/tests/tcg/Makefile.target
+++ b/tests/tcg/Makefile.target
@@ -127,8 +127,14 @@ else
# build options for bare programs are usually pretty different. They
# are expected to provide their own build recipes.
EXTRA_CFLAGS += -ffreestanding -fno-stack-protector
+
+# We skip the multiarch tests if the target hasn't provided a boot.S
+MULTIARCH_SOFTMMU_TARGETS = i386 alpha aarch64 arm loongarch64 s390x x86_64
+
+ifneq ($(filter $(TARGET_NAME),$(MULTIARCH_SOFTMMU_TARGETS)),)
-include $(SRC_PATH)/tests/tcg/minilib/Makefile.target
-include $(SRC_PATH)/tests/tcg/multiarch/system/Makefile.softmmu-target
+endif
-include $(SRC_PATH)/tests/tcg/$(TARGET_NAME)/Makefile.softmmu-target
endif
@@ -151,27 +157,62 @@ ifeq ($(CONFIG_PLUGIN),y)
PLUGIN_SRC=$(SRC_PATH)/tests/tcg/plugins
PLUGIN_LIB=../plugins
VPATH+=$(PLUGIN_LIB)
-PLUGINS=$(patsubst %.c, lib%.so, $(notdir $(wildcard $(PLUGIN_SRC)/*.c)))
+# Some plugins need to be disabled for all tests to avoid exponential explosion.
+# For example, libpatch.so only needs to run against the arch-specific patch
+# target test, so we explicitly run it in the arch-specific Makefile.
+DISABLE_PLUGINS=libpatch.so
+
+# Likewise don't bother with the syscall plugin for softmmu
+ifneq ($(filter %-softmmu, $(TARGET)),)
+DISABLE_PLUGINS += libsyscall.so
+endif
+
+PLUGINS=$(filter-out $(DISABLE_PLUGINS), \
+ $(patsubst %.c, lib%.so, $(notdir $(wildcard $(PLUGIN_SRC)/*.c))))
+
+strip-plugin = $(wordlist 1, 1, $(subst -with-, ,$1))
+extract-plugin = $(wordlist 2, 2, $(subst -with-, ,$1))
+extract-test = $(subst run-plugin-,,$(wordlist 1, 1, $(subst -with-, ,$1)))
# We need to ensure expand the run-plugin-TEST-with-PLUGIN
# pre-requistes manually here as we can't use stems to handle it. We
# only expand MULTIARCH_TESTS which are common on most of our targets
-# to avoid an exponential explosion as new tests are added. We also
-# add some special helpers the run-plugin- rules can use below.
-# In more, extra tests can be added using ADDITIONAL_PLUGINS_TESTS variable.
+# and rotate the plugins so we don't grow too out of control as new
+# tests are added. Plugins that need to run with a specific test
+# should ensure they add their combination to EXTRA_RUNS.
ifneq ($(MULTIARCH_TESTS),)
-$(foreach p,$(PLUGINS), \
- $(foreach t,$(MULTIARCH_TESTS) $(ADDITIONAL_PLUGINS_TESTS),\
- $(eval run-plugin-$(t)-with-$(p): $t $p) \
- $(eval RUN_TESTS+=run-plugin-$(t)-with-$(p))))
+
+# Extract extra tests from the extra test+plugin combination.
+EXTRA_TESTS_WITH_PLUGIN=$(foreach test, \
+ $(EXTRA_RUNS_WITH_PLUGIN),$(call extract-test,$(test)))
+# Exclude tests that were specified to run with specific plugins from the tests
+# which can run with any plugin combination, so we don't run it twice.
+MULTIARCH_TESTS:=$(filter-out $(EXTRA_TESTS_WITH_PLUGIN), $(MULTIARCH_TESTS))
+
+NUM_PLUGINS := $(words $(PLUGINS))
+NUM_TESTS := $(words $(MULTIARCH_TESTS))
+
+define mod_plus_one
+ $(shell $(PYTHON) -c "print( ($(1) % $(2)) + 1 )")
+endef
+
+# Rules for running tests with any plugin combination, i.e., no specific plugin.
+$(foreach _idx, $(shell seq 1 $(NUM_TESTS)), \
+ $(eval _test := $(word $(_idx), $(MULTIARCH_TESTS))) \
+ $(eval _plugin := $(word $(call mod_plus_one, $(_idx), $(NUM_PLUGINS)), $(PLUGINS))) \
+ $(eval run-plugin-$(_test)-with-$(_plugin): $(_test) $(_plugin)) \
+ $(eval RUN_TESTS+=run-plugin-$(_test)-with-$(_plugin)))
+
+# Rules for running extra tests with specific plugins.
+$(foreach f,$(EXTRA_RUNS_WITH_PLUGIN), \
+ $(eval $(f): $(call extract-test,$(f)) $(call extract-plugin,$(f))))
+
endif # MULTIARCH_TESTS
endif # CONFIG_PLUGIN
-strip-plugin = $(wordlist 1, 1, $(subst -with-, ,$1))
-extract-plugin = $(wordlist 2, 2, $(subst -with-, ,$1))
-
RUN_TESTS+=$(EXTRA_RUNS)
+RUN_TESTS+=$(EXTRA_RUNS_WITH_PLUGIN)
# Some plugins need additional arguments above the default to fully
# exercise things. We can define them on a per-test basis here.
diff --git a/tests/tcg/aarch64/Makefile.softmmu-target b/tests/tcg/aarch64/Makefile.softmmu-target
index 9c52475..f7a7d2b 100644
--- a/tests/tcg/aarch64/Makefile.softmmu-target
+++ b/tests/tcg/aarch64/Makefile.softmmu-target
@@ -68,7 +68,8 @@ run-plugin-semiconsole-with-%: semiconsole
# vtimer test needs EL2
QEMU_EL2_MACHINE=-machine virt,virtualization=on,gic-version=2 -cpu cortex-a57 -smp 4
-run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_BASE_ARGS) -kernel
+QEMU_EL2_BASE_ARGS=-semihosting-config enable=on,target=native,chardev=output,arg="2"
+run-vtimer: QEMU_OPTS=$(QEMU_EL2_MACHINE) $(QEMU_EL2_BASE_ARGS) -kernel
# Simple Record/Replay Test
.PHONY: memory-record
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
index 16ddcf4..55ce34e 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -75,6 +75,11 @@ AARCH64_TESTS += $(SME_TESTS)
$(SME_TESTS): CFLAGS += $(CROSS_AS_HAS_ARMV9_SME)
endif
+# GCS Tests
+GCS_TESTS += gcsstr gcspushm gcsss
+AARCH64_TESTS += $(GCS_TESTS)
+$(GCS_TESTS): gcs.h
+
# System Registers Tests
AARCH64_TESTS += sysregs
@@ -134,6 +139,35 @@ run-gdbstub-sve-ioctls: sve-ioctls
EXTRA_RUNS += run-gdbstub-sysregs run-gdbstub-sve-ioctls
+ifneq ($(CROSS_AS_HAS_ARMV9_SME),)
+# SME gdbstub tests
+
+run-gdbstub-sysregs-sme: sysregs
+ $(call run-test, $@, $(GDB_SCRIPT) \
+ --gdb $(GDB) \
+ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+ --bin $< --test $(AARCH64_SRC)/gdbstub/test-sme.py \
+ -- test_sme --gdb_basic_za_test, \
+ basic gdbstub SME support)
+
+ifeq ($(GDB_HAS_SME_TILES),y)
+run-gdbstub-sysregs-sme-tile-slice: sysregs
+ $(call run-test, $@, $(GDB_SCRIPT) \
+ --gdb $(GDB) \
+ --qemu $(QEMU) --qargs "$(QEMU_OPTS)" \
+ --bin $< --test $(AARCH64_SRC)/gdbstub/test-sme.py \
+ -- test_sme --gdb_tile_slice_test, \
+ gdbstub SME ZA tile slice support)
+else
+run-gdbstub-sysregs-sme-tile-slice: sysregs
+ $(call skip-test,"gdbstub SME ZA tile slice support", \
+ "selected gdb ($(GDB)) does not support SME ZA tile slices")
+endif
+
+EXTRA_RUNS += run-gdbstub-sysregs-sme run-gdbstub-sysregs-sme-tile-slice
+
+endif
+
ifeq ($(GDB_HAS_MTE),y)
run-gdbstub-mte: mte-8
$(call run-test, $@, $(GDB_SCRIPT) \
diff --git a/tests/tcg/aarch64/gcs.h b/tests/tcg/aarch64/gcs.h
new file mode 100644
index 0000000..6f013d0
--- /dev/null
+++ b/tests/tcg/aarch64/gcs.h
@@ -0,0 +1,80 @@
+/*
+ * Linux kernel fallback API definitions for GCS and test helpers.
+ *
+ * Copyright (c) 2025 Linaro Ltd
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <sys/mman.h>
+#include <sys/prctl.h>
+#include <sys/syscall.h>
+
+#ifndef PR_GET_SHADOW_STACK_STATUS
+#define PR_GET_SHADOW_STACK_STATUS 74
+#endif
+#ifndef PR_SET_SHADOW_STACK_STATUS
+#define PR_SET_SHADOW_STACK_STATUS 75
+#endif
+#ifndef PR_LOCK_SHADOW_STACK_STATUS
+#define PR_LOCK_SHADOW_STACK_STATUS 76
+#endif
+#ifndef PR_SHADOW_STACK_ENABLE
+# define PR_SHADOW_STACK_ENABLE (1 << 0)
+# define PR_SHADOW_STACK_WRITE (1 << 1)
+# define PR_SHADOW_STACK_PUSH (1 << 2)
+#endif
+#ifndef SHADOW_STACK_SET_TOKEN
+#define SHADOW_STACK_SET_TOKEN (1 << 0)
+#endif
+#ifndef SHADOW_STACK_SET_MARKER
+#define SHADOW_STACK_SET_MARKER (1 << 1)
+#endif
+#ifndef SEGV_CPERR
+#define SEGV_CPERR 10
+#endif
+#ifndef __NR_map_shadow_stack
+#define __NR_map_shadow_stack 453
+#endif
+
+/*
+ * Macros, and implement the syscall inline, lest we fail
+ * the checked return from any function call.
+ */
+#define enable_gcs(flags) \
+ do { \
+ register long num __asm__ ("x8") = __NR_prctl; \
+ register long arg1 __asm__ ("x0") = PR_SET_SHADOW_STACK_STATUS; \
+ register long arg2 __asm__ ("x1") = PR_SHADOW_STACK_ENABLE | flags; \
+ register long arg3 __asm__ ("x2") = 0; \
+ register long arg4 __asm__ ("x3") = 0; \
+ register long arg5 __asm__ ("x4") = 0; \
+ asm volatile("svc #0" \
+ : "+r"(arg1) \
+ : "r"(arg2), "r"(arg3), "r"(arg4), "r"(arg5), "r"(num) \
+ : "memory", "cc"); \
+ if (arg1) { \
+ errno = -arg1; \
+ perror("PR_SET_SHADOW_STACK_STATUS"); \
+ exit(2); \
+ } \
+ } while (0)
+
+#define gcspr() \
+ ({ uint64_t *r; asm volatile("mrs %0, s3_3_c2_c5_1" : "=r"(r)); r; })
+
+#define gcsss1(val) \
+ do { \
+ asm volatile("sys #3, c7, c7, #2, %0" : : "r"(val) : "memory"); \
+ } while (0)
+
+#define gcsss2() \
+ ({ uint64_t *r; \
+ asm volatile("sysl %0, #3, c7, c7, #3" : "=r"(r) : : "memory"); r; })
diff --git a/tests/tcg/aarch64/gcspushm.c b/tests/tcg/aarch64/gcspushm.c
new file mode 100644
index 0000000..c330417
--- /dev/null
+++ b/tests/tcg/aarch64/gcspushm.c
@@ -0,0 +1,71 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gcs.h"
+
+
+#define GCSPUSHM "sys #3, c7, c7, #0, %[push]"
+#define GCSPOPM "sysl %[pop], #3, c7, c7, #1"
+
+static void test_sigsegv(int sig, siginfo_t *info, void *vuc)
+{
+ ucontext_t *uc = vuc;
+ uint64_t inst_sigsegv;
+
+ __asm__("adr %0, inst_sigsegv" : "=r"(inst_sigsegv));
+ assert(uc->uc_mcontext.pc == inst_sigsegv);
+ assert(info->si_code == SEGV_CPERR);
+ /* TODO: Dig for ESR and verify syndrome. */
+ uc->uc_mcontext.pc += 4;
+}
+
+static void test_sigill(int sig, siginfo_t *info, void *vuc)
+{
+ ucontext_t *uc = vuc;
+ uint64_t inst_sigill;
+
+ __asm__("adr %0, inst_sigill" : "=r"(inst_sigill));
+ assert(uc->uc_mcontext.pc == inst_sigill);
+ assert(info->si_code == ILL_ILLOPC);
+ uc->uc_mcontext.pc += 4;
+}
+
+int main()
+{
+ struct sigaction sa = { .sa_flags = SA_SIGINFO };
+ uint64_t old, new;
+
+ sa.sa_sigaction = test_sigsegv;
+ if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+ perror("sigaction");
+ exit(1);
+ }
+
+ sa.sa_sigaction = test_sigill;
+ if (sigaction(SIGILL, &sa, NULL) < 0) {
+ perror("sigaction");
+ exit(1);
+ }
+
+ /* Pushm is disabled -- SIGILL via EC_SYSTEMREGISTERTRAP */
+ asm volatile("inst_sigill:\t" GCSPUSHM
+ : : [push] "r" (1));
+
+ enable_gcs(PR_SHADOW_STACK_PUSH);
+
+ /* Valid value -- low 2 bits clear */
+ old = 0xdeadbeeffeedcaec;
+ asm volatile(GCSPUSHM "\n\t" GCSPOPM
+ : [pop] "=r" (new)
+ : [push] "r" (old)
+ : "memory");
+ assert(old == new);
+
+ /* Invalid value -- SIGSEGV via EC_GCS */
+ asm volatile(GCSPUSHM "\n"
+ "inst_sigsegv:\t" GCSPOPM
+ : [pop] "=r" (new)
+ : [push] "r" (1)
+ : "memory");
+
+ exit(0);
+}
diff --git a/tests/tcg/aarch64/gcsss.c b/tests/tcg/aarch64/gcsss.c
new file mode 100644
index 0000000..9550c68
--- /dev/null
+++ b/tests/tcg/aarch64/gcsss.c
@@ -0,0 +1,74 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gcs.h"
+
+#define IN_PROGRESS(X) ((uint64_t)(X) | 5)
+#define CAP(X) (((uint64_t)(X) & ~0xfff) + 1)
+
+static uint64_t * __attribute__((noinline)) recurse(size_t index)
+{
+ if (index == 0) {
+ return gcspr();
+ }
+ return recurse(index - 1);
+}
+
+int main()
+{
+ void *tmp;
+ uint64_t *alt_stack, *alt_cap;
+ uint64_t *orig_pr, *orig_cap;
+ uint64_t *bottom;
+ size_t pagesize = getpagesize();
+ size_t words;
+
+ enable_gcs(0);
+ orig_pr = gcspr();
+
+ /* Allocate a guard page before and after. */
+ tmp = mmap(0, 3 * pagesize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
+ assert(tmp != MAP_FAILED);
+
+ /* map_shadow_stack won't replace existing mappings */
+ munmap(tmp + pagesize, pagesize);
+
+ /* Allocate a new stack between the guards. */
+ alt_stack = (uint64_t *)
+ syscall(__NR_map_shadow_stack, tmp + pagesize, pagesize,
+ SHADOW_STACK_SET_TOKEN);
+ assert(alt_stack == tmp + pagesize);
+
+ words = pagesize / 8;
+ alt_cap = alt_stack + words - 1;
+
+ /* SHADOW_STACK_SET_TOKEN set the cap. */
+ assert(*alt_cap == CAP(alt_cap));
+
+ /* Swap to the alt stack, one step at a time. */
+ gcsss1(alt_cap);
+
+ assert(gcspr() == alt_cap);
+ assert(*alt_cap == IN_PROGRESS(orig_pr));
+
+ orig_cap = gcsss2();
+
+ assert(orig_cap == orig_pr - 1);
+ assert(*orig_cap == CAP(orig_cap));
+ assert(gcspr() == alt_stack + words);
+
+ /* We should be able to use the whole stack. */
+ bottom = recurse(words - 1);
+ assert(bottom == alt_stack);
+
+ /* We should be back where we started. */
+ assert(gcspr() == alt_stack + words);
+
+ /* Swap back to the original stack. */
+ gcsss1(orig_cap);
+ tmp = gcsss2();
+
+ assert(gcspr() == orig_pr);
+ assert(tmp == alt_cap);
+
+ exit(0);
+}
diff --git a/tests/tcg/aarch64/gcsstr.c b/tests/tcg/aarch64/gcsstr.c
new file mode 100644
index 0000000..b045aee
--- /dev/null
+++ b/tests/tcg/aarch64/gcsstr.c
@@ -0,0 +1,48 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "gcs.h"
+
+/*
+ * A single garbage store to the gcs stack.
+ * The asm inside must be unique, so disallow inlining.
+ */
+void __attribute__((noinline))
+test_gcsstr(void)
+{
+ register uint64_t *ptr __asm__("x0") = gcspr();
+ /* GCSSTR x1, x0 */
+ __asm__("inst_gcsstr: .inst 0xd91f1c01" : : "r"(--ptr));
+}
+
+static void test_sigsegv(int sig, siginfo_t *info, void *vuc)
+{
+ ucontext_t *uc = vuc;
+ uint64_t inst_gcsstr;
+
+ __asm__("adr %0, inst_gcsstr" : "=r"(inst_gcsstr));
+ assert(uc->uc_mcontext.pc == inst_gcsstr);
+ assert(info->si_code == SEGV_CPERR);
+ /* TODO: Dig for ESR and verify syndrome. */
+ exit(0);
+}
+
+int main()
+{
+ struct sigaction sa = {
+ .sa_sigaction = test_sigsegv,
+ .sa_flags = SA_SIGINFO,
+ };
+
+ /* Enable GCSSTR and test the store succeeds. */
+ enable_gcs(PR_SHADOW_STACK_WRITE);
+ test_gcsstr();
+
+ /* Disable GCSSTR and test the resulting sigsegv. */
+ enable_gcs(0);
+ if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+ perror("sigaction");
+ exit(1);
+ }
+ test_gcsstr();
+ abort();
+}
diff --git a/tests/tcg/aarch64/gdbstub/test-mte.py b/tests/tcg/aarch64/gdbstub/test-mte.py
index 9ad98e7..f4a7d7b 100644
--- a/tests/tcg/aarch64/gdbstub/test-mte.py
+++ b/tests/tcg/aarch64/gdbstub/test-mte.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test GDB memory-tag commands that exercise the stubs for the qIsAddressTagged,
# qMemTag, and QMemTag packets, which are used for manipulating allocation tags.
diff --git a/tests/tcg/aarch64/gdbstub/test-sme.py b/tests/tcg/aarch64/gdbstub/test-sme.py
new file mode 100644
index 0000000..ec03189
--- /dev/null
+++ b/tests/tcg/aarch64/gdbstub/test-sme.py
@@ -0,0 +1,117 @@
+#
+# Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+#
+# Test the SME registers are visible and changeable via gdbstub
+#
+# This is launched via tests/guest-debug/run-test.py
+#
+
+import argparse
+import gdb
+from test_gdbstub import main, report
+
+MAGIC = 0x01020304
+BASIC_ZA_TEST = 0
+TILE_SLICE_TEST = 0
+
+
+def run_test():
+ """Run the requested test(s) for SME ZA gdbstub support"""
+
+ if BASIC_ZA_TEST:
+ run_basic_sme_za_gdbstub_support_test()
+ if TILE_SLICE_TEST:
+ run_basic_sme_za_tile_slice_gdbstub_support_test()
+
+
+def run_basic_sme_za_gdbstub_support_test():
+ """Test reads and writes to the SME ZA register at the byte level"""
+
+ frame = gdb.selected_frame()
+ rname = "za"
+ za = frame.read_register(rname)
+ report(True, "Reading %s" % rname)
+
+ # Writing to the ZA register, byte by byte.
+ for i in range(0, 16):
+ for j in range(0, 16):
+ cmd = "set $za[%d][%d] = 0x01" % (i, j)
+ gdb.execute(cmd)
+ report(True, "%s" % cmd)
+
+ # Reading from the ZA register, byte by byte.
+ for i in range(0, 16):
+ for j in range(0, 16):
+ reg = "$za[%d][%d]" % (i, j)
+ v = gdb.parse_and_eval(reg)
+ report(str(v.type) == "uint8_t", "size of %s" % (reg))
+ report(v == 0x1, "%s is 0x%x" % (reg, 0x1))
+
+
+def run_basic_sme_za_tile_slice_gdbstub_support_test():
+ """Test reads and writes of SME ZA horizontal and vertical tile slices
+
+ Test if SME ZA tile slices, both horizontal and vertical,
+ can be correctly read and written to. The sizes to test
+ are quadwords and doublewords.
+ """
+
+ sizes = {}
+ sizes["q"] = "uint128_t"
+ sizes["d"] = "uint64_t"
+
+ # Accessing requested sizes of elements of ZA
+ for size in sizes:
+
+ # Accessing various ZA tiles
+ for i in range(0, 4):
+
+ # Accessing various horizontal slices for each ZA tile
+ for j in range(0, 4):
+ # Writing to various elements in each tile slice
+ for k in range(0, 4):
+ cmd = "set $za%dh%c%d[%d] = 0x%x" % (i, size, j, k, MAGIC)
+ gdb.execute(cmd)
+ report(True, "%s" % cmd)
+
+ # Reading from the written elements in each tile slice
+ for k in range(0, 4):
+ reg = "$za%dh%c%d[%d]" % (i, size, j, k)
+ v = gdb.parse_and_eval(reg)
+ report(str(v.type) == sizes[size], "size of %s" % (reg))
+ report(v == MAGIC, "%s is 0x%x" % (reg, MAGIC))
+
+ # Accessing various vertical slices for each ZA tile
+ for j in range(0, 4):
+ # Writing to various elements in each tile slice
+ for k in range(0, 4):
+ cmd = "set $za%dv%c%d[%d] = 0x%x" % (i, size, j, k, MAGIC)
+ gdb.execute(cmd)
+ report(True, "%s" % cmd)
+
+ # Reading from the written elements in each tile slice
+ for k in range(0, 4):
+ reg = "$za%dv%c%d[%d]" % (i, size, j, k)
+ v = gdb.parse_and_eval(reg)
+ report(str(v.type) == sizes[size], "size of %s" % (reg))
+ report(v == MAGIC, "%s is 0x%x" % (reg, MAGIC))
+
+
+parser = argparse.ArgumentParser(description="A gdbstub test for SME support")
+parser.add_argument("--gdb_basic_za_test",
+ help="Enable test for basic SME ZA support",
+ action="store_true")
+parser.add_argument("--gdb_tile_slice_test",
+ help="Enable test for ZA tile slice support",
+ action="store_true")
+args = parser.parse_args()
+
+if args.gdb_basic_za_test:
+ BASIC_ZA_TEST = 1
+if args.gdb_tile_slice_test:
+ TILE_SLICE_TEST = 1
+
+main(run_test, expected_arch="aarch64")
diff --git a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
index a78a3a2..2c5c218 100644
--- a/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
+++ b/tests/tcg/aarch64/gdbstub/test-sve-ioctl.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test the SVE ZReg reports the right amount of data. It uses the
# sve-ioctl test and examines the register data each time the
diff --git a/tests/tcg/aarch64/gdbstub/test-sve.py b/tests/tcg/aarch64/gdbstub/test-sve.py
index 84cdcd4..7b0489a 100644
--- a/tests/tcg/aarch64/gdbstub/test-sve.py
+++ b/tests/tcg/aarch64/gdbstub/test-sve.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test the SVE registers are visible and changeable via gdbstub
#
diff --git a/tests/tcg/aarch64/system/boot.S b/tests/tcg/aarch64/system/boot.S
index a5df9c1..8bfa4e4 100644
--- a/tests/tcg/aarch64/system/boot.S
+++ b/tests/tcg/aarch64/system/boot.S
@@ -16,6 +16,7 @@
#define semihosting_call hlt 0xf000
#define SYS_WRITEC 0x03 /* character to debug channel */
#define SYS_WRITE0 0x04 /* string to debug channel */
+#define SYS_GET_CMDLINE 0x15 /* get command line */
#define SYS_EXIT 0x18
.align 12
@@ -70,21 +71,172 @@ lower_a32_sync:
lower_a32_irq:
lower_a32_fiq:
lower_a32_serror:
+ adr x1, .unexp_excp
+exit_msg:
mov x0, SYS_WRITE0
- adr x1, .error
semihosting_call
mov x0, 1 /* EXIT_FAILURE */
bl _exit
/* never returns */
.section .rodata
-.error:
- .string "Terminated by exception.\n"
+.unexp_excp:
+ .string "Unexpected exception.\n"
+.high_el_msg:
+ .string "Started in lower EL than requested.\n"
+.unexp_el0:
+ .string "Started in invalid EL.\n"
+
+ .align 8
+.get_cmd:
+ .quad cmdline
+ .quad 128
.text
.align 4
.global __start
__start:
+ /*
+ * Initialise the stack for whatever EL we are in before
+ * anything else, we need it to be able to _exit cleanly.
+ * It's smaller than the stack we pass to the C code but we
+ * don't need much.
+ */
+ adrp x0, system_stack_end
+ add x0, x0, :lo12:system_stack_end
+ mov sp, x0
+
+ /*
+ * The test can set the semihosting command line to the target
+ * EL needed for the test. However if no semihosting args are set we will
+ * end up with -kernel/-append data (see semihosting_arg_fallback).
+ * Keep the normalised target in w11.
+ */
+ mov x0, SYS_GET_CMDLINE
+ adr x1, .get_cmd
+ semihosting_call
+ adrp x10, cmdline
+ add x10, x10, :lo12:cmdline
+ ldrb w11, [x10]
+
+ /* sanity check, normalise char to EL, clamp to 1 if outside range */
+ subs w11, w11, #'0'
+ b.lt el_default
+ cmp w11, #3
+ b.gt el_default
+ b 1f
+
+el_high:
+ adr x1, .high_el_msg
+ b exit_msg
+
+el_default:
+ mov w11, #1
+
+1:
+ /* Determine current Exception Level */
+ mrs x0, CurrentEL
+ lsr x0, x0, #2 /* CurrentEL[3:2] contains the current EL */
+
+ /* Are we already in a lower EL than we want? */
+ cmp w11, w0
+ bgt el_high
+
+ /* Branch based on current EL */
+ cmp x0, #3
+ b.eq setup_el3
+ cmp x0, #2
+ b.eq setup_el2
+ cmp x0, #1
+ b.eq at_testel /* Already at EL1, skip transition */
+
+ /* Should not be at EL0 - error out */
+ adr x1, .unexp_el0
+ b exit_msg
+
+setup_el3:
+ /* Ensure we trap if we get anything wrong */
+ adr x0, vector_table
+ msr vbar_el3, x0
+
+ /* Does the test want to be at EL3? */
+ cmp w11, #3
+ beq at_testel
+
+ /* Configure EL3 to for lower states (EL2 or EL1) */
+ mrs x0, scr_el3
+ orr x0, x0, #(1 << 10) /* RW = 1: EL2/EL1 execution state is AArch64 */
+ orr x0, x0, #(1 << 0) /* NS = 1: Non-secure state */
+ msr scr_el3, x0
+
+ /*
+ * We need to check if EL2 is actually enabled via ID_AA64PFR0_EL1,
+ * otherwise we should just jump straight to EL1.
+ */
+ mrs x0, id_aa64pfr0_el1
+ ubfx x0, x0, #8, #4 /* Extract EL2 field (bits 11:8) */
+ cbz x0, el2_not_present /* If field is 0 no EL2 */
+
+
+ /* Prepare SPSR for exception return to EL2 */
+ mov x0, #0x3c9 /* DAIF bits and EL2h mode (9) */
+ msr spsr_el3, x0
+
+ /* Set EL2 entry point */
+ adr x0, setup_el2
+ msr elr_el3, x0
+
+ /* Return to EL2 */
+ eret
+
+el2_not_present:
+ /* Initialize SCTLR_EL1 with reset value */
+ msr sctlr_el1, xzr
+
+ /* Set EL1 entry point */
+ adr x0, at_testel
+ msr elr_el3, x0
+
+ /* Prepare SPSR for exception return to EL1h with interrupts masked */
+ mov x0, #0x3c5 /* DAIF bits and EL1h mode (5) */
+ msr spsr_el3, x0
+
+ isb /* Synchronization barrier */
+ eret /* Jump to EL1 */
+
+setup_el2:
+ /* Ensure we trap if we get anything wrong */
+ adr x0, vector_table
+ msr vbar_el2, x0
+
+ /* Does the test want to be at EL2? */
+ cmp w11, #2
+ beq at_testel
+
+ /* Configure EL2 to allow transition to EL1 */
+ mrs x0, hcr_el2
+ orr x0, x0, #(1 << 31) /* RW = 1: EL1 execution state is AArch64 */
+ msr hcr_el2, x0
+
+ /* Initialize SCTLR_EL1 with reset value */
+ msr sctlr_el1, xzr
+
+ /* Set EL1 entry point */
+ adr x0, at_testel
+ msr elr_el2, x0
+
+ /* Prepare SPSR for exception return to EL1 */
+ mov x0, #(0x5 << 0) /* EL1h (SPx), with interrupts disabled */
+ msr spsr_el2, x0
+
+ /* Return to EL1 */
+ eret
+
+ /*
+ * At the target EL for the test, usually EL1. Note we still
+ * set everything up as if we were at EL1.
+ */
+at_testel:
/* Installs a table of exception vectors to catch and handle all
exceptions by terminating the process with a diagnostic. */
adr x0, vector_table
@@ -100,7 +252,7 @@ __start:
* maps RAM to the first Gb. The stage2 tables have two 2mb
* translation block entries covering a series of adjacent
* 4k pages.
- */
+ */
/* Stage 1 entry: indexed by IA[38:30] */
adr x1, . /* phys address */
@@ -198,7 +350,8 @@ __start:
orr x0, x0, #(3 << 16)
msr cpacr_el1, x0
- /* Setup some stack space and enter the test code.
+ /*
+ * Setup some stack space before we enter the test code.
* Assume everything except the return value is garbage when we
* return, we won't need it.
*/
@@ -233,6 +386,11 @@ __sys_outc:
ret
.data
+
+ .align 8
+cmdline:
+ .space 128, 0
+
.align 12
/* Translation table
@@ -246,6 +404,10 @@ ttb_stage2:
.space 4096, 0
.align 12
+system_stack:
+ .space 4096, 0
+system_stack_end:
+
stack:
.space 65536, 0
stack_end:
diff --git a/tests/tcg/mips/include/wrappers_mips64r6.h b/tests/tcg/mips/include/wrappers_mips64r6.h
index d1e5edb..33d03de 100644
--- a/tests/tcg/mips/include/wrappers_mips64r6.h
+++ b/tests/tcg/mips/include/wrappers_mips64r6.h
@@ -23,6 +23,7 @@
#ifndef WRAPPERS_MIPS64R6_H
#define WRAPPERS_MIPS64R6_H
+#include <string.h>
#define DO_MIPS64R6__RD__RS(suffix, mnemonic) \
static inline void do_mips64r6_##suffix(const void *input, \
@@ -80,4 +81,35 @@ DO_MIPS64R6__RD__RS_RT(DMULU, dmulu)
DO_MIPS64R6__RD__RS_RT(DMUHU, dmuhu)
+#define DO_MIPS64R6__RT__RS_RT(suffix, mnemonic) \
+static inline void do_mips64r6_##suffix(const void *input1, \
+ const void *input2, \
+ void *output) \
+{ \
+ if (strncmp(#mnemonic, "crc32", 5) == 0) \
+ __asm__ volatile ( \
+ ".set crc\n\t" \
+ ); \
+ \
+ __asm__ volatile ( \
+ "ld $t1, 0(%0)\n\t" \
+ "ld $t2, 0(%1)\n\t" \
+ #mnemonic " $t2, $t1, $t2\n\t" \
+ "sd $t2, 0(%2)\n\t" \
+ : \
+ : "r" (input1), "r" (input2), "r" (output) \
+ : "t0", "t1", "t2", "memory" \
+ ); \
+}
+
+DO_MIPS64R6__RT__RS_RT(CRC32B, crc32b)
+DO_MIPS64R6__RT__RS_RT(CRC32H, crc32h)
+DO_MIPS64R6__RT__RS_RT(CRC32W, crc32w)
+DO_MIPS64R6__RT__RS_RT(CRC32D, crc32d)
+
+DO_MIPS64R6__RT__RS_RT(CRC32CB, crc32cb)
+DO_MIPS64R6__RT__RS_RT(CRC32CH, crc32ch)
+DO_MIPS64R6__RT__RS_RT(CRC32CW, crc32cw)
+DO_MIPS64R6__RT__RS_RT(CRC32CD, crc32cd)
+
#endif
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/Makefile b/tests/tcg/mips/user/isa/mips64r6/crc/Makefile
new file mode 100644
index 0000000..b7f5811
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/Makefile
@@ -0,0 +1,40 @@
+#
+# Test program for MIPS64R6 CRC32 instructions
+#
+# Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+
+ifndef PREFIX
+ $(error "PREFIX not set, please export GNU Toolchain install directory.")
+endif
+
+ifndef SYSROOT
+ $(error "SYSROOT not set, please export GNU Toolchain system root directory.")
+endif
+
+SIM = ../../../../../../../build/qemu-mips64
+SIM_FLAGS = -L $(SYSROOT)
+
+CC = $(PREFIX)/bin/mips64-r6-linux-gnu-gcc
+
+TESTCASES = test_mips64r6_crc32b.tst
+TESTCASES += test_mips64r6_crc32h.tst
+TESTCASES += test_mips64r6_crc32w.tst
+TESTCASES += test_mips64r6_crc32d.tst
+TESTCASES += test_mips64r6_crc32cb.tst
+TESTCASES += test_mips64r6_crc32ch.tst
+TESTCASES += test_mips64r6_crc32cw.tst
+TESTCASES += test_mips64r6_crc32cd.tst
+
+all: $(TESTCASES)
+ @for case in $(TESTCASES); do \
+ echo $(SIM) $(SIM_FLAGS) ./$$case; \
+ $(SIM) $(SIM_FLAGS) ./$$case; \
+ echo $(RM) -rf ./$$case; \
+ $(RM) -rf ./$$case; \
+ done
+
+%.tst: %.c
+ $(CC) $< -o $@
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32b.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32b.c
new file mode 100644
index 0000000..bb1f3f6
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32b.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32B
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0xEDB88320";
+ char *instruction_name = "CRC32B";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x0000000000ffffffULL, /* 0 */
+ 0x000000002d02ef8dULL,
+ 0x000000001bab0fd1ULL,
+ 0x0000000036561fa3ULL,
+ 0xffffffffbf1caddaULL,
+ 0xffffffff92e1bda8ULL,
+ 0x00000000278c7949ULL,
+ 0x000000000a71693bULL,
+ 0x000000002dfd1072ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0x0000000036a9e05cULL,
+ 0x000000001b54f02eULL,
+ 0xffffffff921e4257ULL,
+ 0xffffffffbfe35225ULL,
+ 0x000000000a8e96c4ULL,
+ 0x00000000277386b6ULL,
+ 0x000000001bfe5a84ULL, /* 16 */
+ 0x0000000036034af6ULL,
+ 0x0000000000aaaaaaULL,
+ 0x000000002d57bad8ULL,
+ 0xffffffffa41d08a1ULL,
+ 0xffffffff89e018d3ULL,
+ 0x000000003c8ddc32ULL,
+ 0x000000001170cc40ULL,
+ 0x0000000036fcb509ULL, /* 24 */
+ 0x000000001b01a57bULL,
+ 0x000000002da84527ULL,
+ 0x0000000000555555ULL,
+ 0xffffffff891fe72cULL,
+ 0xffffffffa4e2f75eULL,
+ 0x00000000118f33bfULL,
+ 0x000000003c7223cdULL,
+ 0xffffffffbf2f9ee9ULL, /* 32 */
+ 0xffffffff92d28e9bULL,
+ 0xffffffffa47b6ec7ULL,
+ 0xffffffff89867eb5ULL,
+ 0x0000000000ccccccULL,
+ 0x000000002d31dcbeULL,
+ 0xffffffff985c185fULL,
+ 0xffffffffb5a1082dULL,
+ 0xffffffff922d7164ULL, /* 40 */
+ 0xffffffffbfd06116ULL,
+ 0xffffffff8979814aULL,
+ 0xffffffffa4849138ULL,
+ 0x000000002dce2341ULL,
+ 0x0000000000333333ULL,
+ 0xffffffffb55ef7d2ULL,
+ 0xffffffff98a3e7a0ULL,
+ 0x0000000027fdbe55ULL, /* 48 */
+ 0x000000000a00ae27ULL,
+ 0x000000003ca94e7bULL,
+ 0x0000000011545e09ULL,
+ 0xffffffff981eec70ULL,
+ 0xffffffffb5e3fc02ULL,
+ 0x00000000008e38e3ULL,
+ 0x000000002d732891ULL,
+ 0x000000000aff51d8ULL, /* 56 */
+ 0x00000000270241aaULL,
+ 0x0000000011aba1f6ULL,
+ 0x000000003c56b184ULL,
+ 0xffffffffb51c03fdULL,
+ 0xffffffff98e1138fULL,
+ 0x000000002d8cd76eULL,
+ 0x000000000071c71cULL,
+ 0x0000000000286255ULL, /* 64 */
+ 0x00000000784a5a65ULL,
+ 0xffffffff9bdd0d3bULL,
+ 0xffffffffe7e61ce5ULL,
+ 0x00000000782fabf7ULL,
+ 0x00000000004d93c7ULL,
+ 0xffffffffe3dac499ULL,
+ 0xffffffff9fe1d547ULL,
+ 0xffffffff9b4ca0e5ULL, /* 72 */
+ 0xffffffffe32e98d5ULL,
+ 0x0000000000b9cf8bULL,
+ 0x000000007c82de55ULL,
+ 0xffffffffe7904f52ULL,
+ 0xffffffff9ff27762ULL,
+ 0x000000007c65203cULL,
+ 0x00000000005e31e2ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32B(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32B(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cb.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cb.c
new file mode 100644
index 0000000..1439d44
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cb.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32CB
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0x82F63B78";
+ char *instruction_name = "CRC32CB";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x0000000000ffffffULL, /* 0 */
+ 0xffffffffad7d5351ULL,
+ 0x00000000647e6465ULL,
+ 0xffffffffc9fcc8cbULL,
+ 0x00000000237f7689ULL,
+ 0xffffffff8efdda27ULL,
+ 0xffffffff837defedULL,
+ 0x000000002eff4343ULL,
+ 0xffffffffad82acaeULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0xffffffffc9033734ULL,
+ 0x0000000064819b9aULL,
+ 0xffffffff8e0225d8ULL,
+ 0x0000000023808976ULL,
+ 0x000000002e00bcbcULL,
+ 0xffffffff83821012ULL,
+ 0x00000000642b3130ULL, /* 16 */
+ 0xffffffffc9a99d9eULL,
+ 0x0000000000aaaaaaULL,
+ 0xffffffffad280604ULL,
+ 0x0000000047abb846ULL,
+ 0xffffffffea2914e8ULL,
+ 0xffffffffe7a92122ULL,
+ 0x000000004a2b8d8cULL,
+ 0xffffffffc9566261ULL, /* 24 */
+ 0x0000000064d4cecfULL,
+ 0xffffffffadd7f9fbULL,
+ 0x0000000000555555ULL,
+ 0xffffffffead6eb17ULL,
+ 0x00000000475447b9ULL,
+ 0x000000004ad47273ULL,
+ 0xffffffffe756deddULL,
+ 0x00000000234c45baULL, /* 32 */
+ 0xffffffff8ecee914ULL,
+ 0x0000000047cdde20ULL,
+ 0xffffffffea4f728eULL,
+ 0x0000000000ccccccULL,
+ 0xffffffffad4e6062ULL,
+ 0xffffffffa0ce55a8ULL,
+ 0x000000000d4cf906ULL,
+ 0xffffffff8e3116ebULL, /* 40 */
+ 0x0000000023b3ba45ULL,
+ 0xffffffffeab08d71ULL,
+ 0x00000000473221dfULL,
+ 0xffffffffadb19f9dULL,
+ 0x0000000000333333ULL,
+ 0x000000000db306f9ULL,
+ 0xffffffffa031aa57ULL,
+ 0xffffffff830c28f1ULL, /* 48 */
+ 0x000000002e8e845fULL,
+ 0xffffffffe78db36bULL,
+ 0x000000004a0f1fc5ULL,
+ 0xffffffffa08ca187ULL,
+ 0x000000000d0e0d29ULL,
+ 0x00000000008e38e3ULL,
+ 0xffffffffad0c944dULL,
+ 0x000000002e717ba0ULL, /* 56 */
+ 0xffffffff83f3d70eULL,
+ 0x000000004af0e03aULL,
+ 0xffffffffe7724c94ULL,
+ 0x000000000df1f2d6ULL,
+ 0xffffffffa0735e78ULL,
+ 0xffffffffadf36bb2ULL,
+ 0x000000000071c71cULL,
+ 0x0000000000286255ULL, /* 64 */
+ 0xffffffffcbefd6b4ULL,
+ 0xffffffffc334e94fULL,
+ 0xffffffffac268ec5ULL,
+ 0xffffffffcb8a2726ULL,
+ 0x00000000004d93c7ULL,
+ 0x000000000896ac3cULL,
+ 0x000000006784cbb6ULL,
+ 0xffffffffc3a54491ULL, /* 72 */
+ 0x000000000862f070ULL,
+ 0x0000000000b9cf8bULL,
+ 0x000000006faba801ULL,
+ 0xffffffffac50dd72ULL,
+ 0x0000000067976993ULL,
+ 0x000000006f4c5668ULL,
+ 0x00000000005e31e2ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CB(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CB(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cd.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cd.c
new file mode 100644
index 0000000..bf258e0
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cd.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32CD
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0x82F63B78";
+ char *instruction_name = "CRC32CD";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0xffffffffb798b438ULL, /* 0 */
+ 0xffffffffc44ff94dULL,
+ 0xffffffff992a70ebULL,
+ 0xffffffffeafd3d9eULL,
+ 0x000000005152da26ULL,
+ 0x0000000022859753ULL,
+ 0x0000000015cb6d32ULL,
+ 0x00000000661c2047ULL,
+ 0x0000000073d74d75ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0x000000005d6589a6ULL,
+ 0x000000002eb2c4d3ULL,
+ 0xffffffff951d236bULL,
+ 0xffffffffe6ca6e1eULL,
+ 0xffffffffd184947fULL,
+ 0xffffffffa253d90aULL,
+ 0x0000000008f9ceacULL, /* 16 */
+ 0x000000007b2e83d9ULL,
+ 0x00000000264b0a7fULL,
+ 0x00000000559c470aULL,
+ 0xffffffffee33a0b2ULL,
+ 0xffffffff9de4edc7ULL,
+ 0xffffffffaaaa17a6ULL,
+ 0xffffffffd97d5ad3ULL,
+ 0xffffffffccb637e1ULL, /* 24 */
+ 0xffffffffbf617a94ULL,
+ 0xffffffffe204f332ULL,
+ 0xffffffff91d3be47ULL,
+ 0x000000002a7c59ffULL,
+ 0x0000000059ab148aULL,
+ 0x000000006ee5eeebULL,
+ 0x000000001d32a39eULL,
+ 0x0000000021e3b01bULL, /* 32 */
+ 0x000000005234fd6eULL,
+ 0x000000000f5174c8ULL,
+ 0x000000007c8639bdULL,
+ 0xffffffffc729de05ULL,
+ 0xffffffffb4fe9370ULL,
+ 0xffffffff83b06911ULL,
+ 0xfffffffff0672464ULL,
+ 0xffffffffe5ac4956ULL, /* 40 */
+ 0xffffffff967b0423ULL,
+ 0xffffffffcb1e8d85ULL,
+ 0xffffffffb8c9c0f0ULL,
+ 0x0000000003662748ULL,
+ 0x0000000070b16a3dULL,
+ 0x0000000047ff905cULL,
+ 0x000000003428dd29ULL,
+ 0xffffffffb89d59a6ULL, /* 48 */
+ 0xffffffffcb4a14d3ULL,
+ 0xffffffff962f9d75ULL,
+ 0xffffffffe5f8d000ULL,
+ 0x000000005e5737b8ULL,
+ 0x000000002d807acdULL,
+ 0x000000001ace80acULL,
+ 0x000000006919cdd9ULL,
+ 0x000000007cd2a0ebULL, /* 56 */
+ 0x000000000f05ed9eULL,
+ 0x0000000052606438ULL,
+ 0x0000000021b7294dULL,
+ 0xffffffff9a18cef5ULL,
+ 0xffffffffe9cf8380ULL,
+ 0xffffffffde8179e1ULL,
+ 0xffffffffad563494ULL,
+ 0x000000003a358bb3ULL, /* 64 */
+ 0xffffffff975446ebULL,
+ 0x0000000041d37ad6ULL,
+ 0x000000004be84fe1ULL,
+ 0xffffffff9671b1b3ULL,
+ 0x000000003b107cebULL,
+ 0xffffffffed9740d6ULL,
+ 0xffffffffe7ac75e1ULL,
+ 0xffffffffa1489696ULL, /* 72 */
+ 0x000000000c295bceULL,
+ 0xffffffffdaae67f3ULL,
+ 0xffffffffd09552c4ULL,
+ 0x0000000042bd7071ULL,
+ 0xffffffffefdcbd29ULL,
+ 0x00000000395b8114ULL,
+ 0x000000003360b423ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CD(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CD(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32ch.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32ch.c
new file mode 100644
index 0000000..0e7b677
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32ch.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32CH
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0x82F63B78";
+ char *instruction_name = "CRC32CH";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x000000000000ffffULL, /* 0 */
+ 0x000000000e9e77d2ULL,
+ 0xfffffffff92eaa4bULL,
+ 0xfffffffff7b02266ULL,
+ 0x00000000571acc93ULL,
+ 0x00000000598444beULL,
+ 0xfffffffff1e6ca77ULL,
+ 0xffffffffff78425aULL,
+ 0x000000000e9e882dULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0xfffffffff7b0dd99ULL,
+ 0xfffffffff92e55b4ULL,
+ 0x000000005984bb41ULL,
+ 0x00000000571a336cULL,
+ 0xffffffffff78bda5ULL,
+ 0xfffffffff1e63588ULL,
+ 0xfffffffff92eff1eULL, /* 16 */
+ 0xfffffffff7b07733ULL,
+ 0x000000000000aaaaULL,
+ 0x000000000e9e2287ULL,
+ 0xffffffffae34cc72ULL,
+ 0xffffffffa0aa445fULL,
+ 0x0000000008c8ca96ULL,
+ 0x00000000065642bbULL,
+ 0xfffffffff7b088ccULL, /* 24 */
+ 0xfffffffff92e00e1ULL,
+ 0x000000000e9edd78ULL,
+ 0x0000000000005555ULL,
+ 0xffffffffa0aabba0ULL,
+ 0xffffffffae34338dULL,
+ 0x000000000656bd44ULL,
+ 0x0000000008c83569ULL,
+ 0x00000000571affa0ULL, /* 32 */
+ 0x000000005984778dULL,
+ 0xffffffffae34aa14ULL,
+ 0xffffffffa0aa2239ULL,
+ 0x000000000000ccccULL,
+ 0x000000000e9e44e1ULL,
+ 0xffffffffa6fcca28ULL,
+ 0xffffffffa8624205ULL,
+ 0x0000000059848872ULL, /* 40 */
+ 0x00000000571a005fULL,
+ 0xffffffffa0aaddc6ULL,
+ 0xffffffffae3455ebULL,
+ 0x000000000e9ebb1eULL,
+ 0x0000000000003333ULL,
+ 0xffffffffa862bdfaULL,
+ 0xffffffffa6fc35d7ULL,
+ 0xfffffffff1e6bbb0ULL, /* 48 */
+ 0xffffffffff78339dULL,
+ 0x0000000008c8ee04ULL,
+ 0x0000000006566629ULL,
+ 0xffffffffa6fc88dcULL,
+ 0xffffffffa86200f1ULL,
+ 0x0000000000008e38ULL,
+ 0x000000000e9e0615ULL,
+ 0xffffffffff78cc62ULL, /* 56 */
+ 0xfffffffff1e6444fULL,
+ 0x00000000065699d6ULL,
+ 0x0000000008c811fbULL,
+ 0xffffffffa862ff0eULL,
+ 0xffffffffa6fc7723ULL,
+ 0x000000000e9ef9eaULL,
+ 0x00000000000071c7ULL,
+ 0x0000000000002862ULL, /* 64 */
+ 0x000000001190c4cfULL,
+ 0x000000007b7fdbbeULL,
+ 0xffffffff9204da99ULL,
+ 0x000000001190a13eULL,
+ 0x0000000000004d93ULL,
+ 0x000000006aef52e2ULL,
+ 0xffffffff839453c5ULL,
+ 0x000000007b7f4a13ULL, /* 72 */
+ 0x000000006aefa6beULL,
+ 0x000000000000b9cfULL,
+ 0xffffffffe97bb8e8ULL,
+ 0xffffffff9204accaULL,
+ 0xffffffff83944067ULL,
+ 0xffffffffe97b5f16ULL,
+ 0x0000000000005e31ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CH(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CH(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cw.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cw.c
new file mode 100644
index 0000000..f7110b3
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32cw.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32CW
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0x82F63B78";
+ char *instruction_name = "CRC32CW";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x0000000000000000ULL, /* 0 */
+ 0xffffffffb798b438ULL,
+ 0xffffffff91d3be47ULL,
+ 0x00000000264b0a7fULL,
+ 0x0000000070b16a3dULL,
+ 0xffffffffc729de05ULL,
+ 0x0000000063c5950aULL,
+ 0xffffffffd45d2132ULL,
+ 0xffffffffb798b438ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0x00000000264b0a7fULL,
+ 0xffffffff91d3be47ULL,
+ 0xffffffffc729de05ULL,
+ 0x0000000070b16a3dULL,
+ 0xffffffffd45d2132ULL,
+ 0x0000000063c5950aULL,
+ 0xffffffff91d3be47ULL, /* 16 */
+ 0x00000000264b0a7fULL,
+ 0x0000000000000000ULL,
+ 0xffffffffb798b438ULL,
+ 0xffffffffe162d47aULL,
+ 0x0000000056fa6042ULL,
+ 0xfffffffff2162b4dULL,
+ 0x00000000458e9f75ULL,
+ 0x00000000264b0a7fULL, /* 24 */
+ 0xffffffff91d3be47ULL,
+ 0xffffffffb798b438ULL,
+ 0x0000000000000000ULL,
+ 0x0000000056fa6042ULL,
+ 0xffffffffe162d47aULL,
+ 0x00000000458e9f75ULL,
+ 0xfffffffff2162b4dULL,
+ 0x0000000070b16a3dULL, /* 32 */
+ 0xffffffffc729de05ULL,
+ 0xffffffffe162d47aULL,
+ 0x0000000056fa6042ULL,
+ 0x0000000000000000ULL,
+ 0xffffffffb798b438ULL,
+ 0x000000001374ff37ULL,
+ 0xffffffffa4ec4b0fULL,
+ 0xffffffffc729de05ULL, /* 40 */
+ 0x0000000070b16a3dULL,
+ 0x0000000056fa6042ULL,
+ 0xffffffffe162d47aULL,
+ 0xffffffffb798b438ULL,
+ 0x0000000000000000ULL,
+ 0xffffffffa4ec4b0fULL,
+ 0x000000001374ff37ULL,
+ 0x0000000063c5950aULL, /* 48 */
+ 0xffffffffd45d2132ULL,
+ 0xfffffffff2162b4dULL,
+ 0x00000000458e9f75ULL,
+ 0x000000001374ff37ULL,
+ 0xffffffffa4ec4b0fULL,
+ 0x0000000000000000ULL,
+ 0xffffffffb798b438ULL,
+ 0xffffffffd45d2132ULL, /* 56 */
+ 0x0000000063c5950aULL,
+ 0x00000000458e9f75ULL,
+ 0xfffffffff2162b4dULL,
+ 0xffffffffa4ec4b0fULL,
+ 0x000000001374ff37ULL,
+ 0xffffffffb798b438ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL, /* 64 */
+ 0xffffffffea0755b2ULL,
+ 0x0000000008b188e6ULL,
+ 0xffffffffff3cc8d9ULL,
+ 0xffffffffea0755b2ULL,
+ 0x0000000000000000ULL,
+ 0xffffffffe2b6dd54ULL,
+ 0x00000000153b9d6bULL,
+ 0x0000000008b188e6ULL, /* 72 */
+ 0xffffffffe2b6dd54ULL,
+ 0x0000000000000000ULL,
+ 0xfffffffff78d403fULL,
+ 0xffffffffff3cc8d9ULL,
+ 0x00000000153b9d6bULL,
+ 0xfffffffff78d403fULL,
+ 0x0000000000000000ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CW(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32CW(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32d.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32d.c
new file mode 100644
index 0000000..e391be8
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32d.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32D
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0xEDB88320";
+ char *instruction_name = "CRC32D";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0xffffffffdebb20e3ULL, /* 0 */
+ 0x0000000044660075ULL,
+ 0x000000001e20c2aeULL,
+ 0xffffffff84fde238ULL,
+ 0x00000000281d7ce7ULL,
+ 0xffffffffb2c05c71ULL,
+ 0xffffffffd660a024ULL,
+ 0x000000004cbd80b2ULL,
+ 0xffffffff9add2096ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0x000000005a46c2dbULL,
+ 0xffffffffc09be24dULL,
+ 0x000000006c7b7c92ULL,
+ 0xfffffffff6a65c04ULL,
+ 0xffffffff9206a051ULL,
+ 0x0000000008db80c7ULL,
+ 0x000000005449dd0fULL, /* 16 */
+ 0xffffffffce94fd99ULL,
+ 0xffffffff94d23f42ULL,
+ 0x000000000e0f1fd4ULL,
+ 0xffffffffa2ef810bULL,
+ 0x000000003832a19dULL,
+ 0x000000005c925dc8ULL,
+ 0xffffffffc64f7d5eULL,
+ 0x00000000102fdd7aULL, /* 24 */
+ 0xffffffff8af2fdecULL,
+ 0xffffffffd0b43f37ULL,
+ 0x000000004a691fa1ULL,
+ 0xffffffffe689817eULL,
+ 0x000000007c54a1e8ULL,
+ 0x0000000018f45dbdULL,
+ 0xffffffff82297d2bULL,
+ 0xffffffffa7157447ULL, /* 32 */
+ 0x000000003dc854d1ULL,
+ 0x00000000678e960aULL,
+ 0xfffffffffd53b69cULL,
+ 0x0000000051b32843ULL,
+ 0xffffffffcb6e08d5ULL,
+ 0xffffffffafcef480ULL,
+ 0x000000003513d416ULL,
+ 0xffffffffe3737432ULL, /* 40 */
+ 0x0000000079ae54a4ULL,
+ 0x0000000023e8967fULL,
+ 0xffffffffb935b6e9ULL,
+ 0x0000000015d52836ULL,
+ 0xffffffff8f0808a0ULL,
+ 0xffffffffeba8f4f5ULL,
+ 0x000000007175d463ULL,
+ 0x000000007a6adc3eULL, /* 48 */
+ 0xffffffffe0b7fca8ULL,
+ 0xffffffffbaf13e73ULL,
+ 0x00000000202c1ee5ULL,
+ 0xffffffff8ccc803aULL,
+ 0x000000001611a0acULL,
+ 0x0000000072b15cf9ULL,
+ 0xffffffffe86c7c6fULL,
+ 0x000000003e0cdc4bULL, /* 56 */
+ 0xffffffffa4d1fcddULL,
+ 0xfffffffffe973e06ULL,
+ 0x00000000644a1e90ULL,
+ 0xffffffffc8aa804fULL,
+ 0x000000005277a0d9ULL,
+ 0x0000000036d75c8cULL,
+ 0xffffffffac0a7c1aULL,
+ 0xffffffffed857593ULL, /* 64 */
+ 0xffffffffe0b6f95fULL,
+ 0x00000000253b462cULL,
+ 0xffffffffe15579b9ULL,
+ 0x0000000074897c83ULL,
+ 0x0000000079baf04fULL,
+ 0xffffffffbc374f3cULL,
+ 0x00000000785970a9ULL,
+ 0xffffffffa6bae0a9ULL, /* 72 */
+ 0xffffffffab896c65ULL,
+ 0x000000006e04d316ULL,
+ 0xffffffffaa6aec83ULL,
+ 0x000000005ae171feULL,
+ 0x0000000057d2fd32ULL,
+ 0xffffffff925f4241ULL,
+ 0x0000000056317dd4ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32D(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32D(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32h.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32h.c
new file mode 100644
index 0000000..100f02c
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32h.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32H
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0xEDB88320";
+ char *instruction_name = "CRC32H";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x000000000000ffffULL, /* 0 */
+ 0xffffffffbe2612ffULL,
+ 0xffffffffdccda6c0ULL,
+ 0x0000000062eb4bc0ULL,
+ 0x000000004bbbc8eaULL,
+ 0xfffffffff59d25eaULL,
+ 0x0000000022259ac0ULL,
+ 0xffffffff9c0377c0ULL,
+ 0xffffffffbe26ed00ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0x0000000062ebb43fULL,
+ 0xffffffffdccd593fULL,
+ 0xfffffffff59dda15ULL,
+ 0x000000004bbb3715ULL,
+ 0xffffffff9c03883fULL,
+ 0x000000002225653fULL,
+ 0xffffffffdccdf395ULL, /* 16 */
+ 0x0000000062eb1e95ULL,
+ 0x000000000000aaaaULL,
+ 0xffffffffbe2647aaULL,
+ 0xffffffff9776c480ULL,
+ 0x0000000029502980ULL,
+ 0xfffffffffee896aaULL,
+ 0x0000000040ce7baaULL,
+ 0x0000000062ebe16aULL, /* 24 */
+ 0xffffffffdccd0c6aULL,
+ 0xffffffffbe26b855ULL,
+ 0x0000000000005555ULL,
+ 0x000000002950d67fULL,
+ 0xffffffff97763b7fULL,
+ 0x0000000040ce8455ULL,
+ 0xfffffffffee86955ULL,
+ 0x000000004bbbfbd9ULL, /* 32 */
+ 0xfffffffff59d16d9ULL,
+ 0xffffffff9776a2e6ULL,
+ 0x0000000029504fe6ULL,
+ 0x000000000000ccccULL,
+ 0xffffffffbe2621ccULL,
+ 0x00000000699e9ee6ULL,
+ 0xffffffffd7b873e6ULL,
+ 0xfffffffff59de926ULL, /* 40 */
+ 0x000000004bbb0426ULL,
+ 0x000000002950b019ULL,
+ 0xffffffff97765d19ULL,
+ 0xffffffffbe26de33ULL,
+ 0x0000000000003333ULL,
+ 0xffffffffd7b88c19ULL,
+ 0x00000000699e6119ULL,
+ 0x000000002225eb07ULL, /* 48 */
+ 0xffffffff9c030607ULL,
+ 0xfffffffffee8b238ULL,
+ 0x0000000040ce5f38ULL,
+ 0x00000000699edc12ULL,
+ 0xffffffffd7b83112ULL,
+ 0x0000000000008e38ULL,
+ 0xffffffffbe266338ULL,
+ 0xffffffff9c03f9f8ULL, /* 56 */
+ 0x00000000222514f8ULL,
+ 0x0000000040cea0c7ULL,
+ 0xfffffffffee84dc7ULL,
+ 0xffffffffd7b8ceedULL,
+ 0x00000000699e23edULL,
+ 0xffffffffbe269cc7ULL,
+ 0x00000000000071c7ULL,
+ 0x0000000000002862ULL, /* 64 */
+ 0x0000000026a17af6ULL,
+ 0xffffffffaa919152ULL,
+ 0xffffffffcb865590ULL,
+ 0x0000000026a11f07ULL,
+ 0x0000000000004d93ULL,
+ 0xffffffff8c30a637ULL,
+ 0xffffffffed2762f5ULL,
+ 0xffffffffaa9100ffULL, /* 72 */
+ 0xffffffff8c30526bULL,
+ 0x000000000000b9cfULL,
+ 0x0000000061177d0dULL,
+ 0xffffffffcb8623c3ULL,
+ 0xffffffffed277157ULL,
+ 0x0000000061179af3ULL,
+ 0x0000000000005e31ULL
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32H(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32H(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32w.c b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32w.c
new file mode 100644
index 0000000..b4f5f4b
--- /dev/null
+++ b/tests/tcg/mips/user/isa/mips64r6/crc/test_mips64r6_crc32w.c
@@ -0,0 +1,142 @@
+/*
+ * Test program for MIPS64R6 instruction CRC32W
+ *
+ * Copyright (C) 2019 Wave Computing, Inc.
+ * Copyright (C) 2019 Aleksandar Markovic <amarkovic@wavecomp.com>
+ * Copyright (C) 2025 Aleksandar Rakic <aleksandar.rakic@htecgroup.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <sys/time.h>
+#include <stdint.h>
+
+#include "../../../../include/wrappers_mips64r6.h"
+#include "../../../../include/test_inputs_64.h"
+#include "../../../../include/test_utils_64.h"
+
+#define TEST_COUNT_TOTAL (PATTERN_INPUTS_64_COUNT + RANDOM_INPUTS_64_COUNT)
+
+int32_t main(void)
+{
+ char *isa_ase_name = "mips64r6";
+ char *group_name = "CRC with reversed polynomial 0xEDB88320";
+ char *instruction_name = "CRC32W";
+ int32_t ret;
+ uint32_t i, j;
+ struct timeval start, end;
+ double elapsed_time;
+
+ uint64_t b64_result[TEST_COUNT_TOTAL];
+ uint64_t b64_expect[TEST_COUNT_TOTAL] = {
+ 0x0000000000000000ULL, /* 0 */
+ 0xffffffffdebb20e3ULL,
+ 0x000000004a691fa1ULL,
+ 0xffffffff94d23f42ULL,
+ 0xffffffff8f0808a0ULL,
+ 0x0000000051b32843ULL,
+ 0x0000000065069dceULL,
+ 0xffffffffbbbdbd2dULL,
+ 0xffffffffdebb20e3ULL, /* 8 */
+ 0x0000000000000000ULL,
+ 0xffffffff94d23f42ULL,
+ 0x000000004a691fa1ULL,
+ 0x0000000051b32843ULL,
+ 0xffffffff8f0808a0ULL,
+ 0xffffffffbbbdbd2dULL,
+ 0x0000000065069dceULL,
+ 0x000000004a691fa1ULL, /* 16 */
+ 0xffffffff94d23f42ULL,
+ 0x0000000000000000ULL,
+ 0xffffffffdebb20e3ULL,
+ 0xffffffffc5611701ULL,
+ 0x000000001bda37e2ULL,
+ 0x000000002f6f826fULL,
+ 0xfffffffff1d4a28cULL,
+ 0xffffffff94d23f42ULL, /* 24 */
+ 0x000000004a691fa1ULL,
+ 0xffffffffdebb20e3ULL,
+ 0x0000000000000000ULL,
+ 0x000000001bda37e2ULL,
+ 0xffffffffc5611701ULL,
+ 0xfffffffff1d4a28cULL,
+ 0x000000002f6f826fULL,
+ 0xffffffff8f0808a0ULL, /* 32 */
+ 0x0000000051b32843ULL,
+ 0xffffffffc5611701ULL,
+ 0x000000001bda37e2ULL,
+ 0x0000000000000000ULL,
+ 0xffffffffdebb20e3ULL,
+ 0xffffffffea0e956eULL,
+ 0x0000000034b5b58dULL,
+ 0x0000000051b32843ULL, /* 40 */
+ 0xffffffff8f0808a0ULL,
+ 0x000000001bda37e2ULL,
+ 0xffffffffc5611701ULL,
+ 0xffffffffdebb20e3ULL,
+ 0x0000000000000000ULL,
+ 0x0000000034b5b58dULL,
+ 0xffffffffea0e956eULL,
+ 0x0000000065069dceULL, /* 48 */
+ 0xffffffffbbbdbd2dULL,
+ 0x000000002f6f826fULL,
+ 0xfffffffff1d4a28cULL,
+ 0xffffffffea0e956eULL,
+ 0x0000000034b5b58dULL,
+ 0x0000000000000000ULL,
+ 0xffffffffdebb20e3ULL,
+ 0xffffffffbbbdbd2dULL, /* 56 */
+ 0x0000000065069dceULL,
+ 0xfffffffff1d4a28cULL,
+ 0x000000002f6f826fULL,
+ 0x0000000034b5b58dULL,
+ 0xffffffffea0e956eULL,
+ 0xffffffffdebb20e3ULL,
+ 0x0000000000000000ULL,
+ 0x0000000000000000ULL, /* 64 */
+ 0xffffffff90485967ULL,
+ 0x000000006dfb974aULL,
+ 0x00000000083e4538ULL,
+ 0xffffffff90485967ULL,
+ 0x0000000000000000ULL,
+ 0xfffffffffdb3ce2dULL,
+ 0xffffffff98761c5fULL,
+ 0x000000006dfb974aULL, /* 72 */
+ 0xfffffffffdb3ce2dULL,
+ 0x0000000000000000ULL,
+ 0x0000000065c5d272ULL,
+ 0x00000000083e4538ULL,
+ 0xffffffff98761c5fULL,
+ 0x0000000065c5d272ULL,
+ 0x0000000000000000ULL,
+ };
+
+ gettimeofday(&start, NULL);
+
+ for (i = 0; i < PATTERN_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < PATTERN_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32W(b64_pattern + i, b64_pattern + j,
+ b64_result + (PATTERN_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ for (i = 0; i < RANDOM_INPUTS_64_SHORT_COUNT; i++) {
+ for (j = 0; j < RANDOM_INPUTS_64_SHORT_COUNT; j++) {
+ do_mips64r6_CRC32W(b64_random + i, b64_random + j,
+ b64_result + (((PATTERN_INPUTS_64_SHORT_COUNT) *
+ (PATTERN_INPUTS_64_SHORT_COUNT)) +
+ RANDOM_INPUTS_64_SHORT_COUNT * i + j));
+ }
+ }
+
+ gettimeofday(&end, NULL);
+
+ elapsed_time = (end.tv_sec - start.tv_sec) * 1000.0;
+ elapsed_time += (end.tv_usec - start.tv_usec) / 1000.0;
+
+ ret = check_results_64(isa_ase_name, group_name, instruction_name,
+ TEST_COUNT_TOTAL, elapsed_time, b64_result,
+ b64_expect);
+
+ return ret;
+}
diff --git a/tests/tcg/multiarch/Makefile.target b/tests/tcg/multiarch/Makefile.target
index 45c9cfe..f5b4d2b 100644
--- a/tests/tcg/multiarch/Makefile.target
+++ b/tests/tcg/multiarch/Makefile.target
@@ -29,6 +29,7 @@ run-float_%: float_%
$(call run-test,$<, $(QEMU) $(QEMU_OPTS) $<)
$(call conditional-diff-out,$<,$(SRC_PATH)/tests/tcg/$(TARGET_NAME)/$<.ref)
+fnmsub: LDFLAGS+=-lm
testthread: LDFLAGS+=-lpthread
@@ -45,6 +46,8 @@ vma-pthread: LDFLAGS+=-pthread
sigreturn-sigmask: CFLAGS+=-pthread
sigreturn-sigmask: LDFLAGS+=-pthread
+tb-link: LDFLAGS+=-lpthread
+
# GCC versions 12/13/14/15 at least incorrectly complain about
# "'SHA1Transform' reading 64 bytes from a region of size 0"; see the gcc bug
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106709
@@ -188,6 +191,10 @@ run-plugin-semiconsole-with-%:
TESTS += semihosting semiconsole
endif
+test-plugin-mem-access: CFLAGS+=-pthread -O0
+test-plugin-mem-access: LDFLAGS+=-pthread -O0
+
+ifeq ($(CONFIG_PLUGIN),y)
# Test plugin memory access instrumentation
run-plugin-test-plugin-mem-access-with-libmem.so: \
PLUGIN_ARGS=$(COMMA)print-accesses=true
@@ -196,8 +203,8 @@ run-plugin-test-plugin-mem-access-with-libmem.so: \
$(SRC_PATH)/tests/tcg/multiarch/check-plugin-output.sh \
$(QEMU) $<
-test-plugin-mem-access: CFLAGS+=-pthread -O0
-test-plugin-mem-access: LDFLAGS+=-pthread -O0
+EXTRA_RUNS_WITH_PLUGIN += run-plugin-test-plugin-mem-access-with-libmem.so
+endif
# Update TESTS
TESTS += $(MULTIARCH_TESTS)
diff --git a/tests/tcg/multiarch/fnmsub.c b/tests/tcg/multiarch/fnmsub.c
new file mode 100644
index 0000000..15dd41d
--- /dev/null
+++ b/tests/tcg/multiarch/fnmsub.c
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <stdio.h>
+#include <math.h>
+#include <fenv.h>
+
+union U {
+ double d;
+ unsigned long long l;
+};
+
+union U x = { .l = 0x4ff0000000000000ULL };
+union U y = { .l = 0x2ff0000000000000ULL };
+union U r;
+
+int main()
+{
+#ifdef FE_DOWNWARD
+ fesetround(FE_DOWNWARD);
+
+#if defined(__loongarch__)
+ asm("fnmsub.d %0, %1, %1, %2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__powerpc64__)
+ asm("fnmsub %0,%1,%1,%2" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#elif defined(__s390x__) && 0 /* need -march=z14 */
+ asm("vfnms %0,%1,%1,%2,0,3" : "=f"(r.d) : "f"(x.d), "f"(y.d));
+#else
+ r.d = -fma(x.d, x.d, -y.d);
+#endif
+
+ if (r.l != 0xdfefffffffffffffULL) {
+ printf("r = %.18a (%016llx)\n", r.d, r.l);
+ return 1;
+ }
+#endif
+ return 0;
+}
diff --git a/tests/tcg/multiarch/gdbstub/interrupt.py b/tests/tcg/multiarch/gdbstub/interrupt.py
index 2d5654d..4eccdb4 100644
--- a/tests/tcg/multiarch/gdbstub/interrupt.py
+++ b/tests/tcg/multiarch/gdbstub/interrupt.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test some of the system debug features with the multiarch memory
# test. It is a port of the original vmlinux focused test case but
diff --git a/tests/tcg/multiarch/gdbstub/memory.py b/tests/tcg/multiarch/gdbstub/memory.py
index 532b92e..76d75e5 100644
--- a/tests/tcg/multiarch/gdbstub/memory.py
+++ b/tests/tcg/multiarch/gdbstub/memory.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test some of the system debug features with the multiarch memory
# test. It is a port of the original vmlinux focused test case but
diff --git a/tests/tcg/multiarch/gdbstub/sha1.py b/tests/tcg/multiarch/gdbstub/sha1.py
index 1ce711a..3403b82 100644
--- a/tests/tcg/multiarch/gdbstub/sha1.py
+++ b/tests/tcg/multiarch/gdbstub/sha1.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# A very simple smoke test for debugging the SHA1 userspace test on
# each target.
diff --git a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
index 6eb6ebf..796dca7 100644
--- a/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
+++ b/tests/tcg/multiarch/gdbstub/test-proc-mappings.py
@@ -1,7 +1,6 @@
"""Test that gdbstub has access to proc mappings.
This runs as a sourced script (via -x, via run-test.py)."""
-from __future__ import print_function
import gdb
from test_gdbstub import gdb_exit, main, report
diff --git a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
index 00c26ab..fa36c94 100644
--- a/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
+++ b/tests/tcg/multiarch/gdbstub/test-qxfer-auxv-read.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test auxiliary vector is loaded via gdbstub
#
diff --git a/tests/tcg/multiarch/gdbstub/test-qxfer-siginfo-read.py b/tests/tcg/multiarch/gdbstub/test-qxfer-siginfo-read.py
index 862596b..b18fa12 100644
--- a/tests/tcg/multiarch/gdbstub/test-qxfer-siginfo-read.py
+++ b/tests/tcg/multiarch/gdbstub/test-qxfer-siginfo-read.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test gdbstub Xfer:siginfo:read stub.
#
diff --git a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
index 4d6b6b9..49cbc35 100644
--- a/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
+++ b/tests/tcg/multiarch/gdbstub/test-thread-breakpoint.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test auxiliary vector is loaded via gdbstub
#
diff --git a/tests/tcg/multiarch/system/Makefile.softmmu-target b/tests/tcg/multiarch/system/Makefile.softmmu-target
index 07be001..98c4eda 100644
--- a/tests/tcg/multiarch/system/Makefile.softmmu-target
+++ b/tests/tcg/multiarch/system/Makefile.softmmu-target
@@ -6,6 +6,11 @@
# architecture to add to the test dependencies and deal with the
# complications of building.
#
+# To support the multiarch guests the target arch needs to provide a
+# boot.S that jumps to main and provides a __sys_outc functions.
+# Remember to update MULTIARCH_SOFTMMU_TARGETS in the tcg test
+# Makefile.target when this is done.
+#
MULTIARCH_SRC=$(SRC_PATH)/tests/tcg/multiarch
MULTIARCH_SYSTEM_SRC=$(MULTIARCH_SRC)/system
@@ -66,8 +71,11 @@ endif
MULTIARCH_RUNS += run-gdbstub-memory run-gdbstub-interrupt \
run-gdbstub-untimely-packet run-gdbstub-registers
+ifeq ($(CONFIG_PLUGIN),y)
# Test plugin memory access instrumentation
-run-plugin-memory-with-libmem.so: \
- PLUGIN_ARGS=$(COMMA)region-summary=true
-run-plugin-memory-with-libmem.so: \
- CHECK_PLUGIN_OUTPUT_COMMAND=$(MULTIARCH_SYSTEM_SRC)/validate-memory-counts.py $@.out
+run-plugin-memory-with-libmem.so: memory libmem.so
+run-plugin-memory-with-libmem.so: PLUGIN_ARGS=$(COMMA)region-summary=true
+run-plugin-memory-with-libmem.so: CHECK_PLUGIN_OUTPUT_COMMAND=$(MULTIARCH_SYSTEM_SRC)/validate-memory-counts.py $@.out
+
+EXTRA_RUNS_WITH_PLUGIN += run-plugin-memory-with-libmem.so
+endif
diff --git a/tests/tcg/multiarch/tb-link.c b/tests/tcg/multiarch/tb-link.c
new file mode 100644
index 0000000..4e40306
--- /dev/null
+++ b/tests/tcg/multiarch/tb-link.c
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Verify that a single TB spin-loop is properly invalidated,
+ * releasing the thread from the spin-loop.
+ */
+
+#include <assert.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <sched.h>
+
+
+#ifdef __x86_64__
+#define READY 0x000047c6 /* movb $0,0(%rdi) */
+#define LOOP 0xfceb9090 /* 1: nop*2; jmp 1b */
+#define RETURN 0x909090c3 /* ret; nop*3 */
+#define NOP 0x90909090 /* nop*4 */
+#elif defined(__aarch64__)
+#define READY 0x3900001f /* strb wzr,[x0] */
+#define LOOP 0x14000000 /* b . */
+#define RETURN 0xd65f03c0 /* ret */
+#define NOP 0xd503201f /* nop */
+#elif defined(__riscv)
+#define READY 0x00050023 /* sb zero, (a0) */
+#define LOOP 0x0000006f /* jal zero, #0 */
+#define RETURN 0x00008067 /* jalr zero, ra, 0 */
+#define NOP 0x00000013 /* nop */
+#endif
+
+
+int main()
+{
+#ifdef READY
+ int tmp;
+ pthread_t thread_id;
+ bool hold = true;
+ uint32_t *buf;
+
+ buf = mmap(NULL, 3 * sizeof(uint32_t),
+ PROT_READ | PROT_WRITE | PROT_EXEC,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ assert(buf != MAP_FAILED);
+
+ buf[0] = READY;
+ buf[1] = LOOP;
+ buf[2] = RETURN;
+
+ alarm(2);
+
+ tmp = pthread_create(&thread_id, NULL, (void *(*)(void *))buf, &hold);
+ assert(tmp == 0);
+
+ while (hold) {
+ sched_yield();
+ }
+
+ buf[1] = NOP;
+ __builtin___clear_cache(&buf[1], &buf[2]);
+
+ tmp = pthread_join(thread_id, NULL);
+ assert(tmp == 0);
+#endif
+ return 0;
+}
diff --git a/tests/tcg/plugins/mem.c b/tests/tcg/plugins/mem.c
index ca4e888..9649bce 100644
--- a/tests/tcg/plugins/mem.c
+++ b/tests/tcg/plugins/mem.c
@@ -20,6 +20,7 @@
* few things provided by compiler.h.
*/
#include <compiler.h>
+#include <stdbool.h>
#include <bswap.h>
#include <qemu-plugin.h>
diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build
index 41f02f2..61a007d 100644
--- a/tests/tcg/plugins/meson.build
+++ b/tests/tcg/plugins/meson.build
@@ -1,6 +1,6 @@
t = []
if get_option('plugins')
- foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall']
+ foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall', 'patch']
if host_os == 'windows'
t += shared_module(i, files(i + '.c') + '../../../contrib/plugins/win32_linker.c',
include_directories: '../../../include/qemu',
@@ -17,7 +17,7 @@ endif
if t.length() > 0
alias_target('test-plugins', t)
else
- run_target('test-plugins', command: find_program('true'))
+ run_target('test-plugins', command: [python, '-c', ''])
endif
plugin_modules += t
diff --git a/tests/tcg/plugins/patch.c b/tests/tcg/plugins/patch.c
new file mode 100644
index 0000000..111c5c1
--- /dev/null
+++ b/tests/tcg/plugins/patch.c
@@ -0,0 +1,251 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This plugin patches instructions matching a pattern to a different
+ * instruction as they execute
+ *
+ */
+
+#include "glib.h"
+#include "glibconfig.h"
+
+#include <qemu-plugin.h>
+#include <string.h>
+#include <stdio.h>
+
+QEMU_PLUGIN_EXPORT int qemu_plugin_version = QEMU_PLUGIN_VERSION;
+
+static bool use_hwaddr;
+static GByteArray *target_data;
+static GByteArray *patch_data;
+
+/**
+ * Parse a string of hexadecimal digits into a GByteArray. The string must be
+ * even length
+ */
+static GByteArray *str_to_bytes(const char *str)
+{
+ size_t len = strlen(str);
+
+ if (len == 0 || len % 2 != 0) {
+ return NULL;
+ }
+
+ GByteArray *bytes = g_byte_array_new();
+ char byte[3] = {0};
+ guint8 value = 0;
+
+ for (size_t i = 0; i < len; i += 2) {
+ byte[0] = str[i];
+ byte[1] = str[i + 1];
+ value = (guint8)g_ascii_strtoull(byte, NULL, 16);
+ g_byte_array_append(bytes, &value, 1);
+ }
+
+ return bytes;
+}
+
+static void patch_hwaddr(unsigned int vcpu_index, void *userdata)
+{
+ uintptr_t addr = (uintptr_t) userdata;
+ g_autoptr(GString) str = g_string_new(NULL);
+ g_string_printf(str, "patching: @0x%"
+ PRIxPTR "\n",
+ addr);
+ qemu_plugin_outs(str->str);
+
+ enum qemu_plugin_hwaddr_operation_result result =
+ qemu_plugin_write_memory_hwaddr(addr, patch_data);
+
+
+ if (result != QEMU_PLUGIN_HWADDR_OPERATION_OK) {
+ g_autoptr(GString) errmsg = g_string_new(NULL);
+ g_string_printf(errmsg, "Failed to write memory: %d\n", result);
+ qemu_plugin_outs(errmsg->str);
+ return;
+ }
+
+ GByteArray *read_data = g_byte_array_new();
+
+ result = qemu_plugin_read_memory_hwaddr(addr, read_data,
+ patch_data->len);
+
+ qemu_plugin_outs("Reading memory...\n");
+
+ if (result != QEMU_PLUGIN_HWADDR_OPERATION_OK) {
+ g_autoptr(GString) errmsg = g_string_new(NULL);
+ g_string_printf(errmsg, "Failed to read memory: %d\n", result);
+ qemu_plugin_outs(errmsg->str);
+ return;
+ }
+
+ if (memcmp(patch_data->data, read_data->data, patch_data->len) != 0) {
+ qemu_plugin_outs("Failed to read back written data\n");
+ }
+
+ qemu_plugin_outs("Success!\n");
+
+ return;
+}
+
+static void patch_vaddr(unsigned int vcpu_index, void *userdata)
+{
+ uintptr_t addr = (uintptr_t) userdata;
+ uint64_t hwaddr = 0;
+ if (!qemu_plugin_translate_vaddr(addr, &hwaddr)) {
+ qemu_plugin_outs("Failed to translate vaddr\n");
+ return;
+ }
+ g_autoptr(GString) str = g_string_new(NULL);
+ g_string_printf(str, "patching: @0x%"
+ PRIxPTR " hw: @0x%" PRIx64 "\n",
+ addr, hwaddr);
+ qemu_plugin_outs(str->str);
+
+ qemu_plugin_outs("Writing memory (vaddr)...\n");
+
+ if (!qemu_plugin_write_memory_vaddr(addr, patch_data)) {
+ qemu_plugin_outs("Failed to write memory\n");
+ return;
+ }
+
+ qemu_plugin_outs("Reading memory (vaddr)...\n");
+
+ g_autoptr(GByteArray) read_data = g_byte_array_new();
+
+ if (!qemu_plugin_read_memory_vaddr(addr, read_data, patch_data->len)) {
+ qemu_plugin_outs("Failed to read memory\n");
+ return;
+ }
+
+ if (memcmp(patch_data->data, read_data->data, patch_data->len) != 0) {
+ qemu_plugin_outs("Failed to read back written data\n");
+ }
+
+ qemu_plugin_outs("Success!\n");
+
+ return;
+}
+
+/*
+ * Callback on translation of a translation block.
+ */
+static void vcpu_tb_trans_cb(qemu_plugin_id_t id, struct qemu_plugin_tb *tb)
+{
+ g_autoptr(GByteArray) insn_data = g_byte_array_new();
+ uintptr_t addr = 0;
+
+ for (size_t i = 0; i < qemu_plugin_tb_n_insns(tb); i++) {
+ struct qemu_plugin_insn *insn = qemu_plugin_tb_get_insn(tb, i);
+ uint64_t vaddr = qemu_plugin_insn_vaddr(insn);
+
+ if (use_hwaddr) {
+ uint64_t hwaddr = 0;
+ if (!qemu_plugin_translate_vaddr(vaddr, &hwaddr)) {
+ qemu_plugin_outs("Failed to translate vaddr\n");
+ continue;
+ }
+ /*
+ * As we cannot emulate 64 bit systems on 32 bit hosts we
+ * should never see the top bits set, hence we can safely
+ * cast to uintptr_t.
+ */
+ g_assert(hwaddr <= UINTPTR_MAX);
+ addr = (uintptr_t) hwaddr;
+ } else {
+ g_assert(vaddr <= UINTPTR_MAX);
+ addr = (uintptr_t) vaddr;
+ }
+
+ g_byte_array_set_size(insn_data, qemu_plugin_insn_size(insn));
+ qemu_plugin_insn_data(insn, insn_data->data, insn_data->len);
+
+ if (insn_data->len >= target_data->len &&
+ !memcmp(insn_data->data, target_data->data,
+ MIN(target_data->len, insn_data->len))) {
+ if (use_hwaddr) {
+ qemu_plugin_register_vcpu_tb_exec_cb(tb, patch_hwaddr,
+ QEMU_PLUGIN_CB_NO_REGS,
+ (void *) addr);
+ } else {
+ qemu_plugin_register_vcpu_tb_exec_cb(tb, patch_vaddr,
+ QEMU_PLUGIN_CB_NO_REGS,
+ (void *) addr);
+ }
+ }
+ }
+}
+
+static void usage(void)
+{
+ fprintf(stderr, "Usage: <lib>,target=<bytes>,patch=<new_bytes>"
+ "[,use_hwaddr=true|false]");
+}
+
+/*
+ * Called when the plugin is installed
+ */
+QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id,
+ const qemu_info_t *info, int argc,
+ char **argv)
+{
+
+ use_hwaddr = true;
+ target_data = NULL;
+ patch_data = NULL;
+
+ if (argc > 4) {
+ usage();
+ return -1;
+ }
+
+ for (size_t i = 0; i < argc; i++) {
+ char *opt = argv[i];
+ g_auto(GStrv) tokens = g_strsplit(opt, "=", 2);
+ if (g_strcmp0(tokens[0], "use_hwaddr") == 0) {
+ if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &use_hwaddr)) {
+ fprintf(stderr,
+ "Failed to parse boolean argument use_hwaddr\n");
+ return -1;
+ }
+ } else if (g_strcmp0(tokens[0], "target") == 0) {
+ target_data = str_to_bytes(tokens[1]);
+ if (!target_data) {
+ fprintf(stderr,
+ "Failed to parse target bytes.\n");
+ return -1;
+ }
+ } else if (g_strcmp0(tokens[0], "patch") == 0) {
+ patch_data = str_to_bytes(tokens[1]);
+ if (!patch_data) {
+ fprintf(stderr, "Failed to parse patch bytes.\n");
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "Unknown argument: %s\n", tokens[0]);
+ usage();
+ return -1;
+ }
+ }
+
+ if (!target_data) {
+ fprintf(stderr, "target argument is required\n");
+ usage();
+ return -1;
+ }
+
+ if (!patch_data) {
+ fprintf(stderr, "patch argument is required\n");
+ usage();
+ return -1;
+ }
+
+ if (target_data->len != patch_data->len) {
+ fprintf(stderr, "Target and patch data must be the same length\n");
+ return -1;
+ }
+
+ qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans_cb);
+
+ return 0;
+}
diff --git a/tests/tcg/riscv64/Makefile.softmmu-target b/tests/tcg/riscv64/Makefile.softmmu-target
index 7c1d44d..3ca5953 100644
--- a/tests/tcg/riscv64/Makefile.softmmu-target
+++ b/tests/tcg/riscv64/Makefile.softmmu-target
@@ -20,5 +20,9 @@ EXTRA_RUNS += run-issue1060
run-issue1060: issue1060
$(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
+EXTRA_RUNS += run-test-mepc-masking
+run-test-mepc-masking: test-mepc-masking
+ $(call run-test, $<, $(QEMU) $(QEMU_OPTS)$<)
+
# We don't currently support the multiarch system tests
undefine MULTIARCH_TESTS
diff --git a/tests/tcg/riscv64/test-mepc-masking.S b/tests/tcg/riscv64/test-mepc-masking.S
new file mode 100644
index 0000000..fccd2a7
--- /dev/null
+++ b/tests/tcg/riscv64/test-mepc-masking.S
@@ -0,0 +1,73 @@
+/*
+ * Test for MEPC masking bug fix
+ *
+ * This test verifies that MEPC properly masks the lower bits according
+ * to the RISC-V specification when vectored mode bits from STVEC are
+ * written to MEPC.
+ */
+
+ .option norvc
+
+ .text
+ .global _start
+_start:
+ /* Set up machine trap vector */
+ lla t0, machine_trap_handler
+ csrw mtvec, t0
+
+ /* Set STVEC with vectored mode (mode bits = 01) */
+ li t0, 0x80004001
+ csrw stvec, t0
+
+ /* Clear medeleg to handle exceptions in M-mode */
+ csrw medeleg, zero
+
+ /* Trigger illegal instruction exception */
+ .word 0xffffffff
+
+test_completed:
+ /* Exit with result in a0 */
+ /* a0 = 0: success (bits [1:0] were masked) */
+ /* a0 != 0: failure (some bits were not masked) */
+ j _exit
+
+machine_trap_handler:
+ /* Check if illegal instruction (mcause = 2) */
+ csrr t0, mcause
+ li t1, 2
+ bne t0, t1, skip_test
+
+ /* Test: Copy STVEC (with mode bits) to MEPC */
+ csrr t0, stvec /* t0 = 0x80004001 */
+ csrw mepc, t0 /* Write to MEPC */
+ csrr t1, mepc /* Read back MEPC */
+
+ /* Check if bits [1:0] are masked (IALIGN=32 without RVC) */
+ andi a0, t1, 3 /* a0 = 0 if both bits masked correctly */
+
+ /* Set correct return address */
+ lla t0, test_completed
+ csrw mepc, t0
+
+skip_test:
+ mret
+
+/* Exit with semihosting */
+_exit:
+ lla a1, semiargs
+ li t0, 0x20026 /* ADP_Stopped_ApplicationExit */
+ sd t0, 0(a1)
+ sd a0, 8(a1)
+ li a0, 0x20 /* TARGET_SYS_EXIT_EXTENDED */
+
+ /* Semihosting call sequence */
+ .balign 16
+ slli zero, zero, 0x1f
+ ebreak
+ srai zero, zero, 0x7
+ j .
+
+ .data
+ .balign 8
+semiargs:
+ .space 16
diff --git a/tests/tcg/s390x/gdbstub/test-signals-s390x.py b/tests/tcg/s390x/gdbstub/test-signals-s390x.py
index b6b7b39..398ad53 100644
--- a/tests/tcg/s390x/gdbstub/test-signals-s390x.py
+++ b/tests/tcg/s390x/gdbstub/test-signals-s390x.py
@@ -1,4 +1,3 @@
-from __future__ import print_function
#
# Test that signals and debugging mix well together on s390x.
diff --git a/tests/tcg/s390x/gdbstub/test-svc.py b/tests/tcg/s390x/gdbstub/test-svc.py
index 17210b4..29a0aa0 100644
--- a/tests/tcg/s390x/gdbstub/test-svc.py
+++ b/tests/tcg/s390x/gdbstub/test-svc.py
@@ -1,7 +1,6 @@
"""Test single-stepping SVC.
This runs as a sourced script (via -x, via run-test.py)."""
-from __future__ import print_function
import gdb
from test_gdbstub import main, report
diff --git a/tests/tcg/x86_64/Makefile.softmmu-target b/tests/tcg/x86_64/Makefile.softmmu-target
index ef6bcb4..4e65f58 100644
--- a/tests/tcg/x86_64/Makefile.softmmu-target
+++ b/tests/tcg/x86_64/Makefile.softmmu-target
@@ -1,13 +1,11 @@
#
-# x86 system tests
-#
-# This currently builds only for i386. The common C code is built
-# with standard compiler flags however so we can support both by
-# adding additional boot files for x86_64.
+# x86_64 system tests
#
-I386_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/i386/system
X64_SYSTEM_SRC=$(SRC_PATH)/tests/tcg/x86_64/system
+X64_SYSTEM_TESTS=$(patsubst $(X64_SYSTEM_SRC)/%.c, %, $(wildcard $(X64_SYSTEM_SRC)/*.c))
+
+VPATH+=$(X64_SYSTEM_SRC)
# These objects provide the basic boot code and helper functions for all tests
CRT_OBJS=boot.o
@@ -18,7 +16,7 @@ LDFLAGS=-Wl,-T$(LINK_SCRIPT) -Wl,-melf_x86_64
CFLAGS+=-nostdlib -ggdb -O0 $(MINILIB_INC)
LDFLAGS+=-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc
-TESTS+=$(MULTIARCH_TESTS)
+TESTS+=$(MULTIARCH_TESTS) $(X64_SYSTEM_TESTS)
EXTRA_RUNS+=$(MULTIARCH_RUNS)
# building head blobs
@@ -35,3 +33,12 @@ memory: CFLAGS+=-DCHECK_UNALIGNED=1
# Running
QEMU_OPTS+=-device isa-debugcon,chardev=output -device isa-debug-exit,iobase=0xf4,iosize=0x4 -kernel
+
+ifeq ($(CONFIG_PLUGIN),y)
+run-plugin-patch-target-with-libpatch.so: \
+ PLUGIN_ARGS=$(COMMA)target=ffc0$(COMMA)patch=9090$(COMMA)use_hwaddr=true
+run-plugin-patch-target-with-libpatch.so: \
+ CHECK_PLUGIN_OUTPUT_COMMAND=$(X64_SYSTEM_SRC)/validate-patch.py $@.out
+run-plugin-patch-target-with-libpatch.so: patch-target libpatch.so
+EXTRA_RUNS_WITH_PLUGIN+=run-plugin-patch-target-with-libpatch.so
+endif
diff --git a/tests/tcg/x86_64/fma.c b/tests/tcg/x86_64/fma.c
index 09c622e..3421961 100644
--- a/tests/tcg/x86_64/fma.c
+++ b/tests/tcg/x86_64/fma.c
@@ -79,14 +79,21 @@ static testdata tests[] = {
/*
* Flushing of denormal outputs to zero should also happen after
* rounding, so setting FTZ should not affect the result or the flags.
- * QEMU currently does not emulate this correctly because we do the
- * flush-to-zero check before rounding, so we incorrectly produce a
- * zero result and set Underflow as well as Precision.
*/
-#ifdef ENABLE_FAILING_TESTS
{ 0x3fdfffffffffffff, 0x001fffffffffffff, 0x801fffffffffffff, true,
0x8010000000000000, 0x20 }, /* Enabling FTZ shouldn't change flags */
-#endif
+ /*
+ * normal * 0 + a denormal. With FTZ disabled this gives an exact
+ * result (equal to the input denormal) that has consumed the denormal.
+ */
+ { 0x3cc8000000000000, 0x0000000000000000, 0x8008000000000000, false,
+ 0x8008000000000000, 0x2 }, /* Denormal */
+ /*
+ * With FTZ enabled, this consumes the denormal, returns zero (because
+ * flushed) and indicates also Underflow and Precision.
+ */
+ { 0x3cc8000000000000, 0x0000000000000000, 0x8008000000000000, true,
+ 0x8000000000000000, 0x32 }, /* Precision, Underflow, Denormal */
};
int main(void)
diff --git a/tests/tcg/x86_64/system/patch-target.c b/tests/tcg/x86_64/system/patch-target.c
new file mode 100644
index 0000000..8c2b6f4
--- /dev/null
+++ b/tests/tcg/x86_64/system/patch-target.c
@@ -0,0 +1,22 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This test target increments a value 100 times. The patcher converts the
+ * inc instruction to a nop, so it only increments the value once.
+ *
+ */
+#include <minilib.h>
+
+int main(void)
+{
+ ml_printf("Running test...\n");
+ unsigned int x = 0;
+ for (int i = 0; i < 100; i++) {
+ asm volatile (
+ "inc %[x]"
+ : [x] "+a" (x)
+ );
+ }
+ ml_printf("Value: %d\n", x);
+ return 0;
+}
diff --git a/tests/tcg/x86_64/system/validate-patch.py b/tests/tcg/x86_64/system/validate-patch.py
new file mode 100755
index 0000000..700950e
--- /dev/null
+++ b/tests/tcg/x86_64/system/validate-patch.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+#
+# validate-patch.py: check the patch applies
+#
+# This program takes two inputs:
+# - the plugin output
+# - the binary output
+#
+# Copyright (C) 2024
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import sys
+from argparse import ArgumentParser
+
+def main() -> None:
+ """
+ Process the arguments, injest the program and plugin out and
+ verify they match up and report if they do not.
+ """
+ parser = ArgumentParser(description="Validate patch")
+ parser.add_argument('test_output',
+ help="The output from the test itself")
+ parser.add_argument('plugin_output',
+ help="The output from plugin")
+ args = parser.parse_args()
+
+ with open(args.test_output, 'r') as f:
+ test_data = f.read()
+ with open(args.plugin_output, 'r') as f:
+ plugin_data = f.read()
+ if "Value: 1" in test_data:
+ sys.exit(0)
+ else:
+ sys.exit(1)
+
+if __name__ == "__main__":
+ main()
+
diff --git a/tests/tracetool/dtrace.c b/tests/tracetool/dtrace.c
new file mode 100644
index 0000000..9f862fa
--- /dev/null
+++ b/tests/tracetool/dtrace.c
@@ -0,0 +1,32 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
diff --git a/tests/tracetool/dtrace.d b/tests/tracetool/dtrace.d
new file mode 100644
index 0000000..5cc06f9
--- /dev/null
+++ b/tests/tracetool/dtrace.d
@@ -0,0 +1,10 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+provider qemu {
+
+probe test_blah(void * context,const char * filename);
+
+probe test_wibble(void * context,int value);
+
+};
diff --git a/tests/tracetool/dtrace.h b/tests/tracetool/dtrace.h
new file mode 100644
index 0000000..c8931a8
--- /dev/null
+++ b/tests/tracetool/dtrace.h
@@ -0,0 +1,45 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+#ifndef SDT_USE_VARIADIC
+#define SDT_USE_VARIADIC 1
+#endif
+#include "trace-dtrace-testsuite.h"
+
+#undef SDT_USE_VARIADIC
+#ifndef QEMU_TEST_BLAH_ENABLED
+#define QEMU_TEST_BLAH_ENABLED() true
+#endif
+#ifndef QEMU_TEST_WIBBLE_ENABLED
+#define QEMU_TEST_WIBBLE_ENABLED() true
+#endif
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ QEMU_TEST_BLAH_ENABLED() || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ QEMU_TEST_BLAH(context, filename);
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ QEMU_TEST_WIBBLE_ENABLED() || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ QEMU_TEST_WIBBLE(context, value);
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/dtrace.log-stap b/tests/tracetool/dtrace.log-stap
new file mode 100644
index 0000000..092986e
--- /dev/null
+++ b/tests/tracetool/dtrace.log-stap
@@ -0,0 +1,15 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+probe qemu.log.test_blah = qemu.test_blah ?
+{
+ try {
+ argfilename_str = filename ? user_string_n(filename, 512) : "<null>"
+ } catch {}
+ printf("%d@%d test_blah Blah context=%p filename=%s\n", pid(), gettimeofday_ns(), context, argfilename_str)
+}
+probe qemu.log.test_wibble = qemu.test_wibble ?
+{
+ printf("%d@%d test_wibble Wibble context=%p value=%d\n", pid(), gettimeofday_ns(), context, value)
+}
+
diff --git a/tests/tracetool/dtrace.simpletrace-stap b/tests/tracetool/dtrace.simpletrace-stap
new file mode 100644
index 0000000..d064e3e
--- /dev/null
+++ b/tests/tracetool/dtrace.simpletrace-stap
@@ -0,0 +1,16 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+probe qemu.simpletrace.test_blah = qemu.test_blah ?
+{
+ try {
+ argfilename_str = filename ? user_string_n(filename, 512) : "<null>"
+ } catch {}
+ argfilename_len = strlen(argfilename_str)
+ printf("%8b%8b%8b%4b%4b%8b%4b%.*s", 1, 0, gettimeofday_ns(), 24 + 8 + 4 + argfilename_len, pid(), context, argfilename_len, argfilename_len, argfilename_str)
+}
+probe qemu.simpletrace.test_wibble = qemu.test_wibble ?
+{
+ printf("%8b%8b%8b%4b%4b%8b%8b", 1, 1, gettimeofday_ns(), 24 + 8 + 8, pid(), context, value)
+}
+
diff --git a/tests/tracetool/dtrace.stap b/tests/tracetool/dtrace.stap
new file mode 100644
index 0000000..9c5d8a5
--- /dev/null
+++ b/tests/tracetool/dtrace.stap
@@ -0,0 +1,14 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+probe qemu.test_blah = process("qemu").mark("test_blah")
+{
+ context = $arg1;
+ filename = $arg2;
+}
+probe qemu.test_wibble = process("qemu").mark("test_wibble")
+{
+ context = $arg1;
+ value = $arg2;
+}
+
diff --git a/tests/tracetool/ftrace.c b/tests/tracetool/ftrace.c
new file mode 100644
index 0000000..9f862fa
--- /dev/null
+++ b/tests/tracetool/ftrace.c
@@ -0,0 +1,32 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
diff --git a/tests/tracetool/ftrace.h b/tests/tracetool/ftrace.h
new file mode 100644
index 0000000..1dfe423
--- /dev/null
+++ b/tests/tracetool/ftrace.h
@@ -0,0 +1,43 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+#include "trace/ftrace.h"
+
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ if (trace_event_get_state(TRACE_TEST_BLAH)) {
+#line 4 "trace-events"
+ ftrace_write("test_blah " "Blah context=%p filename=%s" "\n" , context, filename);
+#line 28 "ftrace.h"
+ }
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
+#line 5 "trace-events"
+ ftrace_write("test_wibble " "Wibble context=%p value=%d" "\n" , context, value);
+#line 41 "ftrace.h"
+ }
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/ftrace.rs b/tests/tracetool/ftrace.rs
new file mode 100644
index 0000000..07b9259
--- /dev/null
+++ b/tests/tracetool/ftrace.rs
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// This file is @generated by tracetool, do not edit.
+
+#[allow(unused_imports)]
+use std::ffi::c_char;
+#[allow(unused_imports)]
+use util::bindings;
+
+#[inline(always)]
+fn trace_event_state_is_enabled(dstate: u16) -> bool {
+ (unsafe { trace_events_enabled_count }) != 0 && dstate != 0
+}
+
+extern "C" {
+ static mut trace_events_enabled_count: u32;
+}
+extern "C" {
+ static mut _TRACE_TEST_BLAH_DSTATE: u16;
+ static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) {
+ let format_string = c"Blah context=%p filename=%s";
+ unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());}
+ }
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) {
+ let format_string = c"Wibble context=%p value=%d";
+ unsafe {bindings::ftrace_write(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);}
+ }
+}
diff --git a/tests/tracetool/log.c b/tests/tracetool/log.c
new file mode 100644
index 0000000..9f862fa
--- /dev/null
+++ b/tests/tracetool/log.c
@@ -0,0 +1,32 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
diff --git a/tests/tracetool/log.h b/tests/tracetool/log.h
new file mode 100644
index 0000000..c779587
--- /dev/null
+++ b/tests/tracetool/log.h
@@ -0,0 +1,47 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+#include "qemu/log-for-trace.h"
+
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ if (trace_event_get_state(TRACE_TEST_BLAH)) {
+ if (qemu_loglevel_mask(LOG_TRACE)) {
+#line 4 "trace-events"
+ qemu_log("test_blah " "Blah context=%p filename=%s" "\n", context, filename);
+#line 29 "log.h"
+ }
+ }
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
+ if (qemu_loglevel_mask(LOG_TRACE)) {
+#line 5 "trace-events"
+ qemu_log("test_wibble " "Wibble context=%p value=%d" "\n", context, value);
+#line 44 "log.h"
+ }
+ }
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/log.rs b/tests/tracetool/log.rs
new file mode 100644
index 0000000..c191895
--- /dev/null
+++ b/tests/tracetool/log.rs
@@ -0,0 +1,44 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// This file is @generated by tracetool, do not edit.
+
+#[allow(unused_imports)]
+use std::ffi::c_char;
+#[allow(unused_imports)]
+use util::bindings;
+
+#[inline(always)]
+fn trace_event_state_is_enabled(dstate: u16) -> bool {
+ (unsafe { trace_events_enabled_count }) != 0 && dstate != 0
+}
+
+extern "C" {
+ static mut trace_events_enabled_count: u32;
+}
+extern "C" {
+ static mut _TRACE_TEST_BLAH_DSTATE: u16;
+ static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) {
+ let format_string = c"test_blah Blah context=%p filename=%s\n";
+ if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {
+ unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());}
+ }
+ }
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) {
+ let format_string = c"test_wibble Wibble context=%p value=%d\n";
+ if (unsafe { bindings::qemu_loglevel } & bindings::LOG_TRACE) != 0 {
+ unsafe { bindings::qemu_log(format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);}
+ }
+ }
+}
diff --git a/tests/tracetool/meson.build b/tests/tracetool/meson.build
new file mode 100644
index 0000000..09bbaaa
--- /dev/null
+++ b/tests/tracetool/meson.build
@@ -0,0 +1,28 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_env = environment()
+test_env.set('PYTHONPATH', meson.project_source_root() / 'scripts')
+test_env.set('PYTHONIOENCODING', 'utf-8')
+
+backends = [
+ 'dtrace',
+ 'ftrace',
+ 'log',
+ 'simple',
+ 'syslog',
+ 'ust'
+]
+
+# The tracetool-test.py program has portability problems on Windows.
+if host_machine.system() != 'windows'
+ foreach backend: backends
+ test(backend,
+ python,
+ args: [meson.current_source_dir() / 'tracetool-test.py',
+ meson.project_source_root() / 'scripts' / 'tracetool.py',
+ backend,
+ meson.current_source_dir(),
+ meson.current_build_dir()],
+ suite: ['tracetool'])
+ endforeach
+endif
diff --git a/tests/tracetool/simple.c b/tests/tracetool/simple.c
new file mode 100644
index 0000000..0484177
--- /dev/null
+++ b/tests/tracetool/simple.c
@@ -0,0 +1,61 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
+#include "qemu/osdep.h"
+#include "trace/control.h"
+#include "trace/simple.h"
+
+void _simple_trace_test_blah(void *context, const char *filename)
+{
+ TraceBufferRecord rec;
+ size_t argfilename_len = filename ? MIN(strlen(filename), MAX_TRACE_STRLEN) : 0;
+
+ if (trace_record_start(&rec, _TRACE_TEST_BLAH_EVENT.id, 8 + 4 + argfilename_len)) {
+ return; /* Trace Buffer Full, Event Dropped ! */
+ }
+ trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)context);
+ trace_record_write_str(&rec, filename, argfilename_len);
+ trace_record_finish(&rec);
+}
+
+void _simple_trace_test_wibble(void *context, int value)
+{
+ TraceBufferRecord rec;
+
+ if (trace_record_start(&rec, _TRACE_TEST_WIBBLE_EVENT.id, 8 + 8)) {
+ return; /* Trace Buffer Full, Event Dropped ! */
+ }
+ trace_record_write_u64(&rec, (uintptr_t)(uint64_t *)context);
+ trace_record_write_u64(&rec, (uint64_t)value);
+ trace_record_finish(&rec);
+}
+
diff --git a/tests/tracetool/simple.h b/tests/tracetool/simple.h
new file mode 100644
index 0000000..ec6fcb2
--- /dev/null
+++ b/tests/tracetool/simple.h
@@ -0,0 +1,40 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+void _simple_trace_test_blah(void *context, const char *filename);
+void _simple_trace_test_wibble(void *context, int value);
+
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ if (trace_event_get_state(TRACE_TEST_BLAH)) {
+ _simple_trace_test_blah(context, filename);
+ }
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
+ _simple_trace_test_wibble(context, value);
+ }
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/simple.rs b/tests/tracetool/simple.rs
new file mode 100644
index 0000000..9ee3949
--- /dev/null
+++ b/tests/tracetool/simple.rs
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// This file is @generated by tracetool, do not edit.
+
+#[allow(unused_imports)]
+use std::ffi::c_char;
+#[allow(unused_imports)]
+use util::bindings;
+
+#[inline(always)]
+fn trace_event_state_is_enabled(dstate: u16) -> bool {
+ (unsafe { trace_events_enabled_count }) != 0 && dstate != 0
+}
+
+extern "C" {
+ static mut trace_events_enabled_count: u32;
+}
+extern "C" {
+ static mut _TRACE_TEST_BLAH_DSTATE: u16;
+ static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) {
+ extern "C" { fn _simple_trace_test_blah(_context: *mut (), _filename: *const std::ffi::c_char); }
+ unsafe { _simple_trace_test_blah(_context, _filename.as_ptr()); }
+ }
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) {
+ extern "C" { fn _simple_trace_test_wibble(_context: *mut (), _value: std::ffi::c_int); }
+ unsafe { _simple_trace_test_wibble(_context, _value); }
+ }
+}
diff --git a/tests/tracetool/syslog.c b/tests/tracetool/syslog.c
new file mode 100644
index 0000000..9f862fa
--- /dev/null
+++ b/tests/tracetool/syslog.c
@@ -0,0 +1,32 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
diff --git a/tests/tracetool/syslog.h b/tests/tracetool/syslog.h
new file mode 100644
index 0000000..ed43055
--- /dev/null
+++ b/tests/tracetool/syslog.h
@@ -0,0 +1,43 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+#include <syslog.h>
+
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_BLAH) || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ if (trace_event_get_state(TRACE_TEST_BLAH)) {
+#line 4 "trace-events"
+ syslog(LOG_INFO, "test_blah " "Blah context=%p filename=%s" , context, filename);
+#line 28 "syslog.h"
+ }
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ trace_event_get_state_dynamic_by_id(TRACE_TEST_WIBBLE) || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ if (trace_event_get_state(TRACE_TEST_WIBBLE)) {
+#line 5 "trace-events"
+ syslog(LOG_INFO, "test_wibble " "Wibble context=%p value=%d" , context, value);
+#line 41 "syslog.h"
+ }
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/syslog.rs b/tests/tracetool/syslog.rs
new file mode 100644
index 0000000..9d3675a
--- /dev/null
+++ b/tests/tracetool/syslog.rs
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+// This file is @generated by tracetool, do not edit.
+
+#[allow(unused_imports)]
+use std::ffi::c_char;
+#[allow(unused_imports)]
+use util::bindings;
+
+#[inline(always)]
+fn trace_event_state_is_enabled(dstate: u16) -> bool {
+ (unsafe { trace_events_enabled_count }) != 0 && dstate != 0
+}
+
+extern "C" {
+ static mut trace_events_enabled_count: u32;
+}
+extern "C" {
+ static mut _TRACE_TEST_BLAH_DSTATE: u16;
+ static mut _TRACE_TEST_WIBBLE_DSTATE: u16;
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_blah(_context: *mut (), _filename: &std::ffi::CStr)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_BLAH_DSTATE}) {
+ let format_string = c"Blah context=%p filename=%s";
+ unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _filename.as_ptr());}
+ }
+}
+
+#[inline(always)]
+#[allow(dead_code)]
+pub fn trace_test_wibble(_context: *mut (), _value: std::ffi::c_int)
+{
+ if trace_event_state_is_enabled(unsafe { _TRACE_TEST_WIBBLE_DSTATE}) {
+ let format_string = c"Wibble context=%p value=%d";
+ unsafe {::trace::syslog(::trace::LOG_INFO, format_string.as_ptr() as *const c_char, _context /* as *mut () */, _value /* as std::ffi::c_int */);}
+ }
+}
diff --git a/tests/tracetool/trace-events b/tests/tracetool/trace-events
new file mode 100644
index 0000000..72cf4d6
--- /dev/null
+++ b/tests/tracetool/trace-events
@@ -0,0 +1,5 @@
+# See docs/devel/tracing.rst for syntax documentation.
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_blah(void *context, const char *filename) "Blah context=%p filename=%s"
+test_wibble(void *context, int value) "Wibble context=%p value=%d"
diff --git a/tests/tracetool/tracetool-test.py b/tests/tracetool/tracetool-test.py
new file mode 100755
index 0000000..786083a
--- /dev/null
+++ b/tests/tracetool/tracetool-test.py
@@ -0,0 +1,109 @@
+#!/usr/bin/python3
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+from pathlib import Path
+from shutil import copyfile
+from subprocess import check_call
+import sys
+import tempfile
+
+
+def get_formats(backend):
+ formats = [
+ "c",
+ "h",
+ ]
+ if backend in {"ftrace", "log", "simple", "syslog"}:
+ formats += ["rs"]
+ if backend == "dtrace":
+ formats += [
+ "d",
+ "log-stap",
+ "simpletrace-stap",
+ "stap",
+ ]
+ if backend == "ust":
+ formats += [
+ "ust-events-c",
+ "ust-events-h",
+ ]
+ return formats
+
+
+def test_tracetool_one(tracetool, backend, fmt, src_dir, build_dir):
+ rel_filename = backend + "." + fmt
+ actual_file = Path(build_dir, rel_filename)
+ expect_file = Path(src_dir, rel_filename)
+
+ args = [tracetool, f"--format={fmt}", f"--backends={backend}", "--group=testsuite"]
+
+ if fmt.find("stap") != -1:
+ args += ["--binary=qemu", "--probe-prefix=qemu"]
+
+ # Use relative files for both, as these filenames end
+ # up in '#line' statements in the output
+ args += ["trace-events", rel_filename]
+
+ try:
+ check_call(args, cwd=build_dir)
+ actual = actual_file.read_text()
+ finally:
+ actual_file.unlink()
+
+ if os.getenv("QEMU_TEST_REGENERATE", False):
+ print(f"# regenerate {expect_file}")
+ expect_file.write_text(actual)
+
+ expect = expect_file.read_text()
+
+ assert expect == actual
+
+
+def test_tracetool(tracetool, backend, source_dir, build_dir):
+ fail = False
+ scenarios = len(get_formats(backend))
+
+ print(f"1..{scenarios}")
+
+ src_events = Path(source_dir, "trace-events")
+ build_events = Path(build_dir, "trace-events")
+
+ try:
+ # We need a stable relative filename under build dir
+ # for the '#line' statements, so copy over the input
+ copyfile(src_events, build_events)
+
+ num = 1
+ for fmt in get_formats(backend):
+ status = "not ok"
+ hint = ""
+ try:
+ test_tracetool_one(tracetool, backend, fmt, source_dir, build_dir)
+ status = "ok"
+ except Exception as e:
+ print(f"# {e}")
+ fail = True
+ hint = (
+ " (set QEMU_TEST_REGENERATE=1 to recreate reference "
+ + "output if tracetool generator was intentionally changed)"
+ )
+ finally:
+ print(f"{status} {num} - {backend}.{fmt}{hint}")
+ finally:
+ build_events.unlink()
+
+ return fail
+
+
+if __name__ == "__main__":
+ if len(sys.argv) != 5:
+ argv0 = sys.argv[0]
+ print("syntax: {argv0} TRACE-TOOL BACKEND SRC-DIR BUILD-DIR", file=sys.stderr)
+ sys.exit(1)
+
+ with tempfile.TemporaryDirectory(prefix=sys.argv[4]) as tmpdir:
+ fail = test_tracetool(sys.argv[1], sys.argv[2], sys.argv[3], tmpdir)
+ if fail:
+ sys.exit(1)
+ sys.exit(0)
diff --git a/tests/tracetool/ust.c b/tests/tracetool/ust.c
new file mode 100644
index 0000000..9f862fa
--- /dev/null
+++ b/tests/tracetool/ust.c
@@ -0,0 +1,32 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu/module.h"
+#include "trace-testsuite.h"
+
+uint16_t _TRACE_TEST_BLAH_DSTATE;
+uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+TraceEvent _TRACE_TEST_BLAH_EVENT = {
+ .id = 0,
+ .name = "test_blah",
+ .sstate = TRACE_TEST_BLAH_ENABLED,
+ .dstate = &_TRACE_TEST_BLAH_DSTATE
+};
+TraceEvent _TRACE_TEST_WIBBLE_EVENT = {
+ .id = 0,
+ .name = "test_wibble",
+ .sstate = TRACE_TEST_WIBBLE_ENABLED,
+ .dstate = &_TRACE_TEST_WIBBLE_DSTATE
+};
+TraceEvent *testsuite_trace_events[] = {
+ &_TRACE_TEST_BLAH_EVENT,
+ &_TRACE_TEST_WIBBLE_EVENT,
+ NULL,
+};
+
+static void trace_testsuite_register_events(void)
+{
+ trace_event_register_group(testsuite_trace_events);
+}
+trace_init(trace_testsuite_register_events)
diff --git a/tests/tracetool/ust.h b/tests/tracetool/ust.h
new file mode 100644
index 0000000..b7acd0c
--- /dev/null
+++ b/tests/tracetool/ust.h
@@ -0,0 +1,41 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#ifndef TRACE_TESTSUITE_GENERATED_TRACERS_H
+#define TRACE_TESTSUITE_GENERATED_TRACERS_H
+
+#include "trace/control.h"
+
+extern TraceEvent _TRACE_TEST_BLAH_EVENT;
+extern TraceEvent _TRACE_TEST_WIBBLE_EVENT;
+extern uint16_t _TRACE_TEST_BLAH_DSTATE;
+extern uint16_t _TRACE_TEST_WIBBLE_DSTATE;
+#define TRACE_TEST_BLAH_ENABLED 1
+#define TRACE_TEST_WIBBLE_ENABLED 1
+#include <lttng/tracepoint.h>
+#include "trace-ust-testsuite.h"
+
+/* tracepoint_enabled() was introduced in LTTng UST 2.7 */
+#ifndef tracepoint_enabled
+#define tracepoint_enabled(a, b) true
+#endif
+
+
+#define TRACE_TEST_BLAH_BACKEND_DSTATE() ( \
+ tracepoint_enabled(qemu, test_blah) || \
+ false)
+
+static inline void trace_test_blah(void *context, const char *filename)
+{
+ tracepoint(qemu, test_blah, context, filename);
+}
+
+#define TRACE_TEST_WIBBLE_BACKEND_DSTATE() ( \
+ tracepoint_enabled(qemu, test_wibble) || \
+ false)
+
+static inline void trace_test_wibble(void *context, int value)
+{
+ tracepoint(qemu, test_wibble, context, value);
+}
+#endif /* TRACE_TESTSUITE_GENERATED_TRACERS_H */
diff --git a/tests/tracetool/ust.ust-events-c b/tests/tracetool/ust.ust-events-c
new file mode 100644
index 0000000..db232240
--- /dev/null
+++ b/tests/tracetool/ust.ust-events-c
@@ -0,0 +1,14 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+
+#define TRACEPOINT_DEFINE
+#define TRACEPOINT_CREATE_PROBES
+
+/* If gcc version 4.7 or older is used, LTTng ust gives a warning when compiling with
+ -Wredundant-decls.
+ */
+#pragma GCC diagnostic ignored "-Wredundant-decls"
+
+#include "trace-ust-all.h"
diff --git a/tests/tracetool/ust.ust-events-h b/tests/tracetool/ust.ust-events-h
new file mode 100644
index 0000000..4621a99
--- /dev/null
+++ b/tests/tracetool/ust.ust-events-h
@@ -0,0 +1,56 @@
+/* This file is autogenerated by tracetool, do not edit. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER qemu
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./trace-ust.h"
+
+#if !defined (TRACE_TESTSUITE_GENERATED_UST_H) || \
+ defined(TRACEPOINT_HEADER_MULTI_READ)
+#define TRACE_TESTSUITE_GENERATED_UST_H
+
+#include <lttng/tracepoint.h>
+
+/*
+ * LTTng ust 2.0 does not allow you to use TP_ARGS(void) for tracepoints
+ * requiring no arguments. We define these macros introduced in more recent * versions of LTTng ust as a workaround
+ */
+#ifndef _TP_EXPROTO1
+#define _TP_EXPROTO1(a) void
+#endif
+#ifndef _TP_EXDATA_PROTO1
+#define _TP_EXDATA_PROTO1(a) void *__tp_data
+#endif
+#ifndef _TP_EXDATA_VAR1
+#define _TP_EXDATA_VAR1(a) __tp_data
+#endif
+#ifndef _TP_EXVAR1
+#define _TP_EXVAR1(a)
+#endif
+
+TRACEPOINT_EVENT(
+ qemu,
+ test_blah,
+ TP_ARGS(void *, context, const char *, filename),
+ TP_FIELDS(
+ ctf_integer_hex(void *, context, context)
+ ctf_string(filename, filename)
+ )
+)
+
+TRACEPOINT_EVENT(
+ qemu,
+ test_wibble,
+ TP_ARGS(void *, context, int, value),
+ TP_FIELDS(
+ ctf_integer_hex(void *, context, context)
+ ctf_integer(int, value, value)
+ )
+)
+
+#endif /* TRACE_TESTSUITE_GENERATED_UST_H */
+
+/* This part must be outside ifdef protection */
+#include <lttng/tracepoint-event.h>
diff --git a/tests/tsan/ignore.tsan b/tests/tsan/ignore.tsan
index 423e482..8fa00a2 100644
--- a/tests/tsan/ignore.tsan
+++ b/tests/tsan/ignore.tsan
@@ -4,7 +4,7 @@
# The eventual goal would be to fix these warnings.
# TSan is not happy about setting/getting of dirty bits,
-# for example, cpu_physical_memory_set_dirty_range,
-# and cpu_physical_memory_get_dirty.
+# for example, physical_memory_set_dirty_range,
+# and physical_memory_get_dirty.
src:bitops.c
src:bitmap.c
diff --git a/tests/uefi-test-tools/Makefile b/tests/uefi-test-tools/Makefile
index f4eaebd..8ee6fb3 100644
--- a/tests/uefi-test-tools/Makefile
+++ b/tests/uefi-test-tools/Makefile
@@ -12,7 +12,7 @@
edk2_dir := ../../roms/edk2
images_dir := ../data/uefi-boot-images
-emulation_targets := arm aarch64 i386 x86_64 riscv64
+emulation_targets := arm aarch64 i386 x86_64 riscv64 loongarch64
uefi_binaries := bios-tables-test
intermediate_suffixes := .efi .fat .iso.raw
@@ -56,7 +56,8 @@ Build/%.iso.raw: Build/%.fat
# stripped from, the argument.
map_arm_to_uefi = $(subst arm,ARM,$(1))
map_aarch64_to_uefi = $(subst aarch64,AA64,$(call map_arm_to_uefi,$(1)))
-map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_aarch64_to_uefi,$(1)))
+map_loongarch64_to_uefi = $(subst loongarch64,LOONGARCH64,$(call map_aarch64_to_uefi,$(1)))
+map_riscv64_to_uefi = $(subst riscv64,RISCV64,$(call map_loongarch64_to_uefi,$(1)))
map_i386_to_uefi = $(subst i386,IA32,$(call map_riscv64_to_uefi,$(1)))
map_x86_64_to_uefi = $(subst x86_64,X64,$(call map_i386_to_uefi,$(1)))
map_to_uefi = $(subst .,,$(call map_x86_64_to_uefi,$(1)))
diff --git a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
index 0902fd3..facf8df 100644
--- a/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
+++ b/tests/uefi-test-tools/UefiTestToolsPkg/UefiTestToolsPkg.dsc
@@ -19,7 +19,7 @@
PLATFORM_VERSION = 0.1
PLATFORM_NAME = UefiTestTools
SKUID_IDENTIFIER = DEFAULT
- SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64
+ SUPPORTED_ARCHITECTURES = ARM|AARCH64|IA32|X64|RISCV64|LOONGARCH64
BUILD_TARGETS = DEBUG
[BuildOptions.IA32]
@@ -65,6 +65,10 @@
[LibraryClasses.RISCV64]
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+[LibraryClasses.LOONGARCH64]
+ BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+ StackCheckLib|MdePkg/Library/StackCheckLibNull/StackCheckLibNull.inf
+
[PcdsFixedAtBuild]
gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x8040004F
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2F
diff --git a/tests/uefi-test-tools/uefi-test-build.config b/tests/uefi-test-tools/uefi-test-build.config
index a4c61fc..8bf4826 100644
--- a/tests/uefi-test-tools/uefi-test-build.config
+++ b/tests/uefi-test-tools/uefi-test-build.config
@@ -22,6 +22,16 @@ arch = AARCH64
cpy1 = AARCH64/BiosTablesTest.efi bios-tables-test.aarch64.efi
####################################################################################
+# loongarch64
+
+[build.loongarch64]
+conf = UefiTestToolsPkg/UefiTestToolsPkg.dsc
+plat = UefiTestTools
+dest = ./Build
+arch = LOONGARCH64
+cpy1 = LOONGARCH64/BiosTablesTest.efi bios-tables-test.loongarch64.efi
+
+####################################################################################
# riscv64
[build.riscv64]
diff --git a/tests/unit/io-channel-helpers.c b/tests/unit/io-channel-helpers.c
index c0799c2..22b42d1 100644
--- a/tests/unit/io-channel-helpers.c
+++ b/tests/unit/io-channel-helpers.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "io-channel-helpers.h"
+#include "qapi/error.h"
#include "qemu/iov.h"
struct QIOChannelTest {
@@ -109,8 +110,8 @@ void qio_channel_test_run_threads(QIOChannelTest *test,
test->src = src;
test->dst = dst;
- qio_channel_set_blocking(test->dst, blocking, NULL);
- qio_channel_set_blocking(test->src, blocking, NULL);
+ qio_channel_set_blocking(test->dst, blocking, &error_abort);
+ qio_channel_set_blocking(test->src, blocking, &error_abort);
reader = g_thread_new("reader",
test_io_thread_reader,
diff --git a/tests/unit/socket-helpers.c b/tests/unit/socket-helpers.c
index 37db24f..46d2ff1 100644
--- a/tests/unit/socket-helpers.c
+++ b/tests/unit/socket-helpers.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qemu/sockets.h"
#include "socket-helpers.h"
@@ -88,7 +89,8 @@ static int socket_can_bind_connect(const char *hostname, int family)
goto cleanup;
}
- qemu_socket_set_nonblock(cfd);
+ qemu_set_blocking(cfd, false, &error_abort);
+
if (connect(cfd, (struct sockaddr *)&ss, sslen) < 0) {
if (errno == EINPROGRESS) {
check_soerr = true;
diff --git a/tests/unit/test-aio-multithread.c b/tests/unit/test-aio-multithread.c
index 08d4570..0ead6bf 100644
--- a/tests/unit/test-aio-multithread.c
+++ b/tests/unit/test-aio-multithread.c
@@ -305,7 +305,9 @@ static void mcs_mutex_lock(void)
prev = qatomic_xchg(&mutex_head, id);
if (prev != -1) {
qatomic_set(&nodes[prev].next, id);
- qemu_futex_wait(&nodes[id].locked, 1);
+ while (qatomic_read(&nodes[id].locked) == 1) {
+ qemu_futex_wait(&nodes[id].locked, 1);
+ }
}
}
@@ -328,7 +330,7 @@ static void mcs_mutex_unlock(void)
/* Wake up the next in line. */
next = qatomic_read(&nodes[id].next);
nodes[next].locked = 0;
- qemu_futex_wake(&nodes[next].locked, 1);
+ qemu_futex_wake_single(&nodes[next].locked);
}
static void test_multi_fair_mutex_entry(void *opaque)
diff --git a/tests/unit/test-bdrv-drain.c b/tests/unit/test-bdrv-drain.c
index 290cd2a..43b0ba8 100644
--- a/tests/unit/test-bdrv-drain.c
+++ b/tests/unit/test-bdrv-drain.c
@@ -193,7 +193,9 @@ static BlockBackend * no_coroutine_fn test_setup(void)
blk_insert_bs(blk, bs, &error_abort);
backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(bs, backing, &error_abort);
+ bdrv_graph_wrunlock();
bdrv_unref(backing);
bdrv_unref(bs);
@@ -386,7 +388,9 @@ static void test_nested(void)
backing = bdrv_new_open_driver(&bdrv_test, "backing", 0, &error_abort);
backing_s = backing->opaque;
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(bs, backing, &error_abort);
+ bdrv_graph_wrunlock();
for (outer = 0; outer < DRAIN_TYPE_MAX; outer++) {
for (inner = 0; inner < DRAIN_TYPE_MAX; inner++) {
@@ -733,10 +737,12 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
src_overlay = bdrv_new_open_driver(&bdrv_test, "source-overlay",
BDRV_O_RDWR, &error_abort);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(src_overlay, src, &error_abort);
bdrv_unref(src);
bdrv_set_backing_hd(src, src_backing, &error_abort);
bdrv_unref(src_backing);
+ bdrv_graph_wrunlock();
blk_src = blk_new(qemu_get_aio_context(), BLK_PERM_ALL, BLK_PERM_ALL);
blk_insert_bs(blk_src, src_overlay, &error_abort);
@@ -772,7 +778,7 @@ static void test_blockjob_common_drain_node(enum drain_type drain_type,
tjob->bs = src;
job = &tjob->common;
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
block_job_add_bdrv(job, "target", target, 0, BLK_PERM_ALL, &error_abort);
bdrv_graph_wrunlock();
@@ -953,7 +959,7 @@ static void bdrv_test_top_close(BlockDriverState *bs)
{
BdrvChild *c, *next_c;
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
bdrv_unref_child(bs, c);
}
@@ -1014,7 +1020,9 @@ static void coroutine_fn test_co_delete_by_drain(void *opaque)
bdrv_graph_co_rdlock();
QLIST_FOREACH_SAFE(c, &bs->children, next, next_c) {
bdrv_graph_co_rdunlock();
+ bdrv_drain_all_begin();
bdrv_co_unref_child(bs, c);
+ bdrv_drain_all_end();
bdrv_graph_co_rdlock();
}
bdrv_graph_co_rdunlock();
@@ -1047,7 +1055,7 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
&error_abort);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
@@ -1058,7 +1066,7 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
&error_abort);
child_bs->total_sectors = 65536 >> BDRV_SECTOR_BITS;
/* Takes our reference to child_bs */
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
tts->wait_child = bdrv_attach_child(bs, child_bs, "wait-child",
&child_of_bds,
BDRV_CHILD_DATA | BDRV_CHILD_PRIMARY,
@@ -1069,7 +1077,7 @@ static void do_test_delete_by_drain(bool detach_instead_of_delete,
* (for detach_instead_of_delete == true) */
null_bs = bdrv_open("null-co://", NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
&error_abort);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(bs, null_bs, "null-child", &child_of_bds, BDRV_CHILD_DATA,
&error_abort);
bdrv_graph_wrunlock();
@@ -1155,7 +1163,7 @@ static void no_coroutine_fn detach_indirect_bh(void *opaque)
bdrv_dec_in_flight(data->child_b->bs);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_unref_child(data->parent_b, data->child_b);
bdrv_ref(data->c);
@@ -1260,7 +1268,7 @@ static void TSA_NO_TSA test_detach_indirect(bool by_parent_cb)
/* Set child relationships */
bdrv_ref(b);
bdrv_ref(a);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
child_b = bdrv_attach_child(parent_b, b, "PB-B", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
child_a = bdrv_attach_child(parent_b, a, "PB-A", &child_of_bds,
@@ -1396,14 +1404,10 @@ static void test_set_aio_context(void)
bs = bdrv_new_open_driver(&bdrv_test, "test-node", BDRV_O_RDWR,
&error_abort);
- bdrv_drained_begin(bs);
bdrv_try_change_aio_context(bs, ctx_a, NULL, &error_abort);
- bdrv_drained_end(bs);
- bdrv_drained_begin(bs);
bdrv_try_change_aio_context(bs, ctx_b, NULL, &error_abort);
bdrv_try_change_aio_context(bs, qemu_get_aio_context(), NULL, &error_abort);
- bdrv_drained_end(bs);
bdrv_unref(bs);
iothread_join(a);
@@ -1438,8 +1442,10 @@ static void test_drop_backing_job_commit(Job *job)
TestDropBackingBlockJob *s =
container_of(job, TestDropBackingBlockJob, common.job);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(s->bs, NULL, &error_abort);
bdrv_set_backing_hd(s->detach_also, NULL, &error_abort);
+ bdrv_graph_wrunlock();
*s->did_complete = true;
}
@@ -1532,7 +1538,9 @@ static void test_blockjob_commit_by_drained_end(void)
snprintf(name, sizeof(name), "parent-node-%i", i);
bs_parents[i] = bdrv_new_open_driver(&bdrv_test, name, BDRV_O_RDWR,
&error_abort);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(bs_parents[i], bs_child, &error_abort);
+ bdrv_graph_wrunlock();
}
job = block_job_create("job", &test_drop_backing_job_driver, NULL,
@@ -1681,13 +1689,13 @@ static void test_drop_intermediate_poll(void)
job_node = bdrv_new_open_driver(&bdrv_test, "job-node", BDRV_O_RDWR,
&error_abort);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(job_node, chain[1], &error_abort);
/*
* Establish the chain last, so the chain links are the first
* elements in the BDS.parents lists
*/
- bdrv_graph_wrlock();
for (i = 0; i < 3; i++) {
if (i) {
/* Takes the reference to chain[i - 1] */
@@ -1942,7 +1950,7 @@ static void do_test_replace_child_mid_drain(int old_drain_count,
new_child_bs->total_sectors = 1;
bdrv_ref(old_child_bs);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(parent_bs, old_child_bs, "child", &child_of_bds,
BDRV_CHILD_COW, &error_abort);
bdrv_graph_wrunlock();
diff --git a/tests/unit/test-bdrv-graph-mod.c b/tests/unit/test-bdrv-graph-mod.c
index d743abb..567db99 100644
--- a/tests/unit/test-bdrv-graph-mod.c
+++ b/tests/unit/test-bdrv-graph-mod.c
@@ -137,7 +137,7 @@ static void test_update_perm_tree(void)
blk_insert_bs(root, bs, &error_abort);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(filter, bs, "child", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
bdrv_graph_wrunlock();
@@ -202,9 +202,9 @@ static void test_should_update_child(void)
blk_insert_bs(root, bs, &error_abort);
+ bdrv_graph_wrlock_drained();
bdrv_set_backing_hd(target, bs, &error_abort);
- bdrv_graph_wrlock();
g_assert(target->backing->bs == bs);
bdrv_attach_child(filter, target, "target", &child_of_bds,
BDRV_CHILD_DATA, &error_abort);
@@ -244,7 +244,7 @@ static void test_parallel_exclusive_write(void)
bdrv_ref(base);
bdrv_ref(fl1);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(top, fl1, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
@@ -363,7 +363,7 @@ static void test_parallel_perm_update(void)
*/
bdrv_ref(base);
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(top, ws, "file", &child_of_bds, BDRV_CHILD_DATA,
&error_abort);
c_fl1 = bdrv_attach_child(ws, fl1, "first", &child_of_bds,
@@ -430,7 +430,7 @@ static void test_append_greedy_filter(void)
BlockDriverState *base = no_perm_node("base");
BlockDriverState *fl = exclusive_writer_node("fl1");
- bdrv_graph_wrlock();
+ bdrv_graph_wrlock_drained();
bdrv_attach_child(top, base, "backing", &child_of_bds,
BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
&error_abort);
diff --git a/tests/unit/test-char.c b/tests/unit/test-char.c
index 60a843b..f30a39f 100644
--- a/tests/unit/test-char.c
+++ b/tests/unit/test-char.c
@@ -993,7 +993,7 @@ static void char_udp_test_internal(Chardev *reuse_chr, int sock)
struct sockaddr_in other;
SocketIdleData d = { 0, };
Chardev *chr;
- CharBackend *be;
+ CharBackend stack_be, *be = &stack_be;
socklen_t alen = sizeof(other);
int ret;
char buf[10];
@@ -1009,7 +1009,6 @@ static void char_udp_test_internal(Chardev *reuse_chr, int sock)
chr = qemu_chr_new("client", tmp, NULL);
g_assert_nonnull(chr);
- be = g_alloca(sizeof(CharBackend));
qemu_chr_fe_init(be, chr, &error_abort);
}
diff --git a/tests/unit/test-crypto-block.c b/tests/unit/test-crypto-block.c
index 9217b9a..3ac7f17 100644
--- a/tests/unit/test-crypto-block.c
+++ b/tests/unit/test-crypto-block.c
@@ -574,6 +574,13 @@ int main(int argc, char **argv)
for (i = 0; i < G_N_ELEMENTS(test_data); i++) {
if (test_data[i].open_opts->format == QCRYPTO_BLOCK_FORMAT_LUKS &&
!qcrypto_hash_supports(test_data[i].hash_alg)) {
+ g_printerr("# skip unsupported %s\n",
+ QCryptoHashAlgo_str(test_data[i].hash_alg));
+ continue;
+ }
+ if (!qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128,
+ QCRYPTO_CIPHER_MODE_CBC)) {
+ g_printerr("# skip unsupported aes-128:cbc\n");
continue;
}
if (!test_data[i].slow ||
diff --git a/tests/unit/test-crypto-cipher.c b/tests/unit/test-crypto-cipher.c
index b328b48..1331d55 100644
--- a/tests/unit/test-crypto-cipher.c
+++ b/tests/unit/test-crypto-cipher.c
@@ -828,11 +828,16 @@ int main(int argc, char **argv)
}
}
- g_test_add_func("/crypto/cipher/null-iv",
- test_cipher_null_iv);
+ if (qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_256,
+ QCRYPTO_CIPHER_MODE_CBC)) {
+ g_test_add_func("/crypto/cipher/null-iv",
+ test_cipher_null_iv);
- g_test_add_func("/crypto/cipher/short-plaintext",
- test_cipher_short_plaintext);
+ g_test_add_func("/crypto/cipher/short-plaintext",
+ test_cipher_short_plaintext);
+ } else {
+ g_printerr("# skip unsupported aes-256:cbc\n");
+ }
return g_test_run();
}
diff --git a/tests/unit/test-crypto-secret.c b/tests/unit/test-crypto-secret.c
index ffd13ff..fc32a01 100644
--- a/tests/unit/test-crypto-secret.c
+++ b/tests/unit/test-crypto-secret.c
@@ -22,6 +22,7 @@
#include "crypto/init.h"
#include "crypto/secret.h"
+#include "crypto/cipher.h"
#include "qapi/error.h"
#include "qemu/module.h"
#if defined(CONFIG_KEYUTILS) && defined(CONFIG_SECRET_KEYRING)
@@ -597,18 +598,21 @@ int main(int argc, char **argv)
g_test_add_func("/crypto/secret/conv/utf8/base64",
test_secret_conv_utf8_base64);
- g_test_add_func("/crypto/secret/crypt/raw",
- test_secret_crypt_raw);
- g_test_add_func("/crypto/secret/crypt/base64",
- test_secret_crypt_base64);
- g_test_add_func("/crypto/secret/crypt/shortkey",
- test_secret_crypt_short_key);
- g_test_add_func("/crypto/secret/crypt/shortiv",
- test_secret_crypt_short_iv);
- g_test_add_func("/crypto/secret/crypt/missingiv",
- test_secret_crypt_missing_iv);
- g_test_add_func("/crypto/secret/crypt/badiv",
- test_secret_crypt_bad_iv);
+ if (qcrypto_cipher_supports(QCRYPTO_CIPHER_ALGO_AES_128,
+ QCRYPTO_CIPHER_MODE_CBC)) {
+ g_test_add_func("/crypto/secret/crypt/raw",
+ test_secret_crypt_raw);
+ g_test_add_func("/crypto/secret/crypt/base64",
+ test_secret_crypt_base64);
+ g_test_add_func("/crypto/secret/crypt/shortkey",
+ test_secret_crypt_short_key);
+ g_test_add_func("/crypto/secret/crypt/shortiv",
+ test_secret_crypt_short_iv);
+ g_test_add_func("/crypto/secret/crypt/missingiv",
+ test_secret_crypt_missing_iv);
+ g_test_add_func("/crypto/secret/crypt/badiv",
+ test_secret_crypt_bad_iv);
+ }
return g_test_run();
}
diff --git a/tests/unit/test-crypto-tlssession.c b/tests/unit/test-crypto-tlssession.c
index 554054e..61311cb 100644
--- a/tests/unit/test-crypto-tlssession.c
+++ b/tests/unit/test-crypto-tlssession.c
@@ -112,8 +112,8 @@ static void test_crypto_tls_session_psk(void)
* thread, so we need these non-blocking to avoid deadlock
* of ourselves
*/
- qemu_socket_set_nonblock(channel[0]);
- qemu_socket_set_nonblock(channel[1]);
+ qemu_set_blocking(channel[0], false, &error_abort);
+ qemu_set_blocking(channel[1], false, &error_abort);
clientCreds = test_tls_creds_psk_create(
QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT,
@@ -264,8 +264,8 @@ static void test_crypto_tls_session_x509(const void *opaque)
* thread, so we need these non-blocking to avoid deadlock
* of ourselves
*/
- qemu_socket_set_nonblock(channel[0]);
- qemu_socket_set_nonblock(channel[1]);
+ qemu_set_blocking(channel[0], false, &error_abort);
+ qemu_set_blocking(channel[1], false, &error_abort);
#define CLIENT_CERT_DIR "tests/test-crypto-tlssession-client/"
#define SERVER_CERT_DIR "tests/test-crypto-tlssession-server/"
diff --git a/tests/unit/test-error-report.c b/tests/unit/test-error-report.c
index 54319c8..0cbde3c 100644
--- a/tests/unit/test-error-report.c
+++ b/tests/unit/test-error-report.c
@@ -104,22 +104,6 @@ test_error_report_timestamp(void)
");
}
-static void
-test_error_warn(void)
-{
- if (g_test_subprocess()) {
- error_setg(&error_warn, "Testing &error_warn");
- return;
- }
-
- g_test_trap_subprocess(NULL, 0, 0);
- g_test_trap_assert_passed();
- g_test_trap_assert_stderr("\
-test-error-report: warning: Testing &error_warn*\
-");
-}
-
-
int
main(int argc, char *argv[])
{
@@ -133,7 +117,6 @@ main(int argc, char *argv[])
g_test_add_func("/error-report/glog", test_error_report_glog);
g_test_add_func("/error-report/once", test_error_report_once);
g_test_add_func("/error-report/timestamp", test_error_report_timestamp);
- g_test_add_func("/error-report/warn", test_error_warn);
return g_test_run();
}
diff --git a/tests/unit/test-io-channel-tls.c b/tests/unit/test-io-channel-tls.c
index e036ac5..6f282ad 100644
--- a/tests/unit/test-io-channel-tls.c
+++ b/tests/unit/test-io-channel-tls.c
@@ -184,8 +184,8 @@ static void test_io_channel_tls(const void *opaque)
* thread, so we need these non-blocking to avoid deadlock
* of ourselves
*/
- qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, NULL);
- qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, NULL);
+ qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, &error_abort);
+ qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, &error_abort);
/* Now the real part of the test, setup the sessions */
clientChanTLS = qio_channel_tls_new_client(
diff --git a/tests/unit/test-iov.c b/tests/unit/test-iov.c
index 75bc3be..63e2b15 100644
--- a/tests/unit/test-iov.c
+++ b/tests/unit/test-iov.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include "qapi/error.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
@@ -186,7 +187,7 @@ static void test_io(void)
close(sv[0]);
FD_SET(sv[1], &fds);
- g_unix_set_fd_nonblocking(sv[1], true, NULL);
+ qemu_set_blocking(sv[1], false, &error_abort);
r = g_test_rand_int_range(sz / 2, sz);
setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &r, sizeof(r));
@@ -222,7 +223,7 @@ static void test_io(void)
close(sv[1]);
FD_SET(sv[0], &fds);
- g_unix_set_fd_nonblocking(sv[0], true, NULL);
+ qemu_set_blocking(sv[0], false, &error_abort);
r = g_test_rand_int_range(sz / 2, sz);
setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &r, sizeof(r));
usleep(500000);
diff --git a/tests/unit/test-qga.c b/tests/unit/test-qga.c
index 541b08a..587e30c 100644
--- a/tests/unit/test-qga.c
+++ b/tests/unit/test-qga.c
@@ -332,6 +332,22 @@ static void test_qga_get_fsinfo(gconstpointer fix)
}
}
+static void test_qga_get_load(gconstpointer fix)
+{
+ const TestFixture *fixture = fix;
+ g_autoptr(QDict) ret = NULL;
+ QDict *load;
+
+ ret = qmp_fd(fixture->fd, "{'execute': 'guest-get-load'}");
+ g_assert_nonnull(ret);
+ qmp_assert_no_error(ret);
+
+ load = qdict_get_qdict(ret, "return");
+ g_assert(qdict_haskey(load, "load1m"));
+ g_assert(qdict_haskey(load, "load5m"));
+ g_assert(qdict_haskey(load, "load15m"));
+}
+
static void test_qga_get_memory_block_info(gconstpointer fix)
{
const TestFixture *fixture = fix;
@@ -1105,6 +1121,7 @@ int main(int argc, char **argv)
g_test_add_data_func("/qga/get-vcpus", &fix, test_qga_get_vcpus);
}
g_test_add_data_func("/qga/get-fsinfo", &fix, test_qga_get_fsinfo);
+ g_test_add_data_func("/qga/get-load", &fix, test_qga_get_load);
g_test_add_data_func("/qga/get-memory-block-info", &fix,
test_qga_get_memory_block_info);
g_test_add_data_func("/qga/get-memory-blocks", &fix,
diff --git a/tests/unit/test-util-sockets.c b/tests/unit/test-util-sockets.c
index 4c9dd0b..ee66d72 100644
--- a/tests/unit/test-util-sockets.c
+++ b/tests/unit/test-util-sockets.c
@@ -332,6 +332,220 @@ static void test_socket_unix_abstract(void)
#endif /* CONFIG_LINUX */
+static void inet_parse_test_helper(const char *str,
+ InetSocketAddress *exp_addr, bool success)
+{
+ InetSocketAddress addr;
+ Error *error = NULL;
+
+ int rc = inet_parse(&addr, str, &error);
+
+ if (success) {
+ if (error) {
+ error_report_err(error);
+ }
+ g_assert_cmpint(rc, ==, 0);
+ } else {
+ error_free(error);
+ g_assert_cmpint(rc, <, 0);
+ }
+ if (exp_addr != NULL) {
+ g_assert_cmpstr(addr.host, ==, exp_addr->host);
+ g_assert_cmpstr(addr.port, ==, exp_addr->port);
+ /* Own members: */
+ g_assert_cmpint(addr.has_numeric, ==, exp_addr->has_numeric);
+ g_assert_cmpint(addr.numeric, ==, exp_addr->numeric);
+ g_assert_cmpint(addr.has_to, ==, exp_addr->has_to);
+ g_assert_cmpint(addr.to, ==, exp_addr->to);
+ g_assert_cmpint(addr.has_ipv4, ==, exp_addr->has_ipv4);
+ g_assert_cmpint(addr.ipv4, ==, exp_addr->ipv4);
+ g_assert_cmpint(addr.has_ipv6, ==, exp_addr->has_ipv6);
+ g_assert_cmpint(addr.ipv6, ==, exp_addr->ipv6);
+ g_assert_cmpint(addr.has_keep_alive, ==, exp_addr->has_keep_alive);
+ g_assert_cmpint(addr.keep_alive, ==, exp_addr->keep_alive);
+#ifdef HAVE_TCP_KEEPCNT
+ g_assert_cmpint(addr.has_keep_alive_count, ==,
+ exp_addr->has_keep_alive_count);
+ g_assert_cmpint(addr.keep_alive_count, ==,
+ exp_addr->keep_alive_count);
+#endif
+#ifdef HAVE_TCP_KEEPIDLE
+ g_assert_cmpint(addr.has_keep_alive_idle, ==,
+ exp_addr->has_keep_alive_idle);
+ g_assert_cmpint(addr.keep_alive_idle, ==,
+ exp_addr->keep_alive_idle);
+#endif
+#ifdef HAVE_TCP_KEEPINTVL
+ g_assert_cmpint(addr.has_keep_alive_interval, ==,
+ exp_addr->has_keep_alive_interval);
+ g_assert_cmpint(addr.keep_alive_interval, ==,
+ exp_addr->keep_alive_interval);
+#endif
+#ifdef HAVE_IPPROTO_MPTCP
+ g_assert_cmpint(addr.has_mptcp, ==, exp_addr->has_mptcp);
+ g_assert_cmpint(addr.mptcp, ==, exp_addr->mptcp);
+#endif
+ }
+
+ g_free(addr.host);
+ g_free(addr.port);
+}
+
+static void test_inet_parse_nohost_good(void)
+{
+ char host[] = "";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ };
+ inet_parse_test_helper(":5000", &exp_addr, true);
+}
+
+static void test_inet_parse_empty_bad(void)
+{
+ inet_parse_test_helper("", NULL, false);
+}
+
+static void test_inet_parse_only_colon_bad(void)
+{
+ inet_parse_test_helper(":", NULL, false);
+}
+
+static void test_inet_parse_ipv4_good(void)
+{
+ char host[] = "127.0.0.1";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ };
+ inet_parse_test_helper("127.0.0.1:5000", &exp_addr, true);
+}
+
+static void test_inet_parse_ipv4_noport_bad(void)
+{
+ inet_parse_test_helper("127.0.0.1", NULL, false);
+}
+
+static void test_inet_parse_ipv6_good(void)
+{
+ char host[] = "::1";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ };
+ inet_parse_test_helper("[::1]:5000", &exp_addr, true);
+}
+
+static void test_inet_parse_ipv6_noend_bad(void)
+{
+ inet_parse_test_helper("[::1", NULL, false);
+}
+
+static void test_inet_parse_ipv6_noport_bad(void)
+{
+ inet_parse_test_helper("[::1]:", NULL, false);
+}
+
+static void test_inet_parse_ipv6_empty_bad(void)
+{
+ inet_parse_test_helper("[]:5000", NULL, false);
+}
+
+static void test_inet_parse_hostname_good(void)
+{
+ char host[] = "localhost";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ };
+ inet_parse_test_helper("localhost:5000", &exp_addr, true);
+}
+
+static void test_inet_parse_all_options_good(void)
+{
+ char host[] = "::1";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ .has_numeric = true,
+ .numeric = true,
+ .has_to = true,
+ .to = 5006,
+ .has_ipv4 = true,
+ .ipv4 = false,
+ .has_ipv6 = true,
+ .ipv6 = true,
+ .has_keep_alive = true,
+ .keep_alive = true,
+#ifdef HAVE_TCP_KEEPCNT
+ .has_keep_alive_count = true,
+ .keep_alive_count = 10,
+#endif
+#ifdef HAVE_TCP_KEEPIDLE
+ .has_keep_alive_idle = true,
+ .keep_alive_idle = 60,
+#endif
+#ifdef HAVE_TCP_KEEPINTVL
+ .has_keep_alive_interval = true,
+ .keep_alive_interval = 30,
+#endif
+#ifdef HAVE_IPPROTO_MPTCP
+ .has_mptcp = true,
+ .mptcp = false,
+#endif
+ };
+ inet_parse_test_helper(
+ "[::1]:5000,numeric=on,to=5006,ipv4=off,ipv6=on,keep-alive=on"
+#ifdef HAVE_TCP_KEEPCNT
+ ",keep-alive-count=10"
+#endif
+#ifdef HAVE_TCP_KEEPIDLE
+ ",keep-alive-idle=60"
+#endif
+#ifdef HAVE_TCP_KEEPINTVL
+ ",keep-alive-interval=30"
+#endif
+#ifdef HAVE_IPPROTO_MPTCP
+ ",mptcp=off"
+#endif
+ , &exp_addr, true);
+}
+
+static void test_inet_parse_all_implicit_bool_good(void)
+{
+ char host[] = "::1";
+ char port[] = "5000";
+ InetSocketAddress exp_addr = {
+ .host = host,
+ .port = port,
+ .has_numeric = true,
+ .numeric = true,
+ .has_to = true,
+ .to = 5006,
+ .has_ipv4 = true,
+ .ipv4 = true,
+ .has_ipv6 = true,
+ .ipv6 = true,
+ .has_keep_alive = true,
+ .keep_alive = true,
+#ifdef HAVE_IPPROTO_MPTCP
+ .has_mptcp = true,
+ .mptcp = true,
+#endif
+ };
+ inet_parse_test_helper(
+ "[::1]:5000,numeric,to=5006,ipv4,ipv6,keep-alive"
+#ifdef HAVE_IPPROTO_MPTCP
+ ",mptcp"
+#endif
+ , &exp_addr, true);
+}
+
int main(int argc, char **argv)
{
bool has_ipv4, has_ipv6;
@@ -377,6 +591,31 @@ int main(int argc, char **argv)
test_socket_unix_abstract);
#endif
+ g_test_add_func("/util/socket/inet-parse/nohost-good",
+ test_inet_parse_nohost_good);
+ g_test_add_func("/util/socket/inet-parse/empty-bad",
+ test_inet_parse_empty_bad);
+ g_test_add_func("/util/socket/inet-parse/only-colon-bad",
+ test_inet_parse_only_colon_bad);
+ g_test_add_func("/util/socket/inet-parse/ipv4-good",
+ test_inet_parse_ipv4_good);
+ g_test_add_func("/util/socket/inet-parse/ipv4-noport-bad",
+ test_inet_parse_ipv4_noport_bad);
+ g_test_add_func("/util/socket/inet-parse/ipv6-good",
+ test_inet_parse_ipv6_good);
+ g_test_add_func("/util/socket/inet-parse/ipv6-noend-bad",
+ test_inet_parse_ipv6_noend_bad);
+ g_test_add_func("/util/socket/inet-parse/ipv6-noport-bad",
+ test_inet_parse_ipv6_noport_bad);
+ g_test_add_func("/util/socket/inet-parse/ipv6-empty-bad",
+ test_inet_parse_ipv6_empty_bad);
+ g_test_add_func("/util/socket/inet-parse/hostname-good",
+ test_inet_parse_hostname_good);
+ g_test_add_func("/util/socket/inet-parse/all-options-good",
+ test_inet_parse_all_options_good);
+ g_test_add_func("/util/socket/inet-parse/all-bare-bool-good",
+ test_inet_parse_all_implicit_bool_good);
+
end:
return g_test_run();
}
diff --git a/tests/unit/test-vmstate.c b/tests/unit/test-vmstate.c
index 63f28f2..cadbab3 100644
--- a/tests/unit/test-vmstate.c
+++ b/tests/unit/test-vmstate.c
@@ -30,6 +30,7 @@
#include "../migration/savevm.h"
#include "qemu/module.h"
#include "io/channel-file.h"
+#include "qapi/error.h"
static int temp_fd;
@@ -66,9 +67,13 @@ static QEMUFile *open_test_file(bool write)
static void save_vmstate(const VMStateDescription *desc, void *obj)
{
QEMUFile *f = open_test_file(true);
+ Error *local_err = NULL;
/* Save file with vmstate */
- int ret = vmstate_save_state(f, desc, obj, NULL);
+ int ret = vmstate_save_state(f, desc, obj, NULL, &local_err);
+ if (ret) {
+ error_report_err(local_err);
+ }
g_assert(!ret);
qemu_put_byte(f, QEMU_VM_EOF);
g_assert(!qemu_file_get_error(f));
@@ -108,14 +113,16 @@ static int load_vmstate_one(const VMStateDescription *desc, void *obj,
{
QEMUFile *f;
int ret;
+ Error *local_err = NULL;
f = open_test_file(true);
qemu_put_buffer(f, wire, size);
qemu_fclose(f);
f = open_test_file(false);
- ret = vmstate_load_state(f, desc, obj, version);
+ ret = vmstate_load_state(f, desc, obj, version, &local_err);
if (ret) {
+ error_report_err(local_err);
g_assert(qemu_file_get_error(f));
} else{
g_assert(!qemu_file_get_error(f));
@@ -355,6 +362,8 @@ static const VMStateDescription vmstate_versioned = {
static void test_load_v1(void)
{
+ Error *local_err = NULL;
+ int ret;
uint8_t buf[] = {
0, 0, 0, 10, /* a */
0, 0, 0, 30, /* c */
@@ -365,7 +374,10 @@ static void test_load_v1(void)
QEMUFile *loading = open_test_file(false);
TestStruct obj = { .b = 200, .e = 500, .f = 600 };
- vmstate_load_state(loading, &vmstate_versioned, &obj, 1);
+ ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 1, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
g_assert(!qemu_file_get_error(loading));
g_assert_cmpint(obj.a, ==, 10);
g_assert_cmpint(obj.b, ==, 200);
@@ -378,6 +390,8 @@ static void test_load_v1(void)
static void test_load_v2(void)
{
+ Error *local_err = NULL;
+ int ret;
uint8_t buf[] = {
0, 0, 0, 10, /* a */
0, 0, 0, 20, /* b */
@@ -391,7 +405,10 @@ static void test_load_v2(void)
QEMUFile *loading = open_test_file(false);
TestStruct obj;
- vmstate_load_state(loading, &vmstate_versioned, &obj, 2);
+ ret = vmstate_load_state(loading, &vmstate_versioned, &obj, 2, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
g_assert_cmpint(obj.a, ==, 10);
g_assert_cmpint(obj.b, ==, 20);
g_assert_cmpint(obj.c, ==, 30);
@@ -425,10 +442,15 @@ static const VMStateDescription vmstate_skipping = {
static void test_save_noskip(void)
{
+ Error *local_err = NULL;
QEMUFile *fsave = open_test_file(true);
TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
.skip_c_e = false };
- int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
+ int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
+ &local_err);
+ if (ret) {
+ error_report_err(local_err);
+ }
g_assert(!ret);
g_assert(!qemu_file_get_error(fsave));
@@ -447,10 +469,15 @@ static void test_save_noskip(void)
static void test_save_skip(void)
{
+ Error *local_err = NULL;
QEMUFile *fsave = open_test_file(true);
TestStruct obj = { .a = 1, .b = 2, .c = 3, .d = 4, .e = 5, .f = 6,
.skip_c_e = true };
- int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL);
+ int ret = vmstate_save_state(fsave, &vmstate_skipping, &obj, NULL,
+ &local_err);
+ if (ret) {
+ error_report_err(local_err);
+ }
g_assert(!ret);
g_assert(!qemu_file_get_error(fsave));
@@ -467,6 +494,8 @@ static void test_save_skip(void)
static void test_load_noskip(void)
{
+ Error *local_err = NULL;
+ int ret;
uint8_t buf[] = {
0, 0, 0, 10, /* a */
0, 0, 0, 20, /* b */
@@ -480,7 +509,10 @@ static void test_load_noskip(void)
QEMUFile *loading = open_test_file(false);
TestStruct obj = { .skip_c_e = false };
- vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
+ ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
g_assert(!qemu_file_get_error(loading));
g_assert_cmpint(obj.a, ==, 10);
g_assert_cmpint(obj.b, ==, 20);
@@ -493,6 +525,8 @@ static void test_load_noskip(void)
static void test_load_skip(void)
{
+ Error *local_err = NULL;
+ int ret;
uint8_t buf[] = {
0, 0, 0, 10, /* a */
0, 0, 0, 20, /* b */
@@ -504,7 +538,10 @@ static void test_load_skip(void)
QEMUFile *loading = open_test_file(false);
TestStruct obj = { .skip_c_e = true, .c = 300, .e = 500 };
- vmstate_load_state(loading, &vmstate_skipping, &obj, 2);
+ ret = vmstate_load_state(loading, &vmstate_skipping, &obj, 2, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
g_assert(!qemu_file_get_error(loading));
g_assert_cmpint(obj.a, ==, 10);
g_assert_cmpint(obj.b, ==, 20);
@@ -744,6 +781,8 @@ static void test_save_q(void)
static void test_load_q(void)
{
+ int ret;
+ Error *local_err = NULL;
TestQtailq obj_q = {
.i16 = -512,
.i32 = 70000,
@@ -773,7 +812,10 @@ static void test_load_q(void)
TestQtailq tgt;
QTAILQ_INIT(&tgt.q);
- vmstate_load_state(fload, &vmstate_q, &tgt, 1);
+ ret = vmstate_load_state(fload, &vmstate_q, &tgt, 1, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
char eof = qemu_get_byte(fload);
g_assert(!qemu_file_get_error(fload));
g_assert_cmpint(tgt.i16, ==, obj_q.i16);
@@ -1115,6 +1157,8 @@ static void diff_iommu(TestGTreeIOMMU *iommu1, TestGTreeIOMMU *iommu2)
static void test_gtree_load_domain(void)
{
+ Error *local_err = NULL;
+ int ret;
TestGTreeDomain *dest_domain = g_new0(TestGTreeDomain, 1);
TestGTreeDomain *orig_domain = create_first_domain();
QEMUFile *fload, *fsave;
@@ -1127,7 +1171,11 @@ static void test_gtree_load_domain(void)
fload = open_test_file(false);
- vmstate_load_state(fload, &vmstate_domain, dest_domain, 1);
+ ret = vmstate_load_state(fload, &vmstate_domain, dest_domain, 1,
+ &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
eof = qemu_get_byte(fload);
g_assert(!qemu_file_get_error(fload));
g_assert_cmpint(orig_domain->id, ==, dest_domain->id);
@@ -1230,6 +1278,8 @@ static void test_gtree_save_iommu(void)
static void test_gtree_load_iommu(void)
{
+ Error *local_err = NULL;
+ int ret;
TestGTreeIOMMU *dest_iommu = g_new0(TestGTreeIOMMU, 1);
TestGTreeIOMMU *orig_iommu = create_iommu();
QEMUFile *fsave, *fload;
@@ -1241,7 +1291,10 @@ static void test_gtree_load_iommu(void)
qemu_fclose(fsave);
fload = open_test_file(false);
- vmstate_load_state(fload, &vmstate_iommu, dest_iommu, 1);
+ ret = vmstate_load_state(fload, &vmstate_iommu, dest_iommu, 1, &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
eof = qemu_get_byte(fload);
g_assert(!qemu_file_get_error(fload));
g_assert_cmpint(orig_iommu->id, ==, dest_iommu->id);
@@ -1363,6 +1416,8 @@ static void test_save_qlist(void)
static void test_load_qlist(void)
{
+ Error *local_err = NULL;
+ int ret;
QEMUFile *fsave, *fload;
TestQListContainer *orig_container = alloc_container();
TestQListContainer *dest_container = g_new0(TestQListContainer, 1);
@@ -1376,7 +1431,11 @@ static void test_load_qlist(void)
qemu_fclose(fsave);
fload = open_test_file(false);
- vmstate_load_state(fload, &vmstate_container, dest_container, 1);
+ ret = vmstate_load_state(fload, &vmstate_container, dest_container, 1,
+ &local_err);
+ if (ret < 0) {
+ error_report_err(local_err);
+ }
eof = qemu_get_byte(fload);
g_assert(!qemu_file_get_error(fload));
g_assert_cmpint(eof, ==, QEMU_VM_EOF);
diff --git a/tests/vm/README b/tests/vm/README
index f9c04cc..14ac323 100644
--- a/tests/vm/README
+++ b/tests/vm/README
@@ -1 +1 @@
-See docs/devel/testing.rst for help.
+See docs/devel/testing/main.rst for help.
diff --git a/tests/vm/freebsd b/tests/vm/freebsd
index 74b3b1e..ea09b21 100755
--- a/tests/vm/freebsd
+++ b/tests/vm/freebsd
@@ -28,8 +28,8 @@ class FreeBSDVM(basevm.BaseVM):
name = "freebsd"
arch = "x86_64"
- link = "https://download.freebsd.org/releases/CI-IMAGES/14.1-RELEASE/amd64/Latest/FreeBSD-14.1-RELEASE-amd64-BASIC-CI.raw.xz"
- csum = "202fe27a05427f0a86d3ebb97712745186f2776ccc4f70d95466dd99a0238ba5"
+ link = "https://download.freebsd.org/releases/CI-IMAGES/14.3-RELEASE/amd64/Latest/FreeBSD-14.3-RELEASE-amd64-BASIC-CI.raw.xz"
+ csum = "ec0f5a4bbe63aa50a725d9fee0f1931f850e9a21cbebdadb991df00f168d6805"
size = "20G"
BUILD_SCRIPT = """
@@ -40,7 +40,9 @@ class FreeBSDVM(basevm.BaseVM):
tar -xf /dev/vtbd1;
cd ../build;
../src/configure --extra-ldflags=-L/usr/local/lib \
- --extra-cflags=-I/usr/local/include {configure_opts};
+ --extra-cflags=-I/usr/local/include \
+ --enable-rust \
+ {configure_opts};
gmake --output-sync -j{jobs} {target} {verbose};
"""
diff --git a/tests/vm/openbsd b/tests/vm/openbsd
index 5e4f76f..2ea86a0 100755
--- a/tests/vm/openbsd
+++ b/tests/vm/openbsd
@@ -22,8 +22,8 @@ class OpenBSDVM(basevm.BaseVM):
name = "openbsd"
arch = "x86_64"
- link = "https://cdn.openbsd.org/pub/OpenBSD/7.6/amd64/install76.iso"
- csum = "60cba8cb391b50bba8fa10fc768bd0529636f5345d82133c93e22c798d8e5269"
+ link = "https://cdn.openbsd.org/pub/OpenBSD/7.7/amd64/install77.iso"
+ csum = "da0106e39463f015524dca806f407c37a9bdd17e6dfffe533b06a2dd2edd8a27"
size = "20G"
pkgs = [
# tools