* 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: include/hw/input/adb*
F: pc-bios/qemu_vga.ndrv F: pc-bios/qemu_vga.ndrv
F: tests/functional/test_ppc_mac.py F: tests/functional/test_ppc_mac.py
F: tests/functional/test_ppc64_mac99.py
Old World (g3beige) Old World (g3beige)
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
@ -3461,6 +3462,7 @@ F: include/migration/
F: include/qemu/userfaultfd.h F: include/qemu/userfaultfd.h
F: migration/ F: migration/
F: scripts/vmstate-static-checker.py F: scripts/vmstate-static-checker.py
F: tests/functional/test_migration.py
F: tests/vmstate-static-checker-data/ F: tests/vmstate-static-checker-data/
F: tests/qtest/migration/ F: tests/qtest/migration/
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_kernel.py
F: tests/avocado/replay_linux.py F: tests/avocado/replay_linux.py
F: tests/avocado/reverse_debugging.py F: tests/avocado/reverse_debugging.py
F: tests/functional/*replay*.py
F: qapi/replay.json F: qapi/replay.json
IOVA Tree 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 Tests should not live in this state forever and should either be fixed
or eventually removed. 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 .. _unittest: https://docs.python.org/3/library/unittest.html

View file

@ -38,6 +38,10 @@
GlobalProperty hw_compat_9_2[] = { GlobalProperty hw_compat_9_2[] = {
{"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"}, {"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); 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 "kvm/kvm_s390x.h"
#include "hw/virtio/virtio-md-pci.h" #include "hw/virtio/virtio-md-pci.h"
#include "hw/s390x/virtio-ccw-md.h" #include "hw/s390x/virtio-ccw-md.h"
#include "system/replay.h"
#include CONFIG_DEVICES #include CONFIG_DEVICES
static Error *pv_mig_blocker; static Error *pv_mig_blocker;
@ -454,6 +455,18 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
CPUState *cs, *t; CPUState *cs, *t;
S390CPU *cpu; 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 */ /* get the reset parameters, reset them once done */
s390_ipl_get_reset_request(&cs, &reset_type); s390_ipl_get_reset_request(&cs, &reset_type);
@ -533,7 +546,7 @@ static void s390_machine_reset(MachineState *machine, ResetType type)
* went wrong. * went wrong.
*/ */
s390_cpu_set_state(S390_CPU_STATE_OPERATING, cpu); 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); 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)); run_on_cpu(t, s390_do_cpu_set_diag318, RUN_ON_CPU_HOST_ULONG(0));
} }
s390_ipl_clear_reset_request(); 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, 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)) { if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_pre_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp); virtio_ccw_md_pre_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp);
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) { } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_PCI)) {
error_setg(errp, virtio_md_pci_pre_plug(VIRTIO_MD_PCI(dev), MACHINE(hotplug_dev), errp);
"PCI-attached virtio based memory devices not supported");
} }
} }
@ -566,7 +587,8 @@ static void s390_machine_device_plug(HotplugHandler *hotplug_dev,
if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) { if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
s390_cpu_plug(hotplug_dev, dev, errp); 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 * At this point, the device is realized and set all memdevs mapped, so
* qemu_maxrampagesize() will pick up the page sizes of these memdevs * 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"); " initial memory");
return; return;
} }
virtio_ccw_md_plug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp); 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)) { if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
error_setg(errp, "CPU hot unplug not supported on this machine"); error_setg(errp, "CPU hot unplug not supported on this machine");
return;
} else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) { } else if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_unplug_request(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), virtio_ccw_md_unplug_request(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev),
errp); 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,7 +629,9 @@ static void s390_machine_device_unplug(HotplugHandler *hotplug_dev,
{ {
if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) { if (object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_MD_CCW)) {
virtio_ccw_md_unplug(VIRTIO_MD_CCW(dev), MACHINE(hotplug_dev), errp); 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);
}
} }
static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms, static CpuInstanceProperties s390_cpu_index_to_props(MachineState *ms,

View file

@ -35,11 +35,22 @@ struct VirtIOBalloonPCI {
VirtIOBalloon vdev; 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) static void virtio_balloon_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{ {
VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev); VirtIOBalloonPCI *dev = VIRTIO_BALLOON_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&dev->vdev); DeviceState *vdev = DEVICE(&dev->vdev);
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
vpci_dev->nvectors = 2;
}
vpci_dev->class_code = PCI_CLASS_OTHERS; vpci_dev->class_code = PCI_CLASS_OTHERS;
qdev_realize(vdev, BUS(&vpci_dev->bus), errp); 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->device_id = PCI_DEVICE_ID_VIRTIO_BALLOON;
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
pcidev_k->class_id = PCI_CLASS_OTHERS; pcidev_k->class_id = PCI_CLASS_OTHERS;
device_class_set_props(dc, virtio_balloon_properties);
} }
static void virtio_balloon_pci_instance_init(Object *obj) 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); VirtIOMEMPCI *mem_pci = VIRTIO_MEM_PCI(vpci_dev);
DeviceState *vdev = DEVICE(&mem_pci->vdev); DeviceState *vdev = DEVICE(&mem_pci->vdev);
if (vpci_dev->nvectors == DEV_NVECTORS_UNSPECIFIED) {
vpci_dev->nvectors = 2;
}
virtio_pci_force_virtio_1(vpci_dev); virtio_pci_force_virtio_1(vpci_dev);
qdev_realize(vdev, BUS(&vpci_dev->bus), errp); 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); 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) static void virtio_mem_pci_class_init(ObjectClass *klass, void *data)
{ {
DeviceClass *dc = DEVICE_CLASS(klass); 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); set_bit(DEVICE_CATEGORY_MISC, dc->categories);
pcidev_k->revision = VIRTIO_PCI_ABI_VERSION; pcidev_k->revision = VIRTIO_PCI_ABI_VERSION;
pcidev_k->class_id = PCI_CLASS_OTHERS; 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->get_addr = virtio_mem_pci_get_addr;
mdc->set_addr = virtio_mem_pci_set_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); 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 #ifdef WIN32
AioContext *ctxt = qemu_get_aio_context(); AioContext *ctxt = qemu_get_aio_context();
@ -260,7 +267,7 @@ static void net_slirp_register_poll_fd(int fd, void *opaque)
#endif #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 #ifdef WIN32
if (WSAEventSelect(fd, NULL, 0) != 0) { if (WSAEventSelect(fd, NULL, 0) != 0) {
@ -286,8 +293,8 @@ static const SlirpCb slirp_cb = {
#endif #endif
.timer_free = net_slirp_timer_free, .timer_free = net_slirp_timer_free,
.timer_mod = net_slirp_timer_mod, .timer_mod = net_slirp_timer_mod,
.register_poll_fd = net_slirp_register_poll_fd, .register_poll_socket = net_slirp_register_poll_sock,
.unregister_poll_fd = net_slirp_unregister_poll_fd, .unregister_poll_socket = net_slirp_unregister_poll_sock,
.notify = net_slirp_notify, .notify = net_slirp_notify,
}; };
@ -314,7 +321,7 @@ static int slirp_poll_to_gio(int events)
return ret; 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; GArray *pollfds = opaque;
GPollFD pfd = { GPollFD pfd = {
@ -363,8 +370,8 @@ static void net_slirp_poll_notify(Notifier *notifier, void *data)
switch (poll->state) { switch (poll->state) {
case MAIN_LOOP_POLL_FILL: 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); net_slirp_add_poll, poll->pollfds);
break; break;
case MAIN_LOOP_POLL_OK: case MAIN_LOOP_POLL_OK:
case MAIN_LOOP_POLL_ERR: case MAIN_LOOP_POLL_ERR:
@ -629,7 +636,9 @@ static int net_slirp_init(NetClientState *peer, const char *model,
s = DO_UPCAST(SlirpState, nc, nc); 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.restricted = restricted;
cfg.in_enabled = ipv4; cfg.in_enabled = ipv4;
cfg.vnetwork = net; 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(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(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(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(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) 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, int mmu_idx, bool nonfault,
void **phost, uintptr_t ra) 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); nonfault, phost, ra);
if (unlikely(flags & TLB_INVALID_MASK)) { 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) 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): def test_aarch64_virt(self):
""" """
:avocado: tags=arch:aarch64 :avocado: tags=arch:aarch64
@ -455,123 +410,3 @@ class ReplayKernelNormal(ReplayKernelBase):
'/qac-best-of-multiarch/download/day02.tar.xz') '/qac-best-of-multiarch/download/day02.tar.xz')
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash) file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
self.do_test_advcal_2018(file_path, 'santas-sleigh-ride.elf') 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, 'arm_sx1' : 360,
'intel_iommu': 300, 'intel_iommu': 300,
'mips_malta' : 120, 'mips_malta' : 120,
'mipsel_replay' : 480,
'netdev_ethtool' : 180, 'netdev_ethtool' : 180,
'ppc_40p' : 240, 'ppc_40p' : 240,
'ppc64_hv' : 1000, 'ppc64_hv' : 1000,
'ppc64_powernv' : 480, 'ppc64_powernv' : 480,
'ppc64_pseries' : 480, 'ppc64_pseries' : 480,
'ppc64_tuxrun' : 420, 'ppc64_tuxrun' : 420,
'ppc64_mac99' : 120,
'riscv64_tuxrun' : 120, 'riscv64_tuxrun' : 120,
's390x_ccw_virtio' : 420, 's390x_ccw_virtio' : 420,
'sh4_tuxrun' : 240, 'sh4_tuxrun' : 240,
@ -59,6 +61,10 @@ tests_generic_linuxuser = [
tests_generic_bsduser = [ tests_generic_bsduser = [
] ]
tests_aarch64_system_quick = [
'migration',
]
tests_aarch64_system_thorough = [ tests_aarch64_system_thorough = [
'aarch64_aspeed', 'aarch64_aspeed',
'aarch64_raspi3', 'aarch64_raspi3',
@ -68,16 +74,25 @@ tests_aarch64_system_thorough = [
'aarch64_sbsaref', 'aarch64_sbsaref',
'aarch64_sbsaref_alpine', 'aarch64_sbsaref_alpine',
'aarch64_sbsaref_freebsd', 'aarch64_sbsaref_freebsd',
'aarch64_tcg_plugins',
'aarch64_tuxrun', 'aarch64_tuxrun',
'aarch64_virt', 'aarch64_virt',
'aarch64_xlnx_versal', 'aarch64_xlnx_versal',
'multiprocess', 'multiprocess',
] ]
tests_alpha_system_quick = [
'migration',
]
tests_alpha_system_thorough = [ tests_alpha_system_thorough = [
'alpha_clipper', 'alpha_clipper',
] ]
tests_arm_system_quick = [
'migration',
]
tests_arm_system_thorough = [ tests_arm_system_thorough = [
'arm_aspeed_ast1030', 'arm_aspeed_ast1030',
'arm_aspeed_palmetto', 'arm_aspeed_palmetto',
@ -114,6 +129,10 @@ tests_hppa_system_quick = [
'hppa_seabios', 'hppa_seabios',
] ]
tests_i386_system_quick = [
'migration',
]
tests_i386_system_thorough = [ tests_i386_system_thorough = [
'i386_tuxrun', 'i386_tuxrun',
] ]
@ -139,11 +158,13 @@ tests_microblazeel_system_thorough = [
tests_mips_system_thorough = [ tests_mips_system_thorough = [
'mips_malta', 'mips_malta',
'mips_replay',
'mips_tuxrun', 'mips_tuxrun',
] ]
tests_mipsel_system_thorough = [ tests_mipsel_system_thorough = [
'mipsel_malta', 'mipsel_malta',
'mipsel_replay',
'mipsel_tuxrun', 'mipsel_tuxrun',
] ]
@ -155,6 +176,7 @@ tests_mips64el_system_thorough = [
'mips64el_fuloong2e', 'mips64el_fuloong2e',
'mips64el_loongson3v', 'mips64el_loongson3v',
'mips64el_malta', 'mips64el_malta',
'mips64el_replay',
'mips64el_tuxrun', 'mips64el_tuxrun',
] ]
@ -163,6 +185,7 @@ tests_or1k_system_thorough = [
] ]
tests_ppc_system_quick = [ tests_ppc_system_quick = [
'migration',
'ppc_74xx', 'ppc_74xx',
] ]
@ -177,15 +200,21 @@ tests_ppc_system_thorough = [
'ppc_virtex_ml507', 'ppc_virtex_ml507',
] ]
tests_ppc64_system_quick = [
'migration',
]
tests_ppc64_system_thorough = [ tests_ppc64_system_thorough = [
'ppc64_e500', 'ppc64_e500',
'ppc64_hv', 'ppc64_hv',
'ppc64_powernv', 'ppc64_powernv',
'ppc64_pseries', 'ppc64_pseries',
'ppc64_tuxrun', 'ppc64_tuxrun',
'ppc64_mac99',
] ]
tests_riscv32_system_quick = [ tests_riscv32_system_quick = [
'migration',
'riscv_opensbi', 'riscv_opensbi',
] ]
@ -194,6 +223,7 @@ tests_riscv32_system_thorough = [
] ]
tests_riscv64_system_quick = [ tests_riscv64_system_quick = [
'migration',
'riscv_opensbi', 'riscv_opensbi',
] ]
@ -220,10 +250,18 @@ tests_sh4eb_system_thorough = [
'sh4eb_r2d', 'sh4eb_r2d',
] ]
tests_sparc_system_quick = [
'migration',
]
tests_sparc_system_thorough = [ tests_sparc_system_thorough = [
'sparc_sun4m', 'sparc_sun4m',
] ]
tests_sparc64_system_quick = [
'migration',
]
tests_sparc64_system_thorough = [ tests_sparc64_system_thorough = [
'sparc64_sun4u', 'sparc64_sun4u',
'sparc64_tuxrun', 'sparc64_tuxrun',
@ -232,6 +270,7 @@ tests_sparc64_system_thorough = [
tests_x86_64_system_quick = [ tests_x86_64_system_quick = [
'cpu_queries', 'cpu_queries',
'mem_addr_space', 'mem_addr_space',
'migration',
'pc_cpu_hotplug_props', 'pc_cpu_hotplug_props',
'virtio_version', 'virtio_version',
'x86_cpu_model_versions', 'x86_cpu_model_versions',

View file

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

View file

@ -2,6 +2,7 @@
# #
# Decorators useful in functional tests # Decorators useful in functional tests
import importlib
import os import os
import platform import platform
from unittest import skipUnless from unittest import skipUnless
@ -16,15 +17,14 @@ Example:
@skipIfMissingCommands("mkisofs", "losetup") @skipIfMissingCommands("mkisofs", "losetup")
''' '''
def skipIfMissingCommands(*args): def skipIfMissingCommands(*args):
def has_cmds(cmdlist): has_cmds = True
for cmd in cmdlist: for cmd in args:
if not which(cmd): if not which(cmd):
return False has_cmds = False
return True break
return skipUnless(lambda: has_cmds(args), return skipUnless(has_cmds, 'required command(s) "%s" not installed' %
'required command(s) "%s" not installed' % ", ".join(args))
", ".join(args))
''' '''
Decorator to skip execution of a test if the current Decorator to skip execution of a test if the current
@ -35,9 +35,9 @@ Example
@skipIfNotMachine("x86_64", "aarch64") @skipIfNotMachine("x86_64", "aarch64")
''' '''
def skipIfNotMachine(*args): 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"' % 'not running on one of the required machine(s) "%s"' %
", ".join(args)) ", ".join(args))
''' '''
Decorator to skip execution of flaky tests, unless Decorator to skip execution of flaky tests, unless
@ -86,6 +86,20 @@ def skipBigDataTest():
return skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), return skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'),
'Test requires large host storage space') '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 Decorator to skip execution of a test if the list
of python imports is not available. of python imports is not available.
@ -94,14 +108,13 @@ Example:
@skipIfMissingImports("numpy", "cv2") @skipIfMissingImports("numpy", "cv2")
''' '''
def skipIfMissingImports(*args): def skipIfMissingImports(*args):
def has_imports(importlist): has_imports = True
for impname in importlist: for impname in args:
try: try:
import impname importlib.import_module(impname)
except ImportError: except ImportError:
return False has_imports = False
return True break
return skipUnless(lambda: has_imports(args), return skipUnless(has_imports, 'required import(s) "%s" not installed' %
'required import(s) "%s" not installed' % ", ".join(args))
", ".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 import os
from qemu_test import QemuSystemTest, Asset from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern from qemu_test import wait_for_console_pattern
from unittest import skipUnless from unittest import skipUnless
from test_aarch64_sbsaref import fetch_firmware from test_aarch64_sbsaref import fetch_firmware
@ -53,8 +53,7 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
def test_sbsaref_alpine_linux_max_pauth_impdef(self): def test_sbsaref_alpine_linux_max_pauth_impdef(self):
self.boot_alpine_linux("max,pauth-impdef=on") self.boot_alpine_linux("max,pauth-impdef=on")
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), @skipSlowTest() # Test might timeout due to PAuth emulation
'Test might timeout due to PAuth emulation')
def test_sbsaref_alpine_linux_max(self): def test_sbsaref_alpine_linux_max(self):
self.boot_alpine_linux("max") self.boot_alpine_linux("max")

