* Convert more avocado tests to the functional framework

* Fix the broken aarch64_tcg_plugins test
 * Add test for 64-bit mac99 machine
 * Add a Linux-based test for the 40p machine
 * Fix issues with record/replay of some s390x instructions
 * Fix node.js crashes on emulated s390x due to a bug in the MVC instruction
 * Enable virtio-balloon-pci and virtio-mem-pci on s390x
 * Fix a libslirp v4.9.0 compilation problem
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmebewIRHHRodXRoQHJl
 ZGhhdC5jb20ACgkQLtnXdP5wLbUfZQ//WHrZNVQNe0d+wOtAa5Zj4X9RpadHeGO9
 WCKtBWZ1tDADHiVkZzU6L6q/LYM5FcAOE+Kah/xr8rtf6he+LCYQ0RDHbgY6/oUE
 t9TkIeph59+MMvBXWJ8flngaoVtxe8l2aYem8wk3ATPZtHyMQAZ5PAjY3+WYQAGc
 gm13k1AMD4mA6mBUOs67QSitTqBQsunKpb1IvpyBjtv9NBl61L8h5hWn0bsxa8yC
 3KKZhw6Nclc8RVe33e6ZDrHrBi9klORd6Z+7fJ4w8Yj+C48ogfbQx+Zvb82jXhRe
 2qGdVb6cF7LVQ5D3pECBK7yo4Lkd7MYnNvn+EmbTXhj1y5MSPdokP6k0ZWkhhkCP
 2kIY0o5tFipdxkdDpCptU3gYJLdQFbNX2MqDFY0KeurLDGe4o6jIoRNmdZ67TJei
 zleLlcEatoyRqpCKqTNMDVeWgza3ngykhiQIrG9PMPCRQET0N4qY6db35hzDujLI
 NVuI1traCLawfCDYiMnU59dOxWSHy1bwSfnUxhZ92+Fl3AOb6c6PzhpkIGl/grwT
 8T8EcjFyA4hpaHHKjCeNgSrKt9N0Ka2G3l9oF8eWwJm4KAlwtYBDvfVb+juGBP9+
 8gW0lXA8tYy/P5XgPQ0N5Z8coc1xUrYBhC7v70ud3ponMmmTdhRnosey2cOFUGsN
 /U7avgXIm0Q=
 =rEzl
 -----END PGP SIGNATURE-----

Merge tag 'pull-request-2025-01-30' of https://gitlab.com/thuth/qemu into staging

* Convert more avocado tests to the functional framework
* Fix the broken aarch64_tcg_plugins test
* Add test for 64-bit mac99 machine
* Add a Linux-based test for the 40p machine
* Fix issues with record/replay of some s390x instructions
* Fix node.js crashes on emulated s390x due to a bug in the MVC instruction
* Enable virtio-balloon-pci and virtio-mem-pci on s390x
* Fix a libslirp v4.9.0 compilation problem

# -----BEGIN PGP SIGNATURE-----
#
# iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmebewIRHHRodXRoQHJl
# ZGhhdC5jb20ACgkQLtnXdP5wLbUfZQ//WHrZNVQNe0d+wOtAa5Zj4X9RpadHeGO9
# WCKtBWZ1tDADHiVkZzU6L6q/LYM5FcAOE+Kah/xr8rtf6he+LCYQ0RDHbgY6/oUE
# t9TkIeph59+MMvBXWJ8flngaoVtxe8l2aYem8wk3ATPZtHyMQAZ5PAjY3+WYQAGc
# gm13k1AMD4mA6mBUOs67QSitTqBQsunKpb1IvpyBjtv9NBl61L8h5hWn0bsxa8yC
# 3KKZhw6Nclc8RVe33e6ZDrHrBi9klORd6Z+7fJ4w8Yj+C48ogfbQx+Zvb82jXhRe
# 2qGdVb6cF7LVQ5D3pECBK7yo4Lkd7MYnNvn+EmbTXhj1y5MSPdokP6k0ZWkhhkCP
# 2kIY0o5tFipdxkdDpCptU3gYJLdQFbNX2MqDFY0KeurLDGe4o6jIoRNmdZ67TJei
# zleLlcEatoyRqpCKqTNMDVeWgza3ngykhiQIrG9PMPCRQET0N4qY6db35hzDujLI
# NVuI1traCLawfCDYiMnU59dOxWSHy1bwSfnUxhZ92+Fl3AOb6c6PzhpkIGl/grwT
# 8T8EcjFyA4hpaHHKjCeNgSrKt9N0Ka2G3l9oF8eWwJm4KAlwtYBDvfVb+juGBP9+
# 8gW0lXA8tYy/P5XgPQ0N5Z8coc1xUrYBhC7v70ud3ponMmmTdhRnosey2cOFUGsN
# /U7avgXIm0Q=
# =rEzl
# -----END PGP SIGNATURE-----
# gpg: Signature made Thu 30 Jan 2025 08:13:38 EST
# gpg:                using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5
# gpg:                issuer "thuth@redhat.com"
# gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full]
# gpg:                 aka "Thomas Huth <thuth@redhat.com>" [full]
# gpg:                 aka "Thomas Huth <huth@tuxfamily.org>" [full]
# gpg:                 aka "Thomas Huth <th.huth@posteo.de>" [unknown]
# Primary key fingerprint: 27B8 8847 EEE0 2501 18F3  EAB9 2ED9 D774 FE70 2DB5

* tag 'pull-request-2025-01-30' of https://gitlab.com/thuth/qemu:
  net/slirp: libslirp 4.9.0 compatibility
  tests/functional/test_mips_malta: Convert the mips big endian replay tests
  tests/functional/test_mips64el_malta: Convert the mips64el replay tests
  tests/functional/test_mipsel_malta: Convert the mipsel replay tests
  tests/functional: Add the ReplayKernelBase class
  tests/functional: Add a decorator for skipping long running tests
  tests/functional: Extend PPC 40p test with Linux boot
  s390x/s390-virtio-ccw: Support plugging PCI-based virtio memory devices
  virtio-mem-pci: Allow setting nvectors, so we can use MSI-X
  virtio-balloon-pci: Allow setting nvectors, so we can use MSI-X
  hw/s390x/s390-virtio-ccw: Fix a record/replay deadlock
  tests/tcg/s390x: Test modifying code using the MVC instruction
  target/s390x: Fix MVC not always invalidating translation blocks
  target/s390x: Fix PPNO execution with icount
  tests/functional/test_mips_malta: Fix comment about endianness of the test
  tests/functional: Add a ppc64 mac99 test
  tests/functional: Fix the aarch64_tcg_plugins test
  tests/functional: Convert the migration avocado test
  tests/functional: Fix broken decorators with lamda functions
  tests/functional/qemu_test/decorators: Fix bad check for imports

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2025-01-30 10:29:40 -05:00
commit e60938852f
28 changed files with 685 additions and 358 deletions

