aboutsummaryrefslogtreecommitdiff
path: root/tests/functional
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional')
-rw-r--r--tests/functional/aspeed.py2
-rw-r--r--tests/functional/meson.build29
-rw-r--r--tests/functional/qemu_test/__init__.py2
-rw-r--r--tests/functional/qemu_test/decorators.py18
-rw-r--r--tests/functional/qemu_test/ports.py3
-rw-r--r--tests/functional/qemu_test/testcase.py6
-rw-r--r--tests/functional/qemu_test/tuxruntest.py11
-rw-r--r--tests/functional/qemu_test/uncompress.py2
-rw-r--r--tests/functional/reverse_debugging.py196
-rwxr-xr-xtests/functional/test_aarch64_aspeed_ast2700.py (renamed from tests/functional/test_aarch64_aspeed.py)82
-rwxr-xr-xtests/functional/test_aarch64_aspeed_ast2700fc.py135
-rwxr-xr-xtests/functional/test_aarch64_device_passthrough.py142
-rwxr-xr-xtests/functional/test_aarch64_imx8mp_evk.py68
-rwxr-xr-xtests/functional/test_aarch64_replay.py39
-rwxr-xr-xtests/functional/test_aarch64_reverse_debug.py38
-rwxr-xr-xtests/functional/test_aarch64_rme_sbsaref.py6
-rwxr-xr-xtests/functional/test_aarch64_rme_virt.py2
-rwxr-xr-xtests/functional/test_aarch64_sbsaref.py5
-rwxr-xr-xtests/functional/test_aarch64_sbsaref_alpine.py6
-rwxr-xr-xtests/functional/test_aarch64_sbsaref_freebsd.py5
-rwxr-xr-xtests/functional/test_aarch64_smmu.py211
-rwxr-xr-xtests/functional/test_aarch64_tcg_plugins.py1
-rwxr-xr-xtests/functional/test_aarch64_virt.py8
-rwxr-xr-xtests/functional/test_aarch64_xen.py1
-rwxr-xr-xtests/functional/test_arm_aspeed_ast1030.py10
-rwxr-xr-xtests/functional/test_arm_aspeed_ast2500.py17
-rwxr-xr-xtests/functional/test_arm_aspeed_ast2600.py51
-rw-r--r--tests/functional/test_arm_aspeed_bletchley.py4
-rwxr-xr-xtests/functional/test_arm_aspeed_palmetto.py4
-rwxr-xr-xtests/functional/test_arm_aspeed_romulus.py4
-rw-r--r--tests/functional/test_arm_aspeed_witherspoon.py4
-rwxr-xr-xtests/functional/test_arm_bpim2u.py2
-rwxr-xr-xtests/functional/test_arm_cubieboard.py4
-rwxr-xr-xtests/functional/test_arm_integratorcp.py6
-rwxr-xr-xtests/functional/test_arm_orangepi.py2
-rwxr-xr-xtests/functional/test_arm_quanta_gsj.py2
-rwxr-xr-xtests/functional/test_arm_realview.py47
-rwxr-xr-xtests/functional/test_arm_smdkc210.py2
-rwxr-xr-xtests/functional/test_arm_stellaris.py48
-rwxr-xr-xtests/functional/test_avr_mega2560.py11
-rwxr-xr-xtests/functional/test_avr_uno.py32
-rwxr-xr-xtests/functional/test_hppa_seabios.py2
-rwxr-xr-xtests/functional/test_i386_replay.py28
-rwxr-xr-xtests/functional/test_m68k_nextcube.py6
-rwxr-xr-xtests/functional/test_m68k_q800.py3
-rwxr-xr-xtests/functional/test_m68k_replay.py3
-rwxr-xr-xtests/functional/test_mem_addr_space.py63
-rwxr-xr-xtests/functional/test_memlock.py79
-rwxr-xr-xtests/functional/test_microblaze_s3adsp1800.py18
-rwxr-xr-xtests/functional/test_microblazeel_s3adsp1800.py6
-rwxr-xr-xtests/functional/test_migration.py3
-rwxr-xr-xtests/functional/test_mips64_malta.py35
-rwxr-xr-xtests/functional/test_mips64el_malta.py28
-rwxr-xr-xtests/functional/test_mips64el_replay.py6
-rwxr-xr-xtests/functional/test_mips_malta.py106
-rwxr-xr-xtests/functional/test_mips_replay.py2
-rwxr-xr-xtests/functional/test_mipsel_malta.py22
-rw-r--r--tests/functional/test_mipsel_replay.py2
-rwxr-xr-xtests/functional/test_pc_cpu_hotplug_props.py1
-rwxr-xr-xtests/functional/test_ppc64_hv.py8
-rwxr-xr-xtests/functional/test_ppc64_pseries.py1
-rwxr-xr-xtests/functional/test_ppc64_reverse_debug.py41
-rwxr-xr-xtests/functional/test_s390x_topology.py12
-rwxr-xr-xtests/functional/test_s390x_tuxrun.py1
-rwxr-xr-xtests/functional/test_sparc64_tuxrun.py1
-rwxr-xr-xtests/functional/test_vnc.py10
-rwxr-xr-xtests/functional/test_x86_64_kvm_xen.py2
-rwxr-xr-xtests/functional/test_x86_64_replay.py43
-rwxr-xr-xtests/functional/test_x86_64_reverse_debug.py36
69 files changed, 1617 insertions, 219 deletions
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
index 77dc893..7a40d5d 100644
--- a/tests/functional/aspeed.py
+++ b/tests/functional/aspeed.py
@@ -44,7 +44,7 @@ class AspeedTest(LinuxKernelTest):
def do_test_arm_aspeed_buildroot_poweroff(self):
exec_command_and_wait_for_pattern(self, 'poweroff',
- 'System halted');
+ 'System halted')
def do_test_arm_aspeed_sdk_start(self, image):
self.require_netdev('user')
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 0f8be30..8515856 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -11,12 +11,17 @@ endif
# Timeouts for individual tests that can be slow e.g. with debugging enabled
test_timeouts = {
- 'aarch64_aspeed' : 600,
+ 'aarch64_aspeed_ast2700' : 600,
+ 'aarch64_aspeed_ast2700fc' : 600,
+ 'aarch64_device_passthrough' : 720,
+ 'aarch64_imx8mp_evk' : 240,
'aarch64_raspi4' : 480,
+ 'aarch64_reverse_debug' : 180,
'aarch64_rme_virt' : 1200,
'aarch64_rme_sbsaref' : 1200,
'aarch64_sbsaref_alpine' : 1200,
'aarch64_sbsaref_freebsd' : 720,
+ 'aarch64_smmu' : 720,
'aarch64_tuxrun' : 240,
'aarch64_virt' : 360,
'aarch64_virt_gpu' : 480,
@@ -38,8 +43,11 @@ test_timeouts = {
'arm_tuxrun' : 240,
'arm_sx1' : 360,
'intel_iommu': 300,
- 'mips_malta' : 120,
+ 'mips_malta' : 480,
+ 'mipsel_malta' : 420,
'mipsel_replay' : 480,
+ 'mips64_malta' : 240,
+ 'mips64el_malta' : 420,
'mips64el_replay' : 180,
'netdev_ethtool' : 180,
'ppc_40p' : 240,
@@ -74,15 +82,20 @@ tests_aarch64_system_quick = [
]
tests_aarch64_system_thorough = [
- 'aarch64_aspeed',
+ 'aarch64_aspeed_ast2700',
+ 'aarch64_aspeed_ast2700fc',
+ 'aarch64_device_passthrough',
+ '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',
@@ -124,8 +137,10 @@ tests_arm_system_thorough = [
'arm_orangepi',
'arm_quanta_gsj',
'arm_raspi2',
+ 'arm_realview',
'arm_replay',
'arm_smdkc210',
+ 'arm_stellaris',
'arm_sx1',
'arm_vexpress',
'arm_virt',
@@ -138,6 +153,7 @@ tests_arm_linuxuser_thorough = [
tests_avr_system_thorough = [
'avr_mega2560',
+ 'avr_uno',
]
tests_hppa_system_quick = [
@@ -149,6 +165,7 @@ tests_i386_system_quick = [
]
tests_i386_system_thorough = [
+ 'i386_replay',
'i386_tuxrun',
]
@@ -186,6 +203,7 @@ tests_mipsel_system_thorough = [
]
tests_mips64_system_thorough = [
+ 'mips64_malta',
'mips64_tuxrun',
]
@@ -229,6 +247,7 @@ tests_ppc64_system_thorough = [
'ppc64_powernv',
'ppc64_pseries',
'ppc64_replay',
+ 'ppc64_reverse_debug',
'ppc64_tuxrun',
'ppc64_mac99',
]
@@ -297,6 +316,7 @@ tests_x86_64_system_quick = [
'virtio_version',
'x86_cpu_model_versions',
'vnc',
+ 'memlock',
]
tests_x86_64_system_thorough = [
@@ -311,6 +331,7 @@ tests_x86_64_system_thorough = [
'x86_64_hotplug_cpu',
'x86_64_kvm_xen',
'x86_64_replay',
+ 'x86_64_reverse_debug',
'x86_64_tuxrun',
]
@@ -398,4 +419,4 @@ endforeach
run_target('precache-functional',
depends: precache_all,
- command: ['true'])
+ command: [python, '-c', ''])
diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py
index af41c2c..6e666a0 100644
--- a/tests/functional/qemu_test/__init__.py
+++ b/tests/functional/qemu_test/__init__.py
@@ -15,6 +15,6 @@ from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
from .linuxkernel import LinuxKernelTest
from .decorators import skipIfMissingCommands, skipIfNotMachine, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \
- skipIfMissingImports, skipIfOperatingSystem
+ skipIfMissingImports, skipIfOperatingSystem, skipLockedMemoryTest
from .archive import archive_extract
from .uncompress import uncompress
diff --git a/tests/functional/qemu_test/decorators.py b/tests/functional/qemu_test/decorators.py
index 50d29de..c0d1567 100644
--- a/tests/functional/qemu_test/decorators.py
+++ b/tests/functional/qemu_test/decorators.py
@@ -5,6 +5,7 @@
import importlib
import os
import platform
+import resource
from unittest import skipIf, skipUnless
from .cmd import which
@@ -131,3 +132,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/ports.py b/tests/functional/qemu_test/ports.py
index cc39939..631b77a 100644
--- a/tests/functional/qemu_test/ports.py
+++ b/tests/functional/qemu_test/ports.py
@@ -10,12 +10,11 @@
import fcntl
import os
import socket
-import sys
-import tempfile
from .config import BUILD_DIR
from typing import List
+
class Ports():
PORTS_ADDR = '127.0.0.1'
diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py
index 50c401b..2082c6f 100644
--- a/tests/functional/qemu_test/testcase.py
+++ b/tests/functional/qemu_test/testcase.py
@@ -23,7 +23,7 @@ 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
@@ -317,7 +317,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)
diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py
index ad74156..6c442ff 100644
--- a/tests/functional/qemu_test/tuxruntest.py
+++ b/tests/functional/qemu_test/tuxruntest.py
@@ -10,8 +10,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import os
-import stat
-from subprocess import check_call, DEVNULL
from qemu_test import QemuSystemTest
from qemu_test import exec_command_and_wait_for_pattern
@@ -77,12 +75,12 @@ class TuxRunBaselineTest(QemuSystemTest):
blockdev = "driver=raw,file.driver=file," \
+ f"file.filename={disk},node-name=hd0"
- kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
- kcmd_line += f" root=/dev/{self.root}"
- kcmd_line += f" console={self.console}"
+ self.kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
+ self.kcmd_line += f" root=/dev/{self.root}"
+ self.kcmd_line += f" console={self.console}"
self.vm.add_args('-kernel', kernel,
- '-append', kcmd_line,
+ '-append', self.kcmd_line,
'-blockdev', blockdev)
# Sometimes we need extra devices attached
@@ -103,6 +101,7 @@ class TuxRunBaselineTest(QemuSystemTest):
wait to exit cleanly.
"""
ps1='root@tuxtest:~#'
+ self.wait_for_console_pattern(self.kcmd_line)
self.wait_for_console_pattern('tuxtest login:')
exec_command_and_wait_for_pattern(self, 'root', ps1)
exec_command_and_wait_for_pattern(self, 'cat /proc/interrupts', ps1)
diff --git a/tests/functional/qemu_test/uncompress.py b/tests/functional/qemu_test/uncompress.py
index ce79da1..b7ef8f7 100644
--- a/tests/functional/qemu_test/uncompress.py
+++ b/tests/functional/qemu_test/uncompress.py
@@ -13,7 +13,7 @@ import os
import stat
import shutil
from urllib.parse import urlparse
-from subprocess import run, CalledProcessError, DEVNULL
+from subprocess import run, CalledProcessError
from .asset import Asset
diff --git a/tests/functional/reverse_debugging.py b/tests/functional/reverse_debugging.py
new file mode 100644
index 0000000..f9a1d39
--- /dev/null
+++ b/tests/functional/reverse_debugging.py
@@ -0,0 +1,196 @@
+# Reverse debugging test
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# 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
+
+from qemu_test import LinuxKernelTest, get_qemu_img
+from qemu_test.ports import Ports
+
+
+class ReverseDebugging(LinuxKernelTest):
+ """
+ Test GDB reverse debugging commands: reverse step and reverse continue.
+ Recording saves the execution of some instructions and makes an initial
+ VM snapshot to allow reverse execution.
+ Replay saves the order of the first instructions and then checks that they
+ are executed backwards in the correct order.
+ After that the execution is replayed to the end, and reverse continue
+ command is checked by setting several breakpoints, and asserting
+ 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()
+ if record:
+ logger.info('recording the execution...')
+ mode = 'record'
+ else:
+ logger.info('replaying the execution...')
+ mode = 'replay'
+ vm.add_args('-gdb', 'tcp::%d' % port, '-S')
+ vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' %
+ (shift, mode, replay_path),
+ '-net', 'none')
+ vm.add_args('-drive', 'file=%s,if=none' % image_path)
+ 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;')
+
+ @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
+
+ logger = logging.getLogger('replay')
+
+ # create qcow2 for snapshots
+ logger.info('creating qcow2 image for VM snapshots')
+ image_path = os.path.join(self.workdir, 'disk.qcow2')
+ qemu_img = get_qemu_img(self)
+ 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)
+
+ replay_path = os.path.join(self.workdir, 'replay.bin')
+
+ # record the log
+ vm = self.run_vm(True, shift, args, replay_path, image_path, -1)
+ while self.vm_get_icount(vm) <= self.STEPS:
+ pass
+ last_icount = self.vm_get_icount(vm)
+ vm.shutdown()
+
+ logger.info("recorded log with %s+ steps" % last_icount)
+
+ # replay and run debug commands
+ 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:
+ self.fail('Reverse step is not supported by QEMU')
+ if b'ReverseContinue+' not in r:
+ self.fail('Reverse continue is not supported by QEMU')
+
+ logger.info('stepping forward')
+ steps = []
+ # record first instruction addresses
+ for _ in range(self.STEPS):
+ pc = self.get_pc(g)
+ logger.info('saving position %x' % pc)
+ steps.append(pc)
+ self.gdb_step(g)
+
+ # 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)
+
+ # 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)
+
+ # 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')
+
+ # 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')
+ 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)))
+
+ 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;')
+
+ # assume that none of the first instructions is executed again
+ # breaking the order of the breakpoints
+ self.check_pc(g, steps[-1])
+ logger.info('successfully reached %x' % steps[-1])
+
+ logger.info('exiting gdb and qemu')
+ vm.shutdown()
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/test_aarch64_aspeed_ast2700.py
index c25c966..d02dc79 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/test_aarch64_aspeed_ast2700.py
@@ -18,22 +18,52 @@ class AST2x00MachineSDK(QemuSystemTest):
def do_test_aarch64_aspeed_sdk_start(self, image):
self.require_netdev('user')
self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
'-net', 'nic', '-net', 'user', '-snapshot')
self.vm.launch()
+ def verify_vbootrom_firmware_flow(self):
+ wait_for_console_pattern(self, 'Found valid FIT image')
+ wait_for_console_pattern(self, '[uboot] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[fdt] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[tee] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[atf] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, 'Jumping to BL31 (Trusted Firmware-A)')
+
+ def verify_openbmc_boot_and_login(self, name):
wait_for_console_pattern(self, 'U-Boot 2023.10')
wait_for_console_pattern(self, '## Loading kernel from FIT Image')
wait_for_console_pattern(self, 'Starting kernel ...')
- ASSET_SDK_V905_AST2700 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-a0-default-obmc.tar.gz',
- 'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
- ASSET_SDK_V905_AST2700A1 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-default-obmc.tar.gz',
- 'c1f4496aec06743c812a6e9a1a18d032f34d62f3ddb6956e924fef62aa2046a5')
+ ASSET_SDK_V906_AST2700 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-a0-default-obmc.tar.gz',
+ '7247b6f19dbfb700686f8d9f723ac23f3eb229226c0589cb9b06b80d1b61f3cb')
+
+ ASSET_SDK_V906_AST2700A1 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
+ 'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+
+ 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 ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
def start_ast2700_test(self, name):
num_cpu = 4
@@ -73,38 +103,38 @@ class AST2x00MachineSDK(QemuSystemTest):
f'loader,addr=0x430000000,cpu-num={i}')
self.vm.add_args('-smp', str(num_cpu))
- self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.do_test_aarch64_aspeed_sdk_start(
self.scratch_file(name, 'image-bmc'))
- wait_for_console_pattern(self, f'{name} login:')
-
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
-
- exec_command_and_wait_for_pattern(self,
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
- 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000)
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+ def start_ast2700_test_vbootrom(self, name):
+ self.vm.add_args('-bios', 'ast27x0_bootrom.bin')
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
- def test_aarch64_ast2700_evb_sdk_v09_05(self):
+ def test_aarch64_ast2700_evb_sdk_v09_06(self):
self.set_machine('ast2700-evb')
- self.archive_extract(self.ASSET_SDK_V905_AST2700)
+ self.archive_extract(self.ASSET_SDK_V906_AST2700)
self.start_ast2700_test('ast2700-a0-default')
+ self.verify_openbmc_boot_and_login('ast2700-a0-default')
+ self.do_ast2700_i2c_test()
- def test_aarch64_ast2700a1_evb_sdk_v09_05(self):
+ def test_aarch64_ast2700a1_evb_sdk_v09_06(self):
self.set_machine('ast2700a1-evb')
- self.archive_extract(self.ASSET_SDK_V905_AST2700A1)
+ self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
self.start_ast2700_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+
+ def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_06(self):
+ self.set_machine('ast2700a1-evb')
+ self.archive_extract(self.ASSET_SDK_V906_AST2700A1)
+ self.start_ast2700_test_vbootrom('ast2700-default')
+ self.verify_vbootrom_firmware_flow()
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_aspeed_ast2700fc.py b/tests/functional/test_aarch64_aspeed_ast2700fc.py
new file mode 100755
index 0000000..b85370e
--- /dev/null
+++ b/tests/functional/test_aarch64_aspeed_ast2700fc.py
@@ -0,0 +1,135 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED SoCs with firmware
+#
+# Copyright (C) 2022 ASPEED Technology Inc
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+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 AST2x00MachineSDK(QemuSystemTest):
+
+ def do_test_aarch64_aspeed_sdk_start(self, image):
+ self.require_netdev('user')
+ self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
+ '-net', 'nic', '-net', 'user', '-snapshot')
+
+ self.vm.launch()
+
+ def verify_openbmc_boot_and_login(self, name):
+ wait_for_console_pattern(self, 'U-Boot 2023.10')
+ wait_for_console_pattern(self, '## Loading kernel from FIT Image')
+ wait_for_console_pattern(self, 'Starting kernel ...')
+
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
+
+ ASSET_SDK_V906_AST2700 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
+ 'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+
+ 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 ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+
+ def do_ast2700fc_ssp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=1)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'ssp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def do_ast2700fc_tsp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=2)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'tsp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def start_ast2700fc_test(self, name):
+ ca35_core = 4
+ uboot_size = os.path.getsize(self.scratch_file(name,
+ 'u-boot-nodtb.bin'))
+ uboot_dtb_load_addr = hex(0x400000000 + uboot_size)
+
+ load_images_list = [
+ {
+ 'addr': '0x400000000',
+ 'file': self.scratch_file(name,
+ 'u-boot-nodtb.bin')
+ },
+ {
+ 'addr': str(uboot_dtb_load_addr),
+ 'file': self.scratch_file(name, 'u-boot.dtb')
+ },
+ {
+ 'addr': '0x430000000',
+ 'file': self.scratch_file(name, 'bl31.bin')
+ },
+ {
+ 'addr': '0x430080000',
+ 'file': self.scratch_file(name, 'optee',
+ 'tee-raw.bin')
+ }
+ ]
+
+ for load_image in load_images_list:
+ addr = load_image['addr']
+ file = load_image['file']
+ self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+ for i in range(ca35_core):
+ self.vm.add_args('-device',
+ f'loader,addr=0x430000000,cpu-num={i}')
+
+ load_elf_list = {
+ 'ssp': self.scratch_file(name, 'zephyr-aspeed-ssp.elf'),
+ 'tsp': self.scratch_file(name, 'zephyr-aspeed-tsp.elf')
+ }
+
+ for cpu_num, key in enumerate(load_elf_list, start=4):
+ file = load_elf_list[key]
+ self.vm.add_args('-device',
+ f'loader,file={file},cpu-num={cpu_num}')
+
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
+
+ def test_aarch64_ast2700fc_sdk_v09_06(self):
+ self.set_machine('ast2700fc')
+
+ self.archive_extract(self.ASSET_SDK_V906_AST2700)
+ self.start_ast2700fc_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+ self.do_ast2700fc_ssp_test()
+ self.do_ast2700fc_tsp_test()
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_device_passthrough.py b/tests/functional/test_aarch64_device_passthrough.py
new file mode 100755
index 0000000..1f3f158
--- /dev/null
+++ b/tests/functional/test_aarch64_device_passthrough.py
@@ -0,0 +1,142 @@
+#!/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
+
+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
+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
+ #
+ # 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://fileserver.linaro.org/s/fx5DXxBYme8dw2G/'
+ 'download/device_passthrough.tar.xz'),
+ '812750b664d61c2986f2b149939ae28cafbd60d53e9c7e4b16e97143845e196d')
+
+ # 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_gz = self.ASSET_DEVICE_PASSTHROUGH_STACK.fetch()
+ self.archive_extract(stack_path_tar_gz, format="tar")
+
+ stack = self.scratch_file('out')
+ kernel = os.path.join(stack, 'Image.gz')
+ rootfs_host = os.path.join(stack, 'host.ext4')
+ disk_vfio = os.path.join(stack, 'disk_vfio')
+ disk_iommufd = os.path.join(stack, 'disk_iommufd')
+ guest_cmd = os.path.join(stack, 'guest.sh')
+ nested_guest_cmd = os.path.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/test_aarch64_imx8mp_evk.py b/tests/functional/test_aarch64_imx8mp_evk.py
new file mode 100755
index 0000000..99ddcde
--- /dev/null
+++ b/tests/functional/test_aarch64_imx8mp_evk.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+
+
+class Imx8mpEvkMachine(LinuxKernelTest):
+
+ ASSET_IMAGE = Asset(
+ ('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/'
+ 'debian-12-generic-arm64-20231210-1590.tar.xz'),
+ '7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359')
+
+ KERNEL_OFFSET = 0x51000000
+ KERNEL_SIZE = 32622528
+ INITRD_OFFSET = 0x76000000
+ INITRD_SIZE = 30987766
+ DTB_OFFSET = 0x64F51000
+ DTB_SIZE = 45 * 1024
+
+ def extract(self, in_path, out_path, offset, size):
+ try:
+ with open(in_path, "rb") as source:
+ source.seek(offset)
+ data = source.read(size)
+ with open(out_path, "wb") as target:
+ target.write(data)
+ except (IOError, ValueError) as e:
+ self.log.error(f"Failed to extract {out_path}: {e}")
+ raise
+
+ def setUp(self):
+ super().setUp()
+
+ self.image_path = self.scratch_file("disk.raw")
+ self.kernel_path = self.scratch_file("linux")
+ self.initrd_path = self.scratch_file("initrd.zstd")
+ self.dtb_path = self.scratch_file("imx8mp-evk.dtb")
+
+ self.archive_extract(self.ASSET_IMAGE)
+ self.extract(self.image_path, self.kernel_path,
+ self.KERNEL_OFFSET, self.KERNEL_SIZE)
+ self.extract(self.image_path, self.initrd_path,
+ self.INITRD_OFFSET, self.INITRD_SIZE)
+ self.extract(self.image_path, self.dtb_path,
+ 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',
+ '-smp', '4',
+ '-kernel', self.kernel_path,
+ '-initrd', self.initrd_path,
+ '-dtb', self.dtb_path,
+ '-append', 'root=/dev/mmcblk2p1',
+ '-drive', f'file={self.image_path},if=sd,bus=2,'
+ 'format=raw,id=mmcblk2,snapshot=on')
+
+ self.vm.launch()
+ self.wait_for_console_pattern('Welcome to ')
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_aarch64_replay.py b/tests/functional/test_aarch64_replay.py
index 029fef3..db12e76 100755
--- a/tests/functional/test_aarch64_replay.py
+++ b/tests/functional/test_aarch64_replay.py
@@ -5,27 +5,46 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipIfOperatingSystem
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipIfOperatingSystem, get_qemu_img
from replay_kernel import ReplayKernelBase
class Aarch64Replay(ReplayKernelBase):
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
- 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
- '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/Image',
+ 'b74743c5e89e1cea0f73368d24ae0ae85c5204ff84be3b5e9610417417d2f235')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/rootfs.ext4.zst',
+ 'a1acaaae2068df4648d04ff75f532aaa8c5edcd6b936122b6f0db4848a07b465')
- # Failing on Darwin: https://gitlab.com/qemu-project/qemu/-/issues/2907
- @skipIfOperatingSystem('Darwin')
def test_aarch64_virt(self):
+ self.require_netdev('user')
self.set_machine('virt')
- self.cpu = 'cortex-a53'
+ self.cpu = 'cortex-a57'
kernel_path = self.ASSET_KERNEL.fetch()
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', 'virtio-blk-device,drive=hd0-rr',
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
- 'console=ttyAMA0')
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern)
+ 'console=ttyAMA0 root=/dev/vda')
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern,
+ args=args)
if __name__ == '__main__':
diff --git a/tests/functional/test_aarch64_reverse_debug.py b/tests/functional/test_aarch64_reverse_debug.py
new file mode 100755
index 0000000..58d4532
--- /dev/null
+++ b/tests/functional/test_aarch64_reverse_debug.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# 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 reverse_debugging import ReverseDebugging
+
+
+@skipIfMissingImports('avocado.utils')
+class ReverseDebugging_AArch64(ReverseDebugging):
+
+ REG_PC = 32
+
+ KERNEL_ASSET = 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))
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff --git a/tests/functional/test_aarch64_rme_sbsaref.py b/tests/functional/test_aarch64_rme_sbsaref.py
index 0f4f610..746770e 100755
--- a/tests/functional/test_aarch64_rme_sbsaref.py
+++ b/tests/functional/test_aarch64_rme_sbsaref.py
@@ -9,15 +9,13 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import time
import os
-import logging
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, wait_for_console_pattern
+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:
diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/test_aarch64_rme_virt.py
index a1abf58..8452d27 100755
--- a/tests/functional/test_aarch64_rme_virt.py
+++ b/tests/functional/test_aarch64_rme_virt.py
@@ -9,9 +9,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import time
import os
-import logging
from qemu_test import QemuSystemTest, Asset
from qemu_test import exec_command, wait_for_console_pattern
diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/test_aarch64_sbsaref.py
index e6a55ae..d3402f5 100755
--- a/tests/functional/test_aarch64_sbsaref.py
+++ b/tests/functional/test_aarch64_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/test_aarch64_sbsaref_alpine.py
index c660cc7..8776999 100755
--- a/tests/functional/test_aarch64_sbsaref_alpine.py
+++ b/tests/functional/test_aarch64_sbsaref_alpine.py
@@ -10,11 +10,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
-from unittest import skipUnless
from test_aarch64_sbsaref import fetch_firmware
@@ -29,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/test_aarch64_sbsaref_freebsd.py
index bd6728d..3cddc08 100755
--- a/tests/functional/test_aarch64_sbsaref_freebsd.py
+++ b/tests/functional/test_aarch64_sbsaref_freebsd.py
@@ -10,8 +10,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
from test_aarch64_sbsaref import fetch_firmware
@@ -28,8 +26,9 @@ class Aarch64SbsarefFreeBSD(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_freebsd14(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
+ fetch_firmware(self)
img_path = self.ASSET_FREEBSD_ISO.fetch()
self.vm.set_console()
diff --git a/tests/functional/test_aarch64_smmu.py b/tests/functional/test_aarch64_smmu.py
new file mode 100755
index 0000000..e0f4a92
--- /dev/null
+++ b/tests/functional/test_aarch64_smmu.py
@@ -0,0 +1,211 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# SMMUv3 Functional tests
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Eric Auger <eric.auger@redhat.com>
+#
+# 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 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, hvf_available
+
+
+class SMMU(LinuxKernelTest):
+
+ default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check '
+ 'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 '
+ 'console=ttyAMA0 rd.rescue')
+ IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
+ kernel_path = None
+ initrd_path = None
+ kernel_params = None
+
+ GUEST_PORT = 8080
+
+ def set_up_boot(self, path):
+ self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
+ 'drive=drv0,id=virtio-disk0,bootindex=1,'
+ 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
+ self.vm.add_args('-drive',
+ f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on')
+
+ self.vm.add_args('-netdev',
+ 'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
+ self.GUEST_PORT)
+ self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
+
+ def common_vm_setup(self, kernel, initrd, disk):
+ 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", accel)
+ self.vm.add_args("-cpu", "host")
+ self.vm.add_args("-machine", "iommu=smmuv3")
+ self.vm.add_args("-d", "guest_errors")
+ self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
+ 'edk2-aarch64-code.fd'))
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
+ self.vm.add_args('-object',
+ 'rng-random,id=rng0,filename=/dev/urandom')
+
+ self.kernel_path = kernel.fetch()
+ self.initrd_path = initrd.fetch()
+ self.set_up_boot(disk.fetch())
+
+ def run_and_check(self, filename, hashsum):
+ self.vm.add_args('-initrd', self.initrd_path)
+ self.vm.add_args('-append', self.kernel_params)
+ self.launch_kernel(self.kernel_path, initrd=self.initrd_path,
+ wait_for='attach it to a bug report.')
+ prompt = '# '
+ # Fedora 33 requires 'return' to be pressed to enter the shell.
+ # There seems to be a small race between detecting the previous ':'
+ # and sending the newline, so we need to add a small delay here.
+ self.wait_for_console_pattern(':')
+ time.sleep(0.2)
+ exec_command_and_wait_for_pattern(self, '\n', prompt)
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
+ self.kernel_params)
+
+ # Checking for SMMU enablement:
+ self.log.info("Checking whether SMMU has been enabled...")
+ exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu',
+ 'arm-smmu-v3')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ 'find /sys/kernel/iommu_groups/ -type l',
+ 'devices/0000:00:')
+ self.wait_for_console_pattern(prompt)
+
+ # Copy a file (checked later), umount afterwards to drop disk cache:
+ self.log.info("Checking hard disk...")
+ exec_command_and_wait_for_pattern(self,
+ "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done",
+ "vda2")
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ 'mounted filesystem')
+ exec_command_and_wait_for_pattern(self, 'cp /bin/vi /sysroot/root/vi',
+ prompt)
+ exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
+ # Switch from initrd to the cloud image filesystem:
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ prompt)
+ exec_command_and_wait_for_pattern(self,
+ ('for d in dev proc sys run ; do '
+ 'mount -o bind /$d /sysroot/$d ; done'), prompt)
+ exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
+ # Check files on the hard disk:
+ exec_command_and_wait_for_pattern(self,
+ ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; '
+ 'else echo "files differ"; fi'), 'file ok')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self, f'sha256sum {filename}',
+ hashsum)
+
+ # Check virtio-net via HTTP:
+ exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
+ self.check_http_download(filename, hashsum, self.GUEST_PORT)
+
+
+ # 5.3 kernel without RIL #
+
+ ASSET_KERNEL_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
+
+ ASSET_INITRD_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a')
+
+ ASSET_DISK_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'),
+ '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49')
+
+ F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img'
+ F31_HSUM = '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9'
+
+ def test_smmu_noril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+
+ # 5.8 kernel featuring range invalidation
+ # >= v5.7 kernel
+
+ ASSET_KERNEL_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ 'd8b1e6f7241f339d8e7609c456cf0461ffa4583ed07e0b55c7d1d8a0c154aa89')
+
+ ASSET_INITRD_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df')
+
+ ASSET_DISK_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'),
+ 'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b')
+
+ F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img'
+ F33_HSUM = '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9'
+
+ def test_smmu_ril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/test_aarch64_tcg_plugins.py
index 4ea71f5..cb7e929 100755
--- a/tests/functional/test_aarch64_tcg_plugins.py
+++ b/tests/functional/test_aarch64_tcg_plugins.py
@@ -13,7 +13,6 @@
import tempfile
import mmap
-import os
import re
from qemu.machine.machine import VMLaunchFailure
diff --git a/tests/functional/test_aarch64_virt.py b/tests/functional/test_aarch64_virt.py
index 884aad7..4d0ad90 100755
--- a/tests/functional/test_aarch64_virt.py
+++ b/tests/functional/test_aarch64_virt.py
@@ -13,12 +13,8 @@
import logging
from subprocess import check_call, DEVNULL
-from qemu.machine.machine import VMLaunchFailure
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, exec_command_and_wait_for_pattern
-from qemu_test import wait_for_console_pattern
-from qemu_test import skipIfMissingCommands, get_qemu_img
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern, get_qemu_img
class Aarch64VirtMachine(QemuSystemTest):
diff --git a/tests/functional/test_aarch64_xen.py b/tests/functional/test_aarch64_xen.py
index 3399042..261d796 100755
--- a/tests/functional/test_aarch64_xen.py
+++ b/tests/functional/test_aarch64_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_arm_aspeed_ast1030.py b/tests/functional/test_arm_aspeed_ast1030.py
index d45d9f7..77037f0 100755
--- a/tests/functional/test_arm_aspeed_ast1030.py
+++ b/tests/functional/test_arm_aspeed_ast1030.py
@@ -12,17 +12,17 @@ from qemu_test import exec_command_and_wait_for_pattern
class AST1030Machine(LinuxKernelTest):
- ASSET_ZEPHYR_1_04 = Asset(
+ ASSET_ZEPHYR_3_00 = Asset(
('https://github.com/AspeedTech-BMC'
- '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'),
- '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3')
+ '/zephyr/releases/download/v00.03.00/ast1030-evb-demo.zip'),
+ '37fe3ecd4a1b9d620971a15b96492a81093435396eeac69b6f3e384262ff555f')
- def test_ast1030_zephyros_1_04(self):
+ def test_ast1030_zephyros_3_00(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.elf"
kernel_file = self.archive_extract(
- self.ASSET_ZEPHYR_1_04, member=kernel_name)
+ self.ASSET_ZEPHYR_3_00, member=kernel_name)
self.vm.set_console()
self.vm.add_args('-kernel', kernel_file, '-nographic')
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/test_arm_aspeed_ast2500.py
index 1ffba6c..6923fe8 100755
--- a/tests/functional/test_arm_aspeed_ast2500.py
+++ b/tests/functional/test_arm_aspeed_ast2500.py
@@ -4,9 +4,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset
+from qemu_test import Asset, exec_command_and_wait_for_pattern
from aspeed import AspeedTest
-from qemu_test import exec_command_and_wait_for_pattern
class AST2500Machine(AspeedTest):
@@ -22,30 +21,30 @@ class AST2500Machine(AspeedTest):
image_path = self.ASSET_BR2_202411_AST2500_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.do_test_arm_aspeed_buildroot_start(image_path, '0x0',
'ast2500-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2500 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz',
- 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca')
+ ASSET_SDK_V906_AST2500 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2500-default-obmc.tar.gz',
+ '542db84645b4efd8aed50385d7f4dd1caff379a987032311cfa7b563a3addb2a')
def test_arm_ast2500_evb_sdk(self):
self.set_machine('ast2500-evb')
- self.archive_extract(self.ASSET_SDK_V806_AST2500)
+ self.archive_extract(self.ASSET_SDK_V906_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/test_arm_aspeed_ast2600.py
index 6ae4ed6..fdae4c9 100755
--- a/tests/functional/test_arm_aspeed_ast2600.py
+++ b/tests/functional/test_arm_aspeed_ast2600.py
@@ -27,38 +27,38 @@ class AST2600Machine(AspeedTest):
image_path = self.ASSET_BR2_202411_AST2600_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.3,address=0x32');
+ 'ds1338,bus=aspeed.i2c.bus.3,address=0x32')
self.vm.add_args('-device',
- 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42');
+ 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42')
self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00',
'ast2600-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
exec_command_and_wait_for_pattern(self,
'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32');
+ 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32')
year = time.strftime("%Y")
- exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year);
+ exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year)
exec_command_and_wait_for_pattern(self,
'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device',
- 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64');
+ 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64')
exec_command_and_wait_for_pattern(self,
- 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#');
+ 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#')
exec_command_and_wait_for_pattern(self,
'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom',
- '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff');
+ '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff')
self.do_test_arm_aspeed_buildroot_poweroff()
ASSET_BR2_202302_AST2600_TPM_FLASH = Asset(
@@ -90,50 +90,51 @@ class AST2600Machine(AspeedTest):
exec_command_and_wait_for_pattern(self,
'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device',
- 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)');
+ 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/tpm/tpm0/pcr-sha256/0',
- 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0');
+ 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0')
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2600_A2 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
- '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
+ ASSET_SDK_V906_AST2600 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2600-default-obmc.tar.gz',
+ '768d76e247896ad78c154b9cff4f766da2ce65f217d620b286a4a03a8a4f68f5')
def test_arm_ast2600_evb_sdk(self):
self.set_machine('ast2600-evb')
- self.archive_extract(self.ASSET_SDK_V806_AST2600_A2)
+ self.archive_extract(self.ASSET_SDK_V906_AST2600)
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.5,address=0x32');
+ 'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
self.do_test_arm_aspeed_sdk_start(
- self.scratch_file("ast2600-a2", "image-bmc"))
+ self.scratch_file("ast2600-default", "image-bmc"))
- self.wait_for_console_pattern('ast2600-a2 login:')
+ self.wait_for_console_pattern('ast2600-default login:')
exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#')
+ exec_command_and_wait_for_pattern(self, '0penBmc',
+ 'root@ast2600-default:~#')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
exec_command_and_wait_for_pattern(self,
'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
+ 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32')
year = time.strftime("%Y")
exec_command_and_wait_for_pattern(self,
- '/sbin/hwclock -f /dev/rtc1', year);
+ '/sbin/hwclock -f /dev/rtc1', year)
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_bletchley.py b/tests/functional/test_arm_aspeed_bletchley.py
index 0da856c..5a60b24 100644
--- a/tests/functional/test_arm_aspeed_bletchley.py
+++ b/tests/functional/test_arm_aspeed_bletchley.py
@@ -12,14 +12,14 @@ class BletchleyMachine(AspeedTest):
ASSET_BLETCHLEY_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/bletchley-bmc/openbmc-20250128071329/obmc-phosphor-image-bletchley-20250128071329.static.mtd.xz',
- 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844');
+ 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844')
def test_arm_ast2600_bletchley_openbmc(self):
image_path = self.uncompress(self.ASSET_BLETCHLEY_FLASH)
self.do_test_arm_aspeed_openbmc('bletchley-bmc', image=image_path,
uboot='2019.04', cpu_id='0xf00',
- soc='AST2600 rev A3');
+ soc='AST2600 rev A3')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/test_arm_aspeed_palmetto.py
index 35d832b..ff0b821 100755
--- a/tests/functional/test_arm_aspeed_palmetto.py
+++ b/tests/functional/test_arm_aspeed_palmetto.py
@@ -12,14 +12,14 @@ class PalmettoMachine(AspeedTest):
ASSET_PALMETTO_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/palmetto-bmc/openbmc-20250128071432/obmc-phosphor-image-palmetto-20250128071432.static.mtd',
- 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81');
+ 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81')
def test_arm_ast2400_palmetto_openbmc(self):
image_path = self.ASSET_PALMETTO_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('palmetto-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2400 rev A1');
+ soc='AST2400 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_romulus.py b/tests/functional/test_arm_aspeed_romulus.py
index b97ed95..0447212 100755
--- a/tests/functional/test_arm_aspeed_romulus.py
+++ b/tests/functional/test_arm_aspeed_romulus.py
@@ -12,14 +12,14 @@ class RomulusMachine(AspeedTest):
ASSET_ROMULUS_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/romulus-bmc/openbmc-20250128071340/obmc-phosphor-image-romulus-20250128071340.static.mtd',
- '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b');
+ '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b')
def test_arm_ast2500_romulus_openbmc(self):
image_path = self.ASSET_ROMULUS_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('romulus-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_witherspoon.py b/tests/functional/test_arm_aspeed_witherspoon.py
index ea1ce89..51a2d47 100644
--- a/tests/functional/test_arm_aspeed_witherspoon.py
+++ b/tests/functional/test_arm_aspeed_witherspoon.py
@@ -12,14 +12,14 @@ class WitherspoonMachine(AspeedTest):
ASSET_WITHERSPOON_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/witherspoon-bmc/openbmc-20240618035022/obmc-phosphor-image-witherspoon-20240618035022.ubi.mtd',
- '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213');
+ '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213')
def test_arm_ast2500_witherspoon_openbmc(self):
image_path = self.ASSET_WITHERSPOON_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('witherspoon-bmc', image=image_path,
uboot='2016.07', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/test_arm_bpim2u.py
index 8de6ccb..8bed64b 100755
--- a/tests/functional/test_arm_bpim2u.py
+++ b/tests/functional/test_arm_bpim2u.py
@@ -163,7 +163,7 @@ class BananaPiMachine(LinuxKernelTest):
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff --git a/tests/functional/test_arm_cubieboard.py b/tests/functional/test_arm_cubieboard.py
index b87a281..b536c2f 100755
--- a/tests/functional/test_arm_cubieboard.py
+++ b/tests/functional/test_arm_cubieboard.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern
from qemu_test import skipBigDataTest
@@ -128,7 +126,7 @@ class CubieboardMachine(LinuxKernelTest):
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff --git a/tests/functional/test_arm_integratorcp.py b/tests/functional/test_arm_integratorcp.py
index a85b339..4f00924 100755
--- a/tests/functional/test_arm_integratorcp.py
+++ b/tests/functional/test_arm_integratorcp.py
@@ -73,8 +73,10 @@ class IntegratorMachine(QemuSystemTest):
framebuffer_ready = 'Console: switching to colour frame buffer device'
wait_for_console_pattern(self, framebuffer_ready)
self.vm.cmd('human-monitor-command', command_line='stop')
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screendump_path)
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screendump_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
logger = logging.getLogger('framebuffer')
cpu_count = 1
diff --git a/tests/functional/test_arm_orangepi.py b/tests/functional/test_arm_orangepi.py
index 1815f56..f9bfa8c 100755
--- a/tests/functional/test_arm_orangepi.py
+++ b/tests/functional/test_arm_orangepi.py
@@ -174,7 +174,7 @@ class OrangePiMachine(LinuxKernelTest):
exec_command_and_wait_for_pattern(self, ' ', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern('systemd[1]: Hostname set ' +
'to <orangepipc>')
diff --git a/tests/functional/test_arm_quanta_gsj.py b/tests/functional/test_arm_quanta_gsj.py
index da60aeb..cb0545f 100755
--- a/tests/functional/test_arm_quanta_gsj.py
+++ b/tests/functional/test_arm_quanta_gsj.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern, skipSlowTest
diff --git a/tests/functional/test_arm_realview.py b/tests/functional/test_arm_realview.py
new file mode 100755
index 0000000..82cc964
--- /dev/null
+++ b/tests/functional/test_arm_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_smdkc210.py b/tests/functional/test_arm_smdkc210.py
index 0fda45c..3154e7f 100755
--- a/tests/functional/test_arm_smdkc210.py
+++ b/tests/functional/test_arm_smdkc210.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset
diff --git a/tests/functional/test_arm_stellaris.py b/tests/functional/test_arm_stellaris.py
new file mode 100755
index 0000000..cbd21cb
--- /dev/null
+++ b/tests/functional/test_arm_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_avr_mega2560.py b/tests/functional/test_avr_mega2560.py
index 8e47b42..6359b72 100755
--- a/tests/functional/test_avr_mega2560.py
+++ b/tests/functional/test_avr_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/test_avr_uno.py b/tests/functional/test_avr_uno.py
new file mode 100755
index 0000000..adb3b73
--- /dev/null
+++ b/tests/functional/test_avr_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/test_hppa_seabios.py b/tests/functional/test_hppa_seabios.py
index a44d1a3..661b246 100755
--- a/tests/functional/test_hppa_seabios.py
+++ b/tests/functional/test_hppa_seabios.py
@@ -17,9 +17,9 @@ class HppaSeabios(QemuSystemTest):
def boot_seabios(self):
mach = self.machine
bits = self.MACH_BITS[mach]
+ self.vm.add_args('-no-shutdown')
self.vm.set_console()
self.vm.launch()
- self.machine
wait_for_console_pattern(self, f'SeaBIOS PA-RISC {bits}-bit Firmware')
wait_for_console_pattern(self, f'Emulated machine: HP {mach} ({bits}-bit')
diff --git a/tests/functional/test_i386_replay.py b/tests/functional/test_i386_replay.py
new file mode 100755
index 0000000..7c4c260
--- /dev/null
+++ b/tests/functional/test_i386_replay.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+#
+# Replay test that boots a Linux kernel on a i386 machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from replay_kernel import ReplayKernelBase
+
+
+class I386Replay(ReplayKernelBase):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/20230331/i386/bzImage',
+ 'a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956')
+
+ def test_pc(self):
+ self.set_machine('pc')
+ kernel_url = ()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+ console_pattern = 'VFS: Cannot open root device'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+
+if __name__ == '__main__':
+ ReplayKernelBase.main()
diff --git a/tests/functional/test_m68k_nextcube.py b/tests/functional/test_m68k_nextcube.py
index ff773a7..13c72bd 100755
--- a/tests/functional/test_m68k_nextcube.py
+++ b/tests/functional/test_m68k_nextcube.py
@@ -32,8 +32,10 @@ class NextCubeMachine(QemuSystemTest):
# TODO: wait for the 'displaysurface_create 1120x832' trace-event.
time.sleep(2)
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screenshot_path)
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screenshot_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
@skipIfMissingImports("PIL")
def test_bootrom_framebuffer_size(self):
diff --git a/tests/functional/test_m68k_q800.py b/tests/functional/test_m68k_q800.py
index 400b7ae..b3e6553 100755
--- a/tests/functional/test_m68k_q800.py
+++ b/tests/functional/test_m68k_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/test_m68k_replay.py
index 18c1db5..213d6ae 100755
--- a/tests/functional/test_m68k_replay.py
+++ b/tests/functional/test_m68k_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_mem_addr_space.py b/tests/functional/test_mem_addr_space.py
index 2d9d31e..61b4a19 100755
--- a/tests/functional/test_mem_addr_space.py
+++ b/tests/functional/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/test_memlock.py b/tests/functional/test_memlock.py
new file mode 100755
index 0000000..2b515ff
--- /dev/null
+++ b/tests/functional/test_memlock.py
@@ -0,0 +1,79 @@
+#!/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())
+
+ self.assertTrue(status['VmLck'] == 0)
+
+ 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/test_microblaze_s3adsp1800.py b/tests/functional/test_microblaze_s3adsp1800.py
index c93fa14..f093b16 100755
--- a/tests/functional/test_microblaze_s3adsp1800.py
+++ b/tests/functional/test_microblaze_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/test_microblazeel_s3adsp1800.py b/tests/functional/test_microblazeel_s3adsp1800.py
index ab59941..915902d 100755
--- a/tests/functional/test_microblazeel_s3adsp1800.py
+++ b/tests/functional/test_microblazeel_s3adsp1800.py
@@ -13,9 +13,13 @@ from test_microblaze_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/test_migration.py
index 181223a..c4393c3 100755
--- a/tests/functional/test_migration.py
+++ b/tests/functional/test_migration.py
@@ -11,14 +11,13 @@
# 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 tempfile
-import os
import time
from qemu_test import QemuSystemTest, skipIfMissingCommands
from qemu_test.ports import Ports
+
class MigrationTest(QemuSystemTest):
timeout = 10
diff --git a/tests/functional/test_mips64_malta.py b/tests/functional/test_mips64_malta.py
new file mode 100755
index 0000000..53c3e0c
--- /dev/null
+++ b/tests/functional/test_mips64_malta.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the big-endian 64-bit MIPS Malta board
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+from test_mips_malta import mips_check_wheezy
+
+
+class MaltaMachineConsole(LinuxKernelTest):
+
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '3e4ec154db080b3f1839f04dde83120654a33e5e1716863de576c47cb94f68f6')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='d98b953bb4a41c0fc0fd8d19bbc691c08989ac52568c1d3054d92dfd890d3f06')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/test_mips64el_malta.py
index a8da15a..3cc79b7 100755
--- a/tests/functional/test_mips64el_malta.py
+++ b/tests/functional/test_mips64el_malta.py
@@ -16,6 +16,8 @@ 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
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -90,6 +92,26 @@ class MaltaMachineConsole(LinuxKernelTest):
# Wait for VM to shut down gracefully
self.vm.wait()
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '5e8b725244c59745bb8b64f5d8f49f25fecfa549f3395fb6d19a3b9e5065b85b')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='7579f8b56c1187c7c04d0dc3c0c56c7a6314c5ddd3a9bf8803ecc7cf8a3be9f8')
+
@skipIfMissingImports('numpy', 'cv2')
class MaltaMachineFramebuffer(LinuxKernelTest):
@@ -133,8 +155,10 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
framebuffer_ready = 'Console: switching to colour frame buffer device'
self.wait_for_console_pattern(framebuffer_ready)
self.vm.cmd('human-monitor-command', command_line='stop')
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screendump_path)
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screendump_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
logger = logging.getLogger('framebuffer')
match_threshold = 0.95
diff --git a/tests/functional/test_mips64el_replay.py b/tests/functional/test_mips64el_replay.py
index 4f63d7f..26a6ccf 100755
--- a/tests/functional/test_mips64el_replay.py
+++ b/tests/functional/test_mips64el_replay.py
@@ -4,11 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-import logging
-
-from qemu_test import Asset, exec_command_and_wait_for_pattern
-from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
+from qemu_test import Asset, skipUntrustedTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_mips_malta.py b/tests/functional/test_mips_malta.py
index 9697c7d..30279f0 100755
--- a/tests/functional/test_mips_malta.py
+++ b/tests/functional/test_mips_malta.py
@@ -6,10 +6,91 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import LinuxKernelTest, Asset
+import os
+
+from qemu_test import LinuxKernelTest, Asset, wait_for_console_pattern
from qemu_test import exec_command_and_wait_for_pattern
+def mips_run_common_commands(test, prompt='#'):
+ exec_command_and_wait_for_pattern(test,
+ 'uname -m',
+ 'mips')
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'timer')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'ata_piix')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'rtc')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'input')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'fb')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : ata_piix')
+ wait_for_console_pattern(test, prompt)
+
+def mips_check_wheezy(test, kernel_path, image_path, kernel_command_line,
+ dl_file, hsum, nic='pcnet', cpuinfo='MIPS 24Kc'):
+ test.require_netdev('user')
+ test.require_device(nic)
+ test.set_machine('malta')
+
+ port=8080
+ test.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line,
+ '-drive', 'file=%s,snapshot=on' % image_path,
+ '-netdev', 'user,id=n1' +
+ ',tftp=' + os.path.basename(kernel_path) +
+ ',hostfwd=tcp:127.0.0.1:0-:%d' % port,
+ '-device', f'{nic},netdev=n1',
+ '-no-reboot')
+ test.vm.set_console()
+ test.vm.launch()
+
+ wait_for_console_pattern(test, 'login: ', 'Oops')
+ exec_command_and_wait_for_pattern(test, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(test, 'root', ':~# ')
+ mips_run_common_commands(test)
+
+ exec_command_and_wait_for_pattern(test, 'cd /', '# ')
+ test.check_http_download(dl_file, hsum, port,
+ pythoncmd='python -m SimpleHTTPServer')
+
+ exec_command_and_wait_for_pattern(test, 'cat /proc/cpuinfo', cpuinfo)
+ exec_command_and_wait_for_pattern(test, 'cat /proc/devices', 'usb')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/ioports',
+ ' : piix4_smbus')
+ 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')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/mtd', 'YAMON')
+ # Empty 'Board Config' (64KB)
+ exec_command_and_wait_for_pattern(test, 'md5sum /dev/mtd2ro',
+ '0dfbe8aa4c20b52e1b8bf3cb6cbdf193')
+
+
class MaltaMachineConsole(LinuxKernelTest):
ASSET_KERNEL_2_63_2 = Asset(
@@ -70,7 +151,8 @@ class MaltaMachineConsole(LinuxKernelTest):
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
'BogoMIPS')
exec_command_and_wait_for_pattern(self, 'uname -a',
- 'Debian')
+ '4.5.0-2-4kc-malta #1 Debian')
+ mips_run_common_commands(self)
exec_command_and_wait_for_pattern(self, 'ip link set eth0 up',
'eth0: link up')
@@ -89,6 +171,26 @@ class MaltaMachineConsole(LinuxKernelTest):
# Wait for VM to shut down gracefully
self.vm.wait()
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ '0377fcda31299213c10b8e5babe7260ef99188b3ae1aca6f56594abb71e7f67e')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, nic='e1000',
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='ff0c0369143d9bbb9a6e6bc79322a2be535619df639e84103237f406e87493dc')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/test_mips_replay.py b/tests/functional/test_mips_replay.py
index eda031c..4327481 100755
--- a/tests/functional/test_mips_replay.py
+++ b/tests/functional/test_mips_replay.py
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipSlowTest, exec_command_and_wait_for_pattern
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_mipsel_malta.py b/tests/functional/test_mipsel_malta.py
index fe9c3a1..9ee2884 100755
--- a/tests/functional/test_mipsel_malta.py
+++ b/tests/functional/test_mipsel_malta.py
@@ -13,6 +13,8 @@ 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
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -57,6 +59,26 @@ class MaltaMachineConsole(LinuxKernelTest):
def test_mips_malta32el_nanomips_64k_dbg(self):
self.do_test_mips_malta32el_nanomips(self.ASSET_KERNEL_64K)
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ 'dc8a3648305b0201ca7a5cd135fe2890067a65d93c38728022bb0e656ad2bf9a')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line,
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='9fc9f250ed56a74e35e704ddfd5a1c5a5625adefc5c9da91f649288d3ca000f0')
+
class MaltaMachineYAMON(QemuSystemTest):
diff --git a/tests/functional/test_mipsel_replay.py b/tests/functional/test_mipsel_replay.py
index 0a330de..5f4796c 100644
--- a/tests/functional/test_mipsel_replay.py
+++ b/tests/functional/test_mipsel_replay.py
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, wait_for_console_pattern, skipSlowTest
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_pc_cpu_hotplug_props.py b/tests/functional/test_pc_cpu_hotplug_props.py
index 9d5a37c..2bed8ad 100755
--- a/tests/functional/test_pc_cpu_hotplug_props.py
+++ b/tests/functional/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_ppc64_hv.py b/tests/functional/test_ppc64_hv.py
index 1920e91..d87f440 100755
--- a/tests/functional/test_ppc64_hv.py
+++ b/tests/functional/test_ppc64_hv.py
@@ -9,14 +9,14 @@
# 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 subprocess
+
+from datetime import datetime
from qemu_test import QemuSystemTest, Asset
from qemu_test import wait_for_console_pattern, exec_command
from qemu_test import skipIfMissingCommands, skipBigDataTest
from qemu_test import exec_command_and_wait_for_pattern
-import os
-import time
-import subprocess
-from datetime import datetime
# Alpine is a light weight distro that supports QEMU. These tests boot
# that on the machine then run a QEMU guest inside it in KVM mode,
diff --git a/tests/functional/test_ppc64_pseries.py b/tests/functional/test_ppc64_pseries.py
index fdc404e..6705793 100755
--- a/tests/functional/test_ppc64_pseries.py
+++ b/tests/functional/test_ppc64_pseries.py
@@ -63,6 +63,7 @@ class pseriesMachine(QemuSystemTest):
wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_ppc64_linux_smt_boot(self):
+ self.set_machine('pseries')
self.vm.add_args('-smp', '4,threads=4')
self.do_test_ppc64_linux_boot()
console_pattern = 'CPU maps initialized for 4 threads per core'
diff --git a/tests/functional/test_ppc64_reverse_debug.py b/tests/functional/test_ppc64_reverse_debug.py
new file mode 100755
index 0000000..5931ade
--- /dev/null
+++ b/tests/functional/test_ppc64_reverse_debug.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# 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 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()
+
+ @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()
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff --git a/tests/functional/test_s390x_topology.py b/tests/functional/test_s390x_topology.py
index eefd972..1b5dc65 100755
--- a/tests/functional/test_s390x_topology.py
+++ b/tests/functional/test_s390x_topology.py
@@ -217,12 +217,12 @@ class S390CPUTopology(QemuSystemTest):
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'vertical')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
@@ -283,7 +283,7 @@ class S390CPUTopology(QemuSystemTest):
self.check_polarization('vertical:high')
self.check_topology(0, 0, 0, 0, 'high', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_polarization("horizontal")
self.check_topology(0, 0, 0, 0, 'high', False)
@@ -310,11 +310,11 @@ class S390CPUTopology(QemuSystemTest):
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("vertical:high")
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
@@ -360,7 +360,7 @@ class S390CPUTopology(QemuSystemTest):
self.check_topology(0, 0, 0, 0, 'high', True)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
diff --git a/tests/functional/test_s390x_tuxrun.py b/tests/functional/test_s390x_tuxrun.py
index a7db4bf..8df3c68 100755
--- a/tests/functional/test_s390x_tuxrun.py
+++ b/tests/functional/test_s390x_tuxrun.py
@@ -24,6 +24,7 @@ class TuxRunS390xTest(TuxRunBaselineTest):
'bff7971fc2fef56372d98afe4557b82fd0a785a241e44c29b058e577ad1bbb44')
def test_s390(self):
+ self.set_machine('s390-ccw-virtio')
self.wait_for_shutdown=False
self.common_tuxrun(kernel_asset=self.ASSET_S390X_KERNEL,
rootfs_asset=self.ASSET_S390X_ROOTFS,
diff --git a/tests/functional/test_sparc64_tuxrun.py b/tests/functional/test_sparc64_tuxrun.py
index 3be08d6..0d7b43d 100755
--- a/tests/functional/test_sparc64_tuxrun.py
+++ b/tests/functional/test_sparc64_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_vnc.py b/tests/functional/test_vnc.py
index 8c9953b..f1dd159 100755
--- a/tests/functional/test_vnc.py
+++ b/tests/functional/test_vnc.py
@@ -11,12 +11,12 @@
# later. See the COPYING file in the top-level directory.
import socket
-from typing import List
-from qemu.machine.machine import VMLaunchFailure
+from qemu.machine.machine import VMLaunchFailure
from qemu_test import QemuSystemTest
from qemu_test.ports import Ports
+
VNC_ADDR = '127.0.0.1'
def check_connect(port: int) -> bool:
@@ -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()
@@ -55,11 +56,14 @@ class Vnc(QemuSystemTest):
except VMLaunchFailure as excp:
if "-vnc: invalid option" in excp.output:
self.skipTest("VNC support not available")
+ elif "Cipher backend does not support DES algorithm" in excp.output:
+ self.skipTest("No cryptographic backend available")
else:
self.log.info("unhandled launch failure: %s", excp.output)
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'])
@@ -72,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'])
@@ -101,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/test_x86_64_kvm_xen.py b/tests/functional/test_x86_64_kvm_xen.py
index c6abf6b..a5d4450 100755
--- a/tests/functional/test_x86_64_kvm_xen.py
+++ b/tests/functional/test_x86_64_kvm_xen.py
@@ -11,8 +11,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu.machine import machine
from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
diff --git a/tests/functional/test_x86_64_replay.py b/tests/functional/test_x86_64_replay.py
index 180f23a..27287d4 100755
--- a/tests/functional/test_x86_64_replay.py
+++ b/tests/functional/test_x86_64_replay.py
@@ -5,30 +5,53 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipFlakyTest
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipFlakyTest, get_qemu_img
from replay_kernel import ReplayKernelBase
class X86Replay(ReplayKernelBase):
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/29/Everything/x86_64/os/images/pxeboot/vmlinuz'),
- '8f237d84712b1b411baf3af2aeaaee10b9aae8e345ec265b87ab3a39639eb143')
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/bzImage',
+ 'f57bfc6553bcd6e0a54aab86095bf642b33b5571d14e3af1731b18c87ed5aef8')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/rootfs.ext4.zst',
+ '4b8b2a99117519c5290e1202cb36eb6c7aaba92b357b5160f5970cf5fb78a751')
- def do_test_x86(self, machine):
+ def do_test_x86(self, machine, blkdevice, devroot):
+ self.require_netdev('user')
self.set_machine(machine)
+ self.cpu="Nehalem"
kernel_path = self.ASSET_KERNEL.fetch()
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', '%s,drive=hd0-rr' % blkdevice,
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ f"console=ttyS0 root=/dev/{devroot}")
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
+ args=args)
@skipFlakyTest('https://gitlab.com/qemu-project/qemu/-/issues/2094')
def test_pc(self):
- self.do_test_x86('pc')
+ self.do_test_x86('pc', 'virtio-blk', 'vda')
def test_q35(self):
- self.do_test_x86('q35')
+ self.do_test_x86('q35', 'ide-hd', 'sda')
if __name__ == '__main__':
diff --git a/tests/functional/test_x86_64_reverse_debug.py b/tests/functional/test_x86_64_reverse_debug.py
new file mode 100755
index 0000000..d713e91
--- /dev/null
+++ b/tests/functional/test_x86_64_reverse_debug.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+#
+# 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 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()
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()