View file

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

View file

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

View file

@ -7,8 +7,8 @@
import os import os
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern 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 interrupt_interactive_console_until_pattern, skipSlowTest
from unittest import skipUnless
class EmcraftSf2Machine(LinuxKernelTest): class EmcraftSf2Machine(LinuxKernelTest):
@ -32,7 +32,7 @@ class EmcraftSf2Machine(LinuxKernelTest):
'20200711-gsj-qemu-0/nuvoton-npcm730-gsj.dtb'), '20200711-gsj-qemu-0/nuvoton-npcm730-gsj.dtb'),
'3249b2da787d4b9ad4e61f315b160abfceb87b5e1895a7ce898ce7f40c8d4045') '3249b2da787d4b9ad4e61f315b160abfceb87b5e1895a7ce898ce7f40c8d4045')
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout') @skipSlowTest()
def test_arm_quanta_gsj(self): def test_arm_quanta_gsj(self):
self.set_machine('quanta-gsj') self.set_machine('quanta-gsj')
image_path = self.uncompress(self.ASSET_IMAGE, format='gz') 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 #!/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> # 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 QemuSystemTest, Asset
from qemu_test import wait_for_console_pattern, skipUntrustedTest from qemu_test import wait_for_console_pattern, skipUntrustedTest
from qemu_test import exec_command_and_wait_for_pattern
class IbmPrep40pMachine(QemuSystemTest): class IbmPrep40pMachine(QemuSystemTest):
@ -72,5 +73,22 @@ class IbmPrep40pMachine(QemuSystemTest):
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9') 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__': if __name__ == '__main__':
QemuSystemTest.main() QemuSystemTest.main()

View file

@ -42,6 +42,7 @@ $(ASM_TESTS): LDFLAGS += -Wl,-T$(LINK_SCRIPT) -Wl,--build-id=none
$(ASM_TESTS): $(LINK_SCRIPT) $(ASM_TESTS): $(LINK_SCRIPT)
TESTS += $(ASM_TESTS) TESTS += $(ASM_TESTS)
MULTIARCH_TESTS += mvc-smc
S390X_MULTIARCH_RUNTIME_OBJS = head64.o console.o $(MINILIB_OBJS) S390X_MULTIARCH_RUNTIME_OBJS = head64.o console.o $(MINILIB_OBJS)
$(MULTIARCH_TESTS): $(S390X_MULTIARCH_RUNTIME_OBJS) $(MULTIARCH_TESTS): $(S390X_MULTIARCH_RUNTIME_OBJS)
$(MULTIARCH_TESTS): LDFLAGS += $(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;
}