View file

@ -1453,6 +1453,7 @@ F: include/hw/pci-host/uninorth.h
F: include/hw/input/adb*
F: pc-bios/qemu_vga.ndrv
F: tests/functional/test_ppc_mac.py
F: tests/functional/test_ppc64_mac99.py
Old World (g3beige)
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
@ -3461,6 +3462,7 @@ F: include/migration/
F: include/qemu/userfaultfd.h
F: migration/
F: scripts/vmstate-static-checker.py
F: tests/functional/test_migration.py
F: tests/vmstate-static-checker-data/
F: tests/qtest/migration/
F: tests/qtest/migration-*
@ -3631,6 +3633,7 @@ F: stubs/replay.c
F: tests/avocado/replay_kernel.py
F: tests/avocado/replay_linux.py
F: tests/avocado/reverse_debugging.py
F: tests/functional/*replay*.py
F: qapi/replay.json
IOVA Tree

View file

@ -351,5 +351,13 @@ the code snippet below:
Tests should not live in this state forever and should either be fixed
or eventually removed.
QEMU_TEST_ALLOW_SLOW
^^^^^^^^^^^^^^^^^^^^
Tests that have a very long runtime and might run into timeout issues
e.g. if the QEMU binary has been compiled with debugging options enabled.
To avoid these timeout issues by default and to save some precious CPU
cycles during normal testing, such tests are disabled by default unless
the QEMU_TEST_ALLOW_SLOW environment variable has been set.
.. _unittest: https://docs.python.org/3/library/unittest.html

View file

@ -38,6 +38,10 @@
GlobalProperty hw_compat_9_2[] = {
{"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"},
{ "virtio-balloon-pci", "vectors", "0" },
{ "virtio-balloon-pci-transitional", "vectors", "0" },
{ "virtio-balloon-pci-non-transitional", "vectors", "0" },
{ "virtio-mem-pci", "vectors", "0" },
};
const size_t hw_compat_9_2_len = G_N_ELEMENTS(hw_compat_9_2);

View file

@ -48,6 +48,7 @@
#include "kvm/kvm_s390x.h"
#include "hw/virtio/virtio-md-pci.h"
#include "hw/s390x/virtio-ccw-md.h"
#include "system/replay.h"
#include CONFIG_DEVICES
static Error *pv_mig_blocker;
@ -454,6 +455,18 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
CPUState *cs, *t;
S390CPU *cpu;
/*
* Temporarily drop the record/replay mutex to let rr_cpu_thread_fn()
* process the run_on_cpu() requests below. This is safe, because at this
* point one of the following is true:
* - All CPU threads are not running, either because the machine is being
* initialized, or because the guest requested a reset using diag 308.
* There is no risk to desync the record/replay state.
* - A snapshot is about to be loaded. The record/replay state consistency
* is not important.
*/
replay_mutex_unlock();
/* get the reset parameters, reset them once done */
s390_ipl_get_reset_request(&cs, &reset_type);
@ -533,7 +546,7 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
* went wrong.
*/
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu);
return;
goto out_lock;
}
run_on_cpu(cs, s390_do_cpu_load_normal, RUN_ON_CPU_NULL);
@ -546,6 +559,15 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
}
s390_ipl_clear_reset_request();
out_lock:
/*
* Re-take the record/replay mutex, temporarily dropping the BQL in order
* to satisfy the ordering requirements.
*/
bql_unlock();
replay_mutex_lock();
bql_lock();
}
static void s390_machine_device_pre_plug(HotplugHandler *hotplug_dev,
@ -554,8 +576,7 @@ static void s390_machine_device_pre_plug(HotplugHandler *hotplug_dev,
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_pre_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
error_setg(errp,
"PCI-attached virtio based memory devices not supported");
virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
}
}
@ -566,7 +587,8 @@ static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
s390_cpu_plug(hotplug_dev, dev, errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW) ||
object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
/*
* At this point, the device is realized and set all memdevs mapped, so
* qemu_maxrampagesize() will pick up the page sizes of these memdevs
@ -580,7 +602,11 @@ static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
" initial memory");
return;
}
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
} else {
virtio_md_pci_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
}
}
}
@ -589,10 +615,12 @@ static void s390_machine_device_unplug_request(HotplugHandler *hotplug_dev,
{
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
error_setg(errp, "CPU hot unplug not supported on this machine");
return;
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_unplug_request(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev),
errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
virtio_md_pci_unplug_request(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev),
errp);
}
}
@ -601,6 +629,8 @@ static void s390_machine_device_unplug(HotplugHandler *hotplug_dev,
{
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_unplug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
virtio_md_pci_unplug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
}
}

View file

@ -35,11 +35,22 @@ struct VirtIOBalloonPCI {
VirtIOBalloon vdev;
};
static const Property virtio_balloon_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
};
static void virtio_balloon_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&dev->vdev);
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
vpci_dev->nvectors = 2;
}
vpci_dev->class_code = PCI_CLASS_OTHERS;
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
}
@ -55,6 +66,7 @@ static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data)
pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
pcidev_k->class_id = PCI_CLASS_OTHERS;
device_class_set_props(dc, virtio_balloon_properties);
}
static void virtio_balloon_pci_instance_init(Object *obj)

View file

@ -22,6 +22,10 @@ static void virtio_mem_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
VirtIOMEMPCI *mem_pci = VIRTIO_MEM_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&mem_pci->vdev);
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
vpci_dev->nvectors = 2;
}
virtio_pci_force_virtio_1(vpci_dev);
qdev_realize(vdev, BUS(&vpci_dev->bus), errp);
}
@ -152,6 +156,13 @@ static void virtio_mem_pci_set_requested_size(Object *obj, Visitor *v,
object_property_set(OBJECT(&pci_mem->vdev), name, v, errp);
}
static const Property virtio_mem_pci_class_properties[] = {
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors,
DEV_NVECTORS_UNSPECIFIED),
};
static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
@ -164,6 +175,7 @@ static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_MISC, dc->categories);
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
pcidev_k->class_id = PCI_CLASS_OTHERS;
device_class_set_props(dc, virtio_mem_pci_class_properties);
mdc->get_addr = virtio_mem_pci_get_addr;
mdc->set_addr = virtio_mem_pci_set_addr;

View file

@ -247,7 +247,14 @@ static void net_slirp_timer_mod(void *timer, int64_t expire_timer,
timer_mod(&t->timer, expire_timer);
}
static void net_slirp_register_poll_fd(int fd, void *opaque)
#if !SLIRP_CHECK_VERSION(4, 9, 0)
# define slirp_os_socket int
# define slirp_pollfds_fill_socket slirp_pollfds_fill
# define register_poll_socket register_poll_fd
# define unregister_poll_socket unregister_poll_fd
#endif
static void net_slirp_register_poll_sock(slirp_os_socket fd, void *opaque)
{
#ifdef WIN32
AioContext *ctxt = qemu_get_aio_context();
@ -260,7 +267,7 @@ static void net_slirp_register_poll_fd(int fd, void *opaque)
#endif
}
static void net_slirp_unregister_poll_fd(int fd, void *opaque)
static void net_slirp_unregister_poll_sock(slirp_os_socket fd, void *opaque)
{
#ifdef WIN32
if (WSAEventSelect(fd, NULL, 0) != 0) {
@ -286,8 +293,8 @@ static const SlirpCb slirp_cb = {
#endif
.timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_poll_fd,
.unregister_poll_fd = net_slirp_unregister_poll_fd,
.register_poll_socket = net_slirp_register_poll_sock,
.unregister_poll_socket = net_slirp_unregister_poll_sock,
.notify = net_slirp_notify,
};
@ -314,7 +321,7 @@ static int slirp_poll_to_gio(int events)
return ret;
}
static int net_slirp_add_poll(int fd, int events, void *opaque)
static int net_slirp_add_poll(slirp_os_socket fd, int events, void *opaque)
{
GArray *pollfds = opaque;
GPollFD pfd = {
@ -363,7 +370,7 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data)
switch (poll->state) {
case MAIN_LOOP_POLL_FILL:
slirp_pollfds_fill(s->slirp, &poll->timeout,
slirp_pollfds_fill_socket(s->slirp, &poll->timeout,
net_slirp_add_poll, poll->pollfds);
break;
case MAIN_LOOP_POLL_OK:
@ -629,7 +636,9 @@ static int net_slirp_init(NetClientState *peer, const char *model,
s = DO_UPCAST(SlirpState, nc, nc);
cfg.version = SLIRP_CHECK_VERSION(4,7,0) ? 4 : 1;
cfg.version =
SLIRP_CHECK_VERSION(4, 9, 0) ? 6 :
SLIRP_CHECK_VERSION(4, 7, 0) ? 4 : 1;
cfg.restricted = restricted;
cfg.in_enabled = ipv4;
cfg.vnetwork = net;

View file

@ -1012,7 +1012,7 @@
D(0xb92e, KM, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KM)
D(0xb92f, KMC, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KMC)
D(0xb929, KMA, RRF_b, MSA8, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KMA)
D(0xb93c, PPNO, RRE, MSA5, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_PPNO)
E(0xb93c, PPNO, RRE, MSA5, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_PPNO, IF_IO)
D(0xb93e, KIMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KIMD)
D(0xb93f, KLMD, RRE, MSA, 0, 0, 0, 0, msa, 0, S390_FEAT_TYPE_KLMD)

View file

@ -149,7 +149,7 @@ static inline int s390_probe_access(CPUArchState *env, target_ulong addr,
int mmu_idx, bool nonfault,
void **phost, uintptr_t ra)
{
int flags = probe_access_flags(env, addr, 0, access_type, mmu_idx,
int flags = probe_access_flags(env, addr, size, access_type, mmu_idx,
nonfault, phost, ra);
if (unlikely(flags & TLB_INVALID_MASK)) {

View file

@ -1,135 +0,0 @@
# Migration test
#
# Copyright (c) 2019 Red Hat, Inc.
#
# Authors:
# Cleber Rosa <crosa@redhat.com>
# Caio Carrara <ccarrara@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 tempfile
import os
from avocado_qemu import QemuSystemTest
from avocado import skipUnless
from avocado.utils.network import ports
from avocado.utils import wait
from avocado.utils.path import find_command
class MigrationTest(QemuSystemTest):
"""
:avocado: tags=migration
"""
timeout = 10
@staticmethod
def migration_finished(vm):
return vm.cmd('query-migrate')['status'] in ('completed', 'failed')
def assert_migration(self, src_vm, dst_vm):
wait.wait_for(self.migration_finished,
timeout=self.timeout,
step=0.1,
args=(src_vm,))
wait.wait_for(self.migration_finished,
timeout=self.timeout,
step=0.1,
args=(dst_vm,))
self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
def do_migrate(self, dest_uri, src_uri=None):
dest_vm = self.get_vm('-incoming', dest_uri)
dest_vm.add_args('-nodefaults')
dest_vm.launch()
if src_uri is None:
src_uri = dest_uri
source_vm = self.get_vm()
source_vm.add_args('-nodefaults')
source_vm.launch()
source_vm.qmp('migrate', uri=src_uri)
self.assert_migration(source_vm, dest_vm)
def _get_free_port(self):
port = ports.find_free_port()
if port is None:
self.cancel('Failed to find a free port')
return port
def migration_with_tcp_localhost(self):
dest_uri = 'tcp:localhost:%u' % self._get_free_port()
self.do_migrate(dest_uri)
def migration_with_unix(self):
with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
dest_uri = 'unix:%s/qemu-test.sock' % socket_path
self.do_migrate(dest_uri)
@skipUnless(find_command('nc', default=False), "'nc' command not found")
def migration_with_exec(self):
"""The test works for both netcat-traditional and netcat-openbsd packages."""
free_port = self._get_free_port()
dest_uri = 'exec:nc -l localhost %u' % free_port
src_uri = 'exec:nc localhost %u' % free_port
self.do_migrate(dest_uri, src_uri)
@skipUnless('aarch64' in os.uname()[4], "host != target")
class Aarch64(MigrationTest):
"""
:avocado: tags=arch:aarch64
:avocado: tags=machine:virt
:avocado: tags=cpu:max
"""
def test_migration_with_tcp_localhost(self):
self.migration_with_tcp_localhost()
def test_migration_with_unix(self):
self.migration_with_unix()
def test_migration_with_exec(self):
self.migration_with_exec()
@skipUnless('x86_64' in os.uname()[4], "host != target")
class X86_64(MigrationTest):
"""
:avocado: tags=arch:x86_64
:avocado: tags=machine:pc
:avocado: tags=cpu:qemu64
"""
def test_migration_with_tcp_localhost(self):
self.migration_with_tcp_localhost()
def test_migration_with_unix(self):
self.migration_with_unix()
def test_migration_with_exec(self):
self.migration_with_exec()
@skipUnless('ppc64le' in os.uname()[4], "host != target")
class PPC64(MigrationTest):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
def test_migration_with_tcp_localhost(self):
self.migration_with_tcp_localhost()
def test_migration_with_unix(self):
self.migration_with_unix()
def test_migration_with_exec(self):
self.migration_with_exec()

View file

@ -144,51 +144,6 @@ class ReplayKernelNormal(ReplayKernelBase):
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
def test_mips_malta(self):
"""
:avocado: tags=arch:mips
:avocado: tags=machine:malta
:avocado: tags=endian:big
"""
deb_url = ('http://snapshot.debian.org/archive/debian/'
'20130217T032700Z/pool/main/l/linux-2.6/'
'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb')
deb_hash = 'a8cfc28ad8f45f54811fc6cf74fc43ffcfe0ba04'
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
kernel_path = self.extract_from_deb(deb_path,
'/boot/vmlinux-2.6.32-5-4kc-malta')
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
def test_mips64el_malta(self):
"""
This test requires the ar tool to extract "data.tar.gz" from
the Debian package.
The kernel can be rebuilt using this Debian kernel source [1] and
following the instructions on [2].
[1] http://snapshot.debian.org/package/linux-2.6/2.6.32-48/
#linux-source-2.6.32_2.6.32-48
[2] https://kernel-team.pages.debian.net/kernel-handbook/
ch-common-tasks.html#s-common-official
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
"""
deb_url = ('http://snapshot.debian.org/archive/debian/'
'20130217T032700Z/pool/main/l/linux-2.6/'
'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb')
deb_hash = '1aaec92083bf22fda31e0d27fa8d9a388e5fc3d5'
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
kernel_path = self.extract_from_deb(deb_path,
'/boot/vmlinux-2.6.32-5-5kc-malta')
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
def test_aarch64_virt(self):
"""
:avocado: tags=arch:aarch64
@ -455,123 +410,3 @@ class ReplayKernelNormal(ReplayKernelBase):
'/qac-best-of-multiarch/download/day02.tar.xz')
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf')
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
class ReplayKernelSlow(ReplayKernelBase):
# Override the timeout, because this kernel includes an inner
# loop which is executed with TB recompilings during replay,
# making it very slow.
timeout = 180
def test_mips_malta_cpio(self):
"""
:avocado: tags=arch:mips
:avocado: tags=machine:malta
:avocado: tags=endian:big
:avocado: tags=slowness:high
"""
deb_url = ('http://snapshot.debian.org/archive/debian/'
'20160601T041800Z/pool/main/l/linux/'
'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb')
deb_hash = 'a3c84f3e88b54e06107d65a410d1d1e8e0f340f8'
deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
kernel_path = self.extract_from_deb(deb_path,
'/boot/vmlinux-4.5.0-2-4kc-malta')
initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
'8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/'
'mips/rootfs.cpio.gz')
initrd_hash = 'bf806e17009360a866bf537f6de66590de349a99'
initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
initrd_path = self.workdir + "rootfs.cpio"
archive.gzip_uncompress(initrd_path_gz, initrd_path)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 console=tty '
'rdinit=/sbin/init noreboot')
console_pattern = 'Boot successful.'
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
args=('-initrd', initrd_path))
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
def test_mips64el_malta_5KEc_cpio(self):
"""
:avocado: tags=arch:mips64el
:avocado: tags=machine:malta
:avocado: tags=endian:little
:avocado: tags=slowness:high
:avocado: tags=cpu:5KEc
"""
kernel_url = ('https://github.com/philmd/qemu-testing-blob/'
'raw/9ad2df38/mips/malta/mips64el/'
'vmlinux-3.19.3.mtoman.20150408')
kernel_hash = '00d1d268fb9f7d8beda1de6bebcc46e884d71754'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
initrd_url = ('https://github.com/groeck/linux-build-test/'
'raw/8584a59e/rootfs/'
'mipsel64/rootfs.mipsel64r1.cpio.gz')
initrd_hash = '1dbb8a396e916847325284dbe2151167'
initrd_path_gz = self.fetch_asset(initrd_url, algorithm='md5',
asset_hash=initrd_hash)
initrd_path = self.workdir + "rootfs.cpio"
archive.gzip_uncompress(initrd_path_gz, initrd_path)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 console=tty '
'rdinit=/sbin/init noreboot')
console_pattern = 'Boot successful.'
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
args=('-initrd', initrd_path))
def do_test_mips_malta32el_nanomips(self, kernel_path_xz):
kernel_path = self.workdir + "kernel"
with lzma.open(kernel_path_xz, 'rb') as f_in:
with open(kernel_path, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'mem=256m@@0x0 '
'console=ttyS0')
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
def test_mips_malta32el_nanomips_4k(self):
"""
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
:avocado: tags=cpu:I7200
"""
kernel_url = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page4k.xz')
kernel_hash = '477456aafd2a0f1ddc9482727f20fe9575565dd6'
kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.do_test_mips_malta32el_nanomips(kernel_path_xz)
def test_mips_malta32el_nanomips_16k_up(self):
"""
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
:avocado: tags=cpu:I7200
"""
kernel_url = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page16k_up.xz')
kernel_hash = 'e882868f944c71c816e832e2303b7874d044a7bc'
kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.do_test_mips_malta32el_nanomips(kernel_path_xz)
def test_mips_malta32el_nanomips_64k_dbg(self):
"""
:avocado: tags=arch:mipsel
:avocado: tags=machine:malta
:avocado: tags=endian:little
:avocado: tags=cpu:I7200
"""
kernel_url = ('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page64k_dbg.xz')
kernel_hash = '18d1c68f2e23429e266ca39ba5349ccd0aeb7180'
kernel_path_xz = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.do_test_mips_malta32el_nanomips(kernel_path_xz)

View file

@ -35,12 +35,14 @@ test_timeouts = {
'arm_sx1' : 360,
'intel_iommu': 300,
'mips_malta' : 120,
'mipsel_replay' : 480,
'netdev_ethtool' : 180,
'ppc_40p' : 240,
'ppc64_hv' : 1000,
'ppc64_powernv' : 480,
'ppc64_pseries' : 480,
'ppc64_tuxrun' : 420,
'ppc64_mac99' : 120,
'riscv64_tuxrun' : 120,
's390x_ccw_virtio' : 420,
'sh4_tuxrun' : 240,
@ -59,6 +61,10 @@ tests_generic_linuxuser = [
tests_generic_bsduser = [
]
tests_aarch64_system_quick = [
'migration',
]
tests_aarch64_system_thorough = [
'aarch64_aspeed',
'aarch64_raspi3',
@ -68,16 +74,25 @@ tests_aarch64_system_thorough = [
'aarch64_sbsaref',
'aarch64_sbsaref_alpine',
'aarch64_sbsaref_freebsd',
'aarch64_tcg_plugins',
'aarch64_tuxrun',
'aarch64_virt',
'aarch64_xlnx_versal',
'multiprocess',
]
tests_alpha_system_quick = [
'migration',
]
tests_alpha_system_thorough = [
'alpha_clipper',
]
tests_arm_system_quick = [
'migration',
]
tests_arm_system_thorough = [
'arm_aspeed_ast1030',
'arm_aspeed_palmetto',
@ -114,6 +129,10 @@ tests_hppa_system_quick = [
'hppa_seabios',
]
tests_i386_system_quick = [
'migration',
]
tests_i386_system_thorough = [
'i386_tuxrun',
]
@ -139,11 +158,13 @@ tests_microblazeel_system_thorough = [
tests_mips_system_thorough = [
'mips_malta',
'mips_replay',
'mips_tuxrun',
]
tests_mipsel_system_thorough = [
'mipsel_malta',
'mipsel_replay',
'mipsel_tuxrun',
]
@ -155,6 +176,7 @@ tests_mips64el_system_thorough = [
'mips64el_fuloong2e',
'mips64el_loongson3v',
'mips64el_malta',
'mips64el_replay',
'mips64el_tuxrun',
]
@ -163,6 +185,7 @@ tests_or1k_system_thorough = [
]
tests_ppc_system_quick = [
'migration',
'ppc_74xx',
]
@ -177,15 +200,21 @@ tests_ppc_system_thorough = [
'ppc_virtex_ml507',
]
tests_ppc64_system_quick = [
'migration',
]
tests_ppc64_system_thorough = [
'ppc64_e500',
'ppc64_hv',
'ppc64_powernv',
'ppc64_pseries',
'ppc64_tuxrun',
'ppc64_mac99',
]
tests_riscv32_system_quick = [
'migration',
'riscv_opensbi',
]
@ -194,6 +223,7 @@ tests_riscv32_system_thorough = [
]
tests_riscv64_system_quick = [
'migration',
'riscv_opensbi',
]
@ -220,10 +250,18 @@ tests_sh4eb_system_thorough = [
'sh4eb_r2d',
]
tests_sparc_system_quick = [
'migration',
]
tests_sparc_system_thorough = [
'sparc_sun4m',
]
tests_sparc64_system_quick = [
'migration',
]
tests_sparc64_system_thorough = [
'sparc64_sun4u',
'sparc64_tuxrun',
@ -232,6 +270,7 @@ tests_sparc64_system_thorough = [
tests_x86_64_system_quick = [
'cpu_queries',
'mem_addr_space',
'migration',
'pc_cpu_hotplug_props',
'virtio_version',
'x86_cpu_model_versions',

View file

@ -14,7 +14,7 @@ from .cmd import is_readable_executable_file, \
from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
from .linuxkernel import LinuxKernelTest
from .decorators import skipIfMissingCommands, skipIfNotMachine, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \
skipIfMissingImports
from .archive import archive_extract
from .uncompress import uncompress

View file

@ -2,6 +2,7 @@
#
# Decorators useful in functional tests
import importlib
import os
import platform
from unittest import skipUnless
@ -16,14 +17,13 @@ Example:
@skipIfMissingCommands("mkisofs", "losetup")
'''
def skipIfMissingCommands(*args):
def has_cmds(cmdlist):
for cmd in cmdlist:
has_cmds = True
for cmd in args:
if not which(cmd):
return False
return True
has_cmds = False
break
return skipUnless(lambda: has_cmds(args),
'required command(s) "%s" not installed' %
return skipUnless(has_cmds, 'required command(s) "%s" not installed' %
", ".join(args))
'''
@ -35,7 +35,7 @@ Example
@skipIfNotMachine("x86_64", "aarch64")
'''
def skipIfNotMachine(*args):
return skipUnless(lambda: platform.machine() in args,
return skipUnless(platform.machine() in args,
'not running on one of the required machine(s) "%s"' %
", ".join(args))
@ -86,6 +86,20 @@ def skipBigDataTest():
return skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'),
'Test requires large host storage space')
'''
Decorator to skip execution of tests which have a really long
runtime (and might e.g. time out if QEMU has been compiled with
debugging enabled) unless the $QEMU_TEST_ALLOW_SLOW
environment variable is set
Example:
@skipSlowTest()
'''
def skipSlowTest():
return skipUnless(os.getenv('QEMU_TEST_ALLOW_SLOW'),
'Test has a very long runtime and might time out')
'''
Decorator to skip execution of a test if the list
of python imports is not available.
@ -94,14 +108,13 @@ Example:
@skipIfMissingImports("numpy", "cv2")
'''
def skipIfMissingImports(*args):
def has_imports(importlist):
for impname in importlist:
has_imports = True
for impname in args:
try:
import impname
importlib.import_module(impname)
except ImportError:
return False
return True
has_imports = False
break
return skipUnless(lambda: has_imports(args),
'required import(s) "%s" not installed' %
return skipUnless(has_imports, 'required import(s) "%s" not installed' %
", ".join(args))

View file

@ -0,0 +1,84 @@
# Record/replay test that boots a Linux kernel
#
# Copyright (c) 2020 ISP RAS
#
# Author:
# Pavel Dovgalyuk <Pavel.Dovgaluk@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
import time
import subprocess
from qemu_test.linuxkernel import LinuxKernelTest
class ReplayKernelBase(LinuxKernelTest):
"""
Boots a Linux kernel in record mode and checks that the console
is operational and the kernel command line is properly passed
from QEMU to the kernel.
Then replays the same scenario and verifies, that QEMU correctly
terminates.
"""
timeout = 180
REPLAY_KERNEL_COMMAND_LINE = 'printk.time=1 panic=-1 '
def run_vm(self, kernel_path, kernel_command_line, console_pattern,
record, shift, args, replay_path):
# icount requires TCG to be available
self.require_accelerator('tcg')
logger = logging.getLogger('replay')
start_time = time.time()
vm = self.get_vm()
vm.set_console()
if record:
logger.info('recording the execution...')
mode = 'record'
else:
logger.info('replaying the execution...')
mode = 'replay'
vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
(shift, mode, replay_path),
'-kernel', kernel_path,
'-append', kernel_command_line,
'-net', 'none',
'-no-reboot')
if args:
vm.add_args(*args)
vm.launch()
self.wait_for_console_pattern(console_pattern, vm)
if record:
vm.shutdown()
logger.info('finished the recording with log size %s bytes'
% os.path.getsize(replay_path))
self.run_replay_dump(replay_path)
logger.info('successfully tested replay-dump.py')
else:
vm.wait()
logger.info('successfully finished the replay')
elapsed = time.time() - start_time
logger.info('elapsed time %.2f sec' % elapsed)
return elapsed
def run_replay_dump(self, replay_path):
try:
subprocess.check_call(["./scripts/replay-dump.py",
"-f", replay_path],
stdout=subprocess.DEVNULL)
except subprocess.CalledProcessError:
self.fail('replay-dump.py failed')
def run_rr(self, kernel_path, kernel_command_line, console_pattern,
shift=7, args=None):
replay_path = os.path.join(self.workdir, 'replay.bin')
t1 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
True, shift, args, replay_path)
t2 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
False, shift, args, replay_path)
logger = logging.getLogger('replay')
logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))

View file

@ -10,7 +10,7 @@
import os
from qemu_test import QemuSystemTest, Asset
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
@ -53,8 +53,7 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
def test_sbsaref_alpine_linux_max_pauth_impdef(self):
self.boot_alpine_linux("max,pauth-impdef=on")
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'),
'Test might timeout due to PAuth emulation')
@skipSlowTest() # Test might timeout due to PAuth emulation
def test_sbsaref_alpine_linux_max(self):
self.boot_alpine_linux("max")

View file

@ -10,9 +10,8 @@
import os
from qemu_test import QemuSystemTest, Asset
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
@ -50,13 +49,11 @@ class Aarch64SbsarefFreeBSD(QemuSystemTest):
def test_sbsaref_freebsd14_max_pauth_off(self):
self.boot_freebsd14("max,pauth=off")
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'),
'Test might timeout due to PAuth emulation')
@skipSlowTest() # Test might timeout due to PAuth emulation
def test_sbsaref_freebsd14_max_pauth_impdef(self):
self.boot_freebsd14("max,pauth-impdef=on")
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'),
'Test might timeout due to PAuth emulation')
@skipSlowTest() # Test might timeout due to PAuth emulation
def test_sbsaref_freebsd14_max(self):
self.boot_freebsd14("max")

View file

@ -15,6 +15,7 @@ import tempfile
import mmap
import re
from qemu.machine.machine import VMLaunchFailure
from qemu_test import LinuxKernelTest, Asset
@ -43,10 +44,12 @@ class PluginKernelBase(LinuxKernelTest):
try:
vm.launch()
except:
# TODO: probably fails because plugins not enabled but we
# can't currently probe for the feature.
self.cancel("TCG Plugins not enabled?")
except VMLaunchFailure as excp:
if "plugin interface not enabled in this build" in excp.output:
self.skipTest("TCG plugins not enabled")
else:
self.log.info(f"unhandled launch failure: {excp.output}")
raise excp
self.wait_for_console_pattern(console_pattern, vm)
# ensure logs are flushed
@ -65,7 +68,7 @@ class PluginKernelNormal(PluginKernelBase):
kernel_path = self.ASSET_KERNEL.fetch()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0')
console_pattern = 'Kernel panic - not syncing: VFS:'
console_pattern = 'Please append a correct "root=" boot option'
plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin",
suffix=".log")
@ -91,7 +94,7 @@ class PluginKernelNormal(PluginKernelBase):
kernel_path = self.ASSET_KERNEL.fetch()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0')
console_pattern = 'Kernel panic - not syncing: VFS:'
console_pattern = 'Please append a correct "root=" boot option'
plugin_log = tempfile.NamedTemporaryFile(mode="r+t", prefix="plugin",
suffix=".log")

View file

@ -7,8 +7,8 @@
import os
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern
from unittest import skipUnless
from qemu_test import interrupt_interactive_console_until_pattern, skipSlowTest
class EmcraftSf2Machine(LinuxKernelTest):
@ -32,7 +32,7 @@ class EmcraftSf2Machine(LinuxKernelTest):
'20200711-gsj-qemu-0/nuvoton-npcm730-gsj.dtb'),
'3249b2da787d4b9ad4e61f315b160abfceb87b5e1895a7ce898ce7f40c8d4045')
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
@skipSlowTest()
def test_arm_quanta_gsj(self):
self.set_machine('quanta-gsj')
image_path = self.uncompress(self.ASSET_IMAGE, format='gz')

View file

@ -0,0 +1,100 @@
#!/usr/bin/env python3
#
# Migration test
#
# Copyright (c) 2019 Red Hat, Inc.
#
# Authors:
# Cleber Rosa <crosa@redhat.com>
# Caio Carrara <ccarrara@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 tempfile
import os
import time
from qemu_test import QemuSystemTest, skipIfMissingCommands
from qemu_test.ports import Ports
class MigrationTest(QemuSystemTest):
timeout = 10
@staticmethod
def migration_finished(vm):
return vm.cmd('query-migrate')['status'] in ('completed', 'failed')
def assert_migration(self, src_vm, dst_vm):
end = time.monotonic() + self.timeout
while time.monotonic() < end and not self.migration_finished(src_vm):
time.sleep(0.1)
end = time.monotonic() + self.timeout
while time.monotonic() < end and not self.migration_finished(dst_vm):
time.sleep(0.1)
self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed')
self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
def select_machine(self):
target_machine = {
'aarch64': 'quanta-gsj',
'alpha': 'clipper',
'arm': 'npcm750-evb',
'i386': 'isapc',
'ppc': 'sam460ex',
'ppc64': 'mac99',
'riscv32': 'spike',
'riscv64': 'virt',
'sparc': 'SS-4',
'sparc64': 'sun4u',
'x86_64': 'microvm',
}
self.set_machine(target_machine[self.arch])
def do_migrate(self, dest_uri, src_uri=None):
self.select_machine()
dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu")
dest_vm.add_args('-nodefaults')
dest_vm.launch()
if src_uri is None:
src_uri = dest_uri
source_vm = self.get_vm(name="source-qemu")
source_vm.add_args('-nodefaults')
source_vm.launch()
source_vm.qmp('migrate', uri=src_uri)
self.assert_migration(source_vm, dest_vm)
def _get_free_port(self, ports):
port = ports.find_free_port()
if port is None:
self.skipTest('Failed to find a free port')
return port
def test_migration_with_tcp_localhost(self):
with Ports() as ports:
dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
self.do_migrate(dest_uri)
def test_migration_with_unix(self):
with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
dest_uri = 'unix:%s/qemu-test.sock' % socket_path
self.do_migrate(dest_uri)
@skipIfMissingCommands('nc')
def test_migration_with_exec(self):
"""The test works for both netcat-traditional and netcat-openbsd packages."""
with Ports() as ports:
free_port = self._get_free_port(ports)
dest_uri = 'exec:nc -l localhost %u' % free_port
src_uri = 'exec:nc localhost %u' % free_port
self.do_migrate(dest_uri, src_uri)
if __name__ == '__main__':
QemuSystemTest.main()

View file

@ -0,0 +1,60 @@
#!/usr/bin/env python3
#
# Replay tests for the little-endian 64-bit MIPS Malta board
#
# 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 replay_kernel import ReplayKernelBase
class Mips64elReplay(ReplayKernelBase):
ASSET_KERNEL_2_63_2 = Asset(
('http://snapshot.debian.org/archive/debian/'
'20130217T032700Z/pool/main/l/linux-2.6/'
'linux-image-2.6.32-5-5kc-malta_2.6.32-48_mipsel.deb'),
'35eb476f03be589824b0310358f1c447d85e645b88cbcd2ac02b97ef560f9f8d')
def test_replay_mips64el_malta(self):
self.set_machine('malta')
kernel_path = self.archive_extract(self.ASSET_KERNEL_2_63_2,
member='boot/vmlinux-2.6.32-5-5kc-malta')
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
ASSET_KERNEL_3_19_3 = Asset(
('https://github.com/philmd/qemu-testing-blob/'
'raw/9ad2df38/mips/malta/mips64el/'
'vmlinux-3.19.3.mtoman.20150408'),
'8d3beb003bc66051ead98e7172139017fcf9ce2172576541c57e86418dfa5ab8')
ASSET_CPIO_R1 = Asset(
('https://github.com/groeck/linux-build-test/'
'raw/8584a59e/rootfs/mipsel64/'
'rootfs.mipsel64r1.cpio.gz'),
'75ba10cd35fb44e32948eeb26974f061b703c81c4ba2fab1ebcacf1d1bec3b61')
@skipUntrustedTest()
def test_replay_mips64el_malta_5KEc_cpio(self):
self.set_machine('malta')
self.cpu = '5KEc'
kernel_path = self.ASSET_KERNEL_3_19_3.fetch()
initrd_path = self.uncompress(self.ASSET_CPIO_R1)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 console=tty '
'rdinit=/sbin/init noreboot')
console_pattern = 'Boot successful.'
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
args=('-initrd', initrd_path))
if __name__ == '__main__':
ReplayKernelBase.main()

View file

@ -1,6 +1,6 @@
#!/usr/bin/env python3
#
# Functional tests for the little-endian 32-bit MIPS Malta board
# Functional tests for the big-endian 32-bit MIPS Malta board
#
# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
#

View file

@ -0,0 +1,55 @@
#!/usr/bin/env python3
#
# Replay tests for the big-endian 32-bit MIPS Malta board
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import Asset, skipSlowTest, exec_command_and_wait_for_pattern
from replay_kernel import ReplayKernelBase
class MipsReplay(ReplayKernelBase):
ASSET_KERNEL_2_63_2 = Asset(
('http://snapshot.debian.org/archive/debian/'
'20130217T032700Z/pool/main/l/linux-2.6/'
'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb'),
'16ca524148afb0626f483163e5edf352bc1ab0e4fc7b9f9d473252762f2c7a43')
def test_replay_mips_malta(self):
self.set_machine('malta')
kernel_path = self.archive_extract(self.ASSET_KERNEL_2_63_2,
member='boot/vmlinux-2.6.32-5-4kc-malta')
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
ASSET_KERNEL_4_5_0 = Asset(
('http://snapshot.debian.org/archive/debian/'
'20160601T041800Z/pool/main/l/linux/'
'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb'),
'526b17d5889840888b76fc2c36a0ebde182c9b1410a3a1e68203c3b160eb2027')
ASSET_INITRD = Asset(
('https://github.com/groeck/linux-build-test/raw/'
'8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/'
'mips/rootfs.cpio.gz'),
'dcfe3a7fe3200da3a00d176b95caaa086495eb158f2bff64afc67d7e1eb2cddc')
@skipSlowTest()
def test_replay_mips_malta_cpio(self):
self.set_machine('malta')
kernel_path = self.archive_extract(self.ASSET_KERNEL_4_5_0,
member='boot/vmlinux-4.5.0-2-4kc-malta')
initrd_path = self.uncompress(self.ASSET_INITRD)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 console=tty '
'rdinit=/sbin/init noreboot')
console_pattern = 'Boot successful.'
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
args=('-initrd', initrd_path))
if __name__ == '__main__':
ReplayKernelBase.main()

View file

@ -0,0 +1,54 @@
#!/usr/bin/env python3
#
# Replay tests for the little-endian 32-bit MIPS Malta board
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import Asset, wait_for_console_pattern, skipSlowTest
from replay_kernel import ReplayKernelBase
class MipselReplay(ReplayKernelBase):
ASSET_KERNEL_4K = Asset(
('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page4k.xz'),
'019e034094ac6cf3aa77df5e130fb023ce4dbc804b04bfcc560c6403e1ae6bdb')
ASSET_KERNEL_16K = Asset(
('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page16k_up.xz'),
'3a54a10b3108c16a448dca9ea3db378733a27423befc2a45a5bdf990bd85e12c')
ASSET_KERNEL_64K = Asset(
('http://mipsdistros.mips.com/LinuxDistro/nanomips/'
'kernels/v4.15.18-432-gb2eb9a8b07a1-20180627102142/'
'generic_nano32r6el_page64k_dbg.xz'),
'ce21ff4b07a981ecb8a39db2876616f5a2473eb2ab459c6f67465b9914b0c6b6')
def do_test_replay_mips_malta32el_nanomips(self, kernel_asset):
self.set_machine('malta')
self.cpu = 'I7200'
kernel_path = self.uncompress(kernel_asset)
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'mem=256m@@0x0 '
'console=ttyS0')
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
@skipSlowTest()
def test_replay_mips_malta32el_nanomips_4k(self):
self.do_test_replay_mips_malta32el_nanomips(self.ASSET_KERNEL_4K)
@skipSlowTest()
def test_replay_mips_malta32el_nanomips_16k_up(self):
self.do_test_replay_mips_malta32el_nanomips(self.ASSET_KERNEL_16K)
@skipSlowTest()
def test_replay_mips_malta32el_nanomips_64k_dbg(self):
self.do_test_replay_mips_malta32el_nanomips(self.ASSET_KERNEL_64K)
if __name__ == '__main__':
ReplayKernelBase.main()

View file

@ -0,0 +1,44 @@
#!/usr/bin/env python3
#
# Functional test that boots a mac99 machine with a PPC970 CPU
#
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import LinuxKernelTest, Asset
from qemu_test import exec_command_and_wait_for_pattern
class mac99Test(LinuxKernelTest):
ASSET_BR2_MAC99_LINUX = Asset(
'https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/buildroot/qemu_ppc64_mac99-2023.11-8-gdcd9f0f6eb-20240105/vmlinux',
'd59307437e4365f2cced0bbd1b04949f7397b282ef349b7cafd894d74aadfbff')
ASSET_BR2_MAC99_ROOTFS = Asset(
'https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main//buildroot/qemu_ppc64_mac99-2023.11-8-gdcd9f0f6eb-20240105/rootfs.ext2',
'bbd5fd8af62f580bc4e585f326fe584e22856572633a8333178ea6d4ed4955a4')
def test_ppc64_mac99_buildroot(self):
self.set_machine('mac99')
linux_path = self.ASSET_BR2_MAC99_LINUX.fetch()
rootfs_path = self.ASSET_BR2_MAC99_ROOTFS.fetch()
self.vm.set_console()
# Note: We need '-nographic' to get a serial console
self.vm.add_args('-kernel', linux_path,
'-append', 'root=/dev/sda',
'-drive', f'file={rootfs_path},format=raw',
'-snapshot', '-nographic')
self.vm.launch()
self.wait_for_console_pattern('>> OpenBIOS')
self.wait_for_console_pattern('Linux version')
self.wait_for_console_pattern('/init as init process')
self.wait_for_console_pattern('gem 0000:f0:0e.0 eth0: Link is up at 100 Mbps')
self.wait_for_console_pattern('buildroot login:')
exec_command_and_wait_for_pattern(self, 'root', '#')
exec_command_and_wait_for_pattern(self, 'poweroff', 'Power down')
if __name__ == '__main__':
LinuxKernelTest.main()

View file

@ -9,6 +9,7 @@
from qemu_test import QemuSystemTest, Asset
from qemu_test import wait_for_console_pattern, skipUntrustedTest
from qemu_test import exec_command_and_wait_for_pattern
class IbmPrep40pMachine(QemuSystemTest):
@ -72,5 +73,22 @@ class IbmPrep40pMachine(QemuSystemTest):
self.vm.launch()
wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9')
ASSET_40P_SANDALFOOT = Asset(
'http://www.juneau-lug.org/zImage.initrd.sandalfoot',
'749ab02f576c6dc8f33b9fb022ecb44bf6a35a0472f2ea6a5e9956bc15933901')
def test_openbios_and_linux(self):
self.set_machine('40p')
self.require_accelerator("tcg")
drive_path = self.ASSET_40P_SANDALFOOT.fetch()
self.vm.set_console()
self.vm.add_args('-cdrom', drive_path,
'-boot', 'd')
self.vm.launch()
wait_for_console_pattern(self, 'Please press Enter to activate this console.')
exec_command_and_wait_for_pattern(self, '\012', '#')
exec_command_and_wait_for_pattern(self, 'uname -a', 'Linux ppc 2.4.18')
if __name__ == '__main__':
QemuSystemTest.main()

View file

@ -42,6 +42,7 @@ $(ASM_TESTS): LDFLAGS += -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
$(ASM_TESTS): $(LINK_SCRIPT)
TESTS += $(ASM_TESTS)
MULTIARCH_TESTS += mvc-smc
S390X_MULTIARCH_RUNTIME_OBJS = head64.o console.o $(MINILIB_OBJS)
$(MULTIARCH_TESTS): $(S390X_MULTIARCH_RUNTIME_OBJS)
$(MULTIARCH_TESTS): LDFLAGS += $(S390X_MULTIARCH_RUNTIME_OBJS)

82
tests/tcg/s390x/mvc-smc.c Normal file
View file

@ -0,0 +1,82 @@
/*
* Test modifying code using the MVC instruction.
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include <minilib.h>
#define PAGE_SIZE 4096
#define BR_14_SIZE 2
#define RWX_OFFSET 2
static unsigned char rw[PAGE_SIZE + BR_14_SIZE];
static unsigned char rwx[RWX_OFFSET + sizeof(rw)]
__attribute__((aligned(PAGE_SIZE)));
typedef unsigned long (*function_t)(unsigned long);
static int emit_function(unsigned char *p, int n)
{
int i = 0, val = 0;
while (i < n - 2) {
/* aghi %r2,1 */
p[i++] = 0xa7;
p[i++] = 0x2b;
p[i++] = 0x00;
p[i++] = 0x01;
val++;
}
/* br %r14 */
p[i++] = 0x07;
p[i++] = 0xfe;
return val;
}
static void memcpy_mvc(void *dest, void *src, unsigned long n)
{
while (n >= 256) {
asm("mvc 0(256,%[dest]),0(%[src])"
:
: [dest] "a" (dest)
, [src] "a" (src)
: "memory");
dest += 256;
src += 256;
n -= 256;
}
asm("exrl %[n],0f\n"
"j 1f\n"
"0: mvc 0(1,%[dest]),0(%[src])\n"
"1:"
:
: [dest] "a" (dest)
, [src] "a" (src)
, [n] "a" (n)
: "memory");
}
int main(void)
{
int expected, size;
/* Create a TB. */
size = sizeof(rwx) - RWX_OFFSET - 4;
expected = emit_function(rwx + RWX_OFFSET, size);
if (((function_t)(rwx + RWX_OFFSET))(0) != expected) {
return 1;
}
/* Overwrite the TB. */
size += 4;
expected = emit_function(rw, size);
memcpy_mvc(rwx + RWX_OFFSET, rw, size);
if (((function_t)(rwx + RWX_OFFSET))(0) != expected) {
return 2;
}
return 0;
}