mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-03 07:43:54 -06:00
* 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:
commit
e60938852f
28 changed files with 685 additions and 358 deletions
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
25
net/slirp.c
25
net/slirp.c
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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)) {
|
||||||
|
|
|
@ -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()
|
|
|
@ -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)
|
|
||||||
|
|
|
@ -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',
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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))
|
|
||||||
|
|
84
tests/functional/replay_kernel.py
Normal file
84
tests/functional/replay_kernel.py
Normal 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))
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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')
|
||||||
|
|
100
tests/functional/test_migration.py
Executable file
100
tests/functional/test_migration.py
Executable 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()
|
60
tests/functional/test_mips64el_replay.py
Executable file
60
tests/functional/test_mips64el_replay.py
Executable 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()
|
|
@ -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>
|
||||||
#
|
#
|
||||||
|
|
55
tests/functional/test_mips_replay.py
Executable file
55
tests/functional/test_mips_replay.py
Executable 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()
|
54
tests/functional/test_mipsel_replay.py
Normal file
54
tests/functional/test_mipsel_replay.py
Normal 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()
|
44
tests/functional/test_ppc64_mac99.py
Executable file
44
tests/functional/test_ppc64_mac99.py
Executable 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()
|
|
@ -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()
|
||||||
|
|
|
@ -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
82
tests/tcg/s390x/mvc-smc.c
Normal 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;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue