diff mbox series

[PULL,10/66] tests/qtest: enable tests for virtio-scmi

Message ID b6f53ae005a1c05034769beebf799e861b82d48a.1689030052.git.mst@redhat.com
State New
Headers show
Series [PULL,01/66] vdpa: Remove status in reset tracing | expand

Commit Message

Michael S. Tsirkin July 10, 2023, 11:02 p.m. UTC
From: Milan Zamazal <mzamazal@redhat.com>

We don't have a virtio-scmi implementation in QEMU and only support a
vhost-user backend.  This is very similar to virtio-gpio and we add the same
set of tests, just passing some vhost-user messages over the control socket.

Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
Acked-by: Thomas Huth <thuth@redhat.com>
Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 tests/qtest/libqos/virtio-scmi.h |  34 ++++++
 tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
 tests/qtest/vhost-user-test.c    |  44 ++++++++
 MAINTAINERS                      |   1 +
 tests/qtest/libqos/meson.build   |   1 +
 5 files changed, 254 insertions(+)
 create mode 100644 tests/qtest/libqos/virtio-scmi.h
 create mode 100644 tests/qtest/libqos/virtio-scmi.c

Comments

Thomas Huth July 18, 2023, 12:42 p.m. UTC | #1
On 11/07/2023 01.02, Michael S. Tsirkin wrote:
> From: Milan Zamazal <mzamazal@redhat.com>
> 
> We don't have a virtio-scmi implementation in QEMU and only support a
> vhost-user backend.  This is very similar to virtio-gpio and we add the same
> set of tests, just passing some vhost-user messages over the control socket.
> 
> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
> Acked-by: Thomas Huth <thuth@redhat.com>
> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
> ---
>   tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>   tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>   tests/qtest/vhost-user-test.c    |  44 ++++++++
>   MAINTAINERS                      |   1 +
>   tests/qtest/libqos/meson.build   |   1 +
>   5 files changed, 254 insertions(+)
>   create mode 100644 tests/qtest/libqos/virtio-scmi.h
>   create mode 100644 tests/qtest/libqos/virtio-scmi.c

  Hi!

I'm seeing some random failures with this new scmi test, so far only on 
non-x86 systems, e.g.:

  https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774

It also reproduces on a s390x host here, but only if I run "make check 
-j$(nproc)" - if I run the tests single-threaded, the qos-test passes there. 
Seems like there is a race somewhere in this test?

No clue how to debug this, but since it currently only happens on non-x86 
architectures, maybe we should limit it to x86 hosts for now?

  Thomas
Milan Zamazal July 18, 2023, 12:55 p.m. UTC | #2
Thomas Huth <thuth@redhat.com> writes:

> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>> From: Milan Zamazal <mzamazal@redhat.com>
>> We don't have a virtio-scmi implementation in QEMU and only support
>
>> a
>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>> set of tests, just passing some vhost-user messages over the control socket.
>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>> Acked-by: Thomas Huth <thuth@redhat.com>
>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>> ---
>>   tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>   tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>   tests/qtest/vhost-user-test.c    |  44 ++++++++
>>   MAINTAINERS                      |   1 +
>>   tests/qtest/libqos/meson.build   |   1 +
>>   5 files changed, 254 insertions(+)
>>   create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>   create mode 100644 tests/qtest/libqos/virtio-scmi.c
>
>  Hi!
>
> I'm seeing some random failures with this new scmi test, so far only
> on non-x86 systems, e.g.:
>
>  https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>
> It also reproduces on a s390x host here, but only if I run "make check
> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
> there. Seems like there is a race somewhere in this test?

Hmm, it's basically the same as virtio-gpio.c test, so it should be OK.
Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
interfere with each other in some way?  Is there possibly a way to
serialize them to check?

> No clue how to debug this, but since it currently only happens on
> non-x86 architectures, maybe we should limit it to x86 hosts for now?
>
>  Thomas
Thomas Huth July 19, 2023, 1:02 p.m. UTC | #3
On 18/07/2023 14.55, Milan Zamazal wrote:
> Thomas Huth <thuth@redhat.com> writes:
> 
>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>> From: Milan Zamazal <mzamazal@redhat.com>
>>> We don't have a virtio-scmi implementation in QEMU and only support
>>
>>> a
>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>> set of tests, just passing some vhost-user messages over the control socket.
>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>> ---
>>>    tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>    tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>    tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>    MAINTAINERS                      |   1 +
>>>    tests/qtest/libqos/meson.build   |   1 +
>>>    5 files changed, 254 insertions(+)
>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>
>>   Hi!
>>
>> I'm seeing some random failures with this new scmi test, so far only
>> on non-x86 systems, e.g.:
>>
>>   https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>
>> It also reproduces on a s390x host here, but only if I run "make check
>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>> there. Seems like there is a race somewhere in this test?
> 
> Hmm, it's basically the same as virtio-gpio.c test, so it should be OK.
> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
> interfere with each other in some way?  Is there possibly a way to
> serialize them to check?

I think within one qos-test, the sub-tests are already run serialized. But there might be multiple qos-tests running in parallel, e.g. one for the aarch64 target and one for the ppc64 target. And indeed, I can reproduce the problem on my x86 laptop by running this in one terminal window:

for ((x=0;x<1000;x++)); do \
  QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
  G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
  QTEST_QEMU_BINARY=./qemu-system-ppc64 \
  MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
  tests/qtest/qos-test -p \
  /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile \
  || break ; \
done

And this in another terminal window at the same time:

for ((x=0;x<1000;x++)); do \
  QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
  G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
  QTEST_QEMU_BINARY=./qemu-system-aarch64 \
  MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
  tests/qtest/qos-test -p \
  /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile \
  || break ; \
done

After a while, the aarch64 test broke with:

/aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile: qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost_set_vring_call failed 22
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost_set_vring_call failed 22
qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
qemu-system-aarch64: Failed to set msg fds.
qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659: msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && dev->msix_vector_release_notifier' failed.
../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped)
**
ERROR:../../devel/qemu/tests/qtest/qos-test.c:191:subprocess_run_one_test: child process (/aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile/subprocess [488457]) failed unexpectedly
Aborted (core dumped)

Can you also reproduce it this way?

  Thomas
Milan Zamazal July 19, 2023, 7:56 p.m. UTC | #4
Thomas Huth <thuth@redhat.com> writes:

> On 18/07/2023 14.55, Milan Zamazal wrote:
>> Thomas Huth <thuth@redhat.com> writes:
>> 
>
>>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>>> From: Milan Zamazal <mzamazal@redhat.com>
>>>> We don't have a virtio-scmi implementation in QEMU and only support
>>>
>>>> a
>>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>>> set of tests, just passing some vhost-user messages over the control socket.
>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>> ---
>>>>    tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>>    tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>>    tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>>    MAINTAINERS                      |   1 +
>>>>    tests/qtest/libqos/meson.build   |   1 +
>>>>    5 files changed, 254 insertions(+)
>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>>
>>>   Hi!
>>>
>>> I'm seeing some random failures with this new scmi test, so far only
>>> on non-x86 systems, e.g.:
>>>
>>>   https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>>
>>> It also reproduces on a s390x host here, but only if I run "make check
>>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>>> there. Seems like there is a race somewhere in this test?
>> Hmm, it's basically the same as virtio-gpio.c test, so it should be
>> OK.
>> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
>> interfere with each other in some way?  Is there possibly a way to
>> serialize them to check?
>
> I think within one qos-test, the sub-tests are already run
> serialized. 

I see, OK.

> But there might be multiple qos-tests running in parallel, e.g. one
> for the aarch64 target and one for the ppc64 target. And indeed, I can
> reproduce the problem on my x86 laptop by running this in one terminal
> window:
>
> for ((x=0;x<1000;x++)); do \
>  QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>  G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>  QTEST_QEMU_BINARY=./qemu-system-ppc64 \
>  MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>  tests/qtest/qos-test -p \
>  /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
> \
>  || break ; \
> done
>
> And this in another terminal window at the same time:
>
> for ((x=0;x<1000;x++)); do \
>  QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>  G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>  QTEST_QEMU_BINARY=./qemu-system-aarch64 \
>  MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>  tests/qtest/qos-test -p \
>  /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
> \
>  || break ; \
> done
>
> After a while, the aarch64 test broke with:
>
> /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile:
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost_set_vring_call failed 22
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost_set_vring_call failed 22
> qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659:
> msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier
> && dev->msix_vector_release_notifier' failed.
> ../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected QEMU
> death from signal 6 (Aborted) (core dumped)
> **
> ERROR:../../devel/qemu/tests/qtest/qos-test.c:191:subprocess_run_one_test:
> child process
> (/aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile/subprocess
> [488457]) failed unexpectedly
> Aborted (core dumped)

Interesting, good discovery.

> Can you also reproduce it this way?

Unfortunately not.  I ran the loops several times and everything passed.
I tried to compile and run it in a different distro container and it
passed too.  I also haven't been successful in getting any idea how the
processes could influence each other.

What OS and what QEMU configure flags did you use to compile and run it?

Thanks,
Milan
Fabiano Rosas July 19, 2023, 8:51 p.m. UTC | #5
Thomas Huth <thuth@redhat.com> writes:

> On 18/07/2023 14.55, Milan Zamazal wrote:
>> Thomas Huth <thuth@redhat.com> writes:
>> 
>>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>>> From: Milan Zamazal <mzamazal@redhat.com>
>>>> We don't have a virtio-scmi implementation in QEMU and only support
>>>
>>>> a
>>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>>> set of tests, just passing some vhost-user messages over the control socket.
>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>> ---
>>>>    tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>>    tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>>    tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>>    MAINTAINERS                      |   1 +
>>>>    tests/qtest/libqos/meson.build   |   1 +
>>>>    5 files changed, 254 insertions(+)
>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>>
>>>   Hi!
>>>
>>> I'm seeing some random failures with this new scmi test, so far only
>>> on non-x86 systems, e.g.:
>>>
>>>   https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>>
>>> It also reproduces on a s390x host here, but only if I run "make check
>>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>>> there. Seems like there is a race somewhere in this test?
>> 
>> Hmm, it's basically the same as virtio-gpio.c test, so it should be OK.
>> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
>> interfere with each other in some way?  Is there possibly a way to
>> serialize them to check?
>
> I think within one qos-test, the sub-tests are already run serialized. But there might be multiple qos-tests running in parallel, e.g. one for the aarch64 target and one for the ppc64 target. And indeed, I can reproduce the problem on my x86 laptop by running this in one terminal window:
>
> for ((x=0;x<1000;x++)); do \
>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>   QTEST_QEMU_BINARY=./qemu-system-ppc64 \
>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>   tests/qtest/qos-test -p \
>   /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile \
>   || break ; \
> done
>
> And this in another terminal window at the same time:
>
> for ((x=0;x<1000;x++)); do \
>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>   QTEST_QEMU_BINARY=./qemu-system-aarch64 \
>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>   tests/qtest/qos-test -p \
>   /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile \
>   || break ; \
> done
>
> After a while, the aarch64 test broke with:
>
> /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile: qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost_set_vring_call failed 22
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost_set_vring_call failed 22
> qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: Failed to set msg fds.
> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
> qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659: msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier && dev->msix_vector_release_notifier' failed.
> ../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected QEMU death from signal 6 (Aborted) (core dumped)

If it helps,

it looks like msix_unset_vector_notifiers is being called twice, once
from vu_scmi_set_status() and another from vu_scmi_disconnect():

msix_unset_vector_notifiers
virtio_pci_set_guest_notifiers
vu_scmi_stop
vu_scmi_disconnect   <-
vu_scmi_event
chr_be_event
qemu_chr_be_event
tcp_chr_disconnect_locked
tcp_chr_write
qemu_chr_write_buffer

msix_unset_vector_notifiers
virtio_pci_set_guest_notifiers
vu_scmi_stop
vu_scmi_set_status   <-
virtio_set_status
virtio_vmstate_change
vm_state_notify
do_vm_stop
vm_shutdown
qemu_cleanup
Milan Zamazal July 20, 2023, 8:34 a.m. UTC | #6
Fabiano Rosas <farosas@suse.de> writes:

> Thomas Huth <thuth@redhat.com> writes:
>
>> On 18/07/2023 14.55, Milan Zamazal wrote:
>>> Thomas Huth <thuth@redhat.com> writes:
>>> 
>>>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>>>> From: Milan Zamazal <mzamazal@redhat.com>
>>>>> We don't have a virtio-scmi implementation in QEMU and only support
>>>>
>>>>> a
>>>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>>>> set of tests, just passing some vhost-user messages over the control socket.
>>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>>> ---
>>>>>    tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>>>    tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>>>    tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>>>    MAINTAINERS                      |   1 +
>>>>>    tests/qtest/libqos/meson.build   |   1 +
>>>>>    5 files changed, 254 insertions(+)
>>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>>>    create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>>>
>>>>   Hi!
>>>>
>>>> I'm seeing some random failures with this new scmi test, so far only
>>>> on non-x86 systems, e.g.:
>>>>
>>>>   https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>>>
>>>> It also reproduces on a s390x host here, but only if I run "make check
>>>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>>>> there. Seems like there is a race somewhere in this test?
>>> 
>>> Hmm, it's basically the same as virtio-gpio.c test, so it should be OK.
>>> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
>>> interfere with each other in some way?  Is there possibly a way to
>>> serialize them to check?
>>
>> I think within one qos-test, the sub-tests are already run
>> serialized. But there might be multiple qos-tests running in
>> parallel, e.g. one for the aarch64 target and one for the ppc64
>> target. And indeed, I can reproduce the problem on my x86 laptop by
>> running this in one terminal window:
>>
>> for ((x=0;x<1000;x++)); do \
>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>   QTEST_QEMU_BINARY=./qemu-system-ppc64 \
>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>   tests/qtest/qos-test -p \
>>   /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>> \
>>   || break ; \
>> done
>>
>> And this in another terminal window at the same time:
>>
>> for ((x=0;x<1000;x++)); do \
>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>   QTEST_QEMU_BINARY=./qemu-system-aarch64 \
>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>   tests/qtest/qos-test -p \
>>   /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>> \
>>   || break ; \
>> done
>>
>> After a while, the aarch64 test broke with:
>>
>> /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile:
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost_set_vring_call failed 22
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost_set_vring_call failed 22
>> qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659:
>> msix_unset_vector_notifiers: Assertion
>> `dev->msix_vector_use_notifier && dev->msix_vector_release_notifier'
>> failed.
>> ../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected
>> QEMU death from signal 6 (Aborted) (core dumped)
>
> If it helps,

It helps a lot, thank you!

> it looks like msix_unset_vector_notifiers is being called twice, once
> from vu_scmi_set_status() and another from vu_scmi_disconnect():

Interesting.  Usually, vu_scmi_stop is called only once, which explains
why the test regularly passes.  Both the vu_scmi_stop callers have a
check protecting from duplicate vu_scmi_stop calls but it's perhaps not
fully reliable.  I can see vhost-user-gpio has an extra protection.
I'll post a patch adding a similar thing, hopefully it will fix the
problem.

> msix_unset_vector_notifiers
> virtio_pci_set_guest_notifiers
> vu_scmi_stop
> vu_scmi_disconnect   <-
> vu_scmi_event
> chr_be_event
> qemu_chr_be_event
> tcp_chr_disconnect_locked
> tcp_chr_write
> qemu_chr_write_buffer
>
> msix_unset_vector_notifiers
> virtio_pci_set_guest_notifiers
> vu_scmi_stop
> vu_scmi_set_status   <-
> virtio_set_status
> virtio_vmstate_change
> vm_state_notify
> do_vm_stop
> vm_shutdown
> qemu_cleanup
Thomas Huth July 20, 2023, 8:40 a.m. UTC | #7
On 19/07/2023 21.56, Milan Zamazal wrote:
> Thomas Huth <thuth@redhat.com> writes:
> 
>> On 18/07/2023 14.55, Milan Zamazal wrote:
>>> Thomas Huth <thuth@redhat.com> writes:
>>>
>>
>>>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>>>> From: Milan Zamazal <mzamazal@redhat.com>
>>>>> We don't have a virtio-scmi implementation in QEMU and only support
>>>>
>>>>> a
>>>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>>>> set of tests, just passing some vhost-user messages over the control socket.
>>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>>> ---
>>>>>     tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>>>     tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>>>     tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>>>     MAINTAINERS                      |   1 +
>>>>>     tests/qtest/libqos/meson.build   |   1 +
>>>>>     5 files changed, 254 insertions(+)
>>>>>     create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>>>     create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>>>
>>>>    Hi!
>>>>
>>>> I'm seeing some random failures with this new scmi test, so far only
>>>> on non-x86 systems, e.g.:
>>>>
>>>>    https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>>>
>>>> It also reproduces on a s390x host here, but only if I run "make check
>>>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>>>> there. Seems like there is a race somewhere in this test?
>>> Hmm, it's basically the same as virtio-gpio.c test, so it should be
>>> OK.
>>> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
>>> interfere with each other in some way?  Is there possibly a way to
>>> serialize them to check?
>>
>> I think within one qos-test, the sub-tests are already run
>> serialized.
> 
> I see, OK.
> 
>> But there might be multiple qos-tests running in parallel, e.g. one
>> for the aarch64 target and one for the ppc64 target. And indeed, I can
>> reproduce the problem on my x86 laptop by running this in one terminal
>> window:
>>
>> for ((x=0;x<1000;x++)); do \
>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>   QTEST_QEMU_BINARY=./qemu-system-ppc64 \
>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>   tests/qtest/qos-test -p \
>>   /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>> \
>>   || break ; \
>> done
>>
>> And this in another terminal window at the same time:
>>
>> for ((x=0;x<1000;x++)); do \
>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>   QTEST_QEMU_BINARY=./qemu-system-aarch64 \
>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>   tests/qtest/qos-test -p \
>>   /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>> \
>>   || break ; \
>> done
>>
>> After a while, the aarch64 test broke with:
>>
>> /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile:
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost_set_vring_call failed 22
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost_set_vring_call failed 22
>> qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: Failed to set msg fds.
>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>> qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659:
>> msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier
>> && dev->msix_vector_release_notifier' failed.
>> ../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected QEMU
>> death from signal 6 (Aborted) (core dumped)
>> **
>> ERROR:../../devel/qemu/tests/qtest/qos-test.c:191:subprocess_run_one_test:
>> child process
>> (/aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile/subprocess
>> [488457]) failed unexpectedly
>> Aborted (core dumped)
> 
> Interesting, good discovery.
> 
>> Can you also reproduce it this way?
> 
> Unfortunately not.  I ran the loops several times and everything passed.
> I tried to compile and run it in a different distro container and it
> passed too.  I also haven't been successful in getting any idea how the
> processes could influence each other.
> 
> What OS and what QEMU configure flags did you use to compile and run it?

I'm using RHEL 8 on an older laptop ... and maybe the latter is related: I 
just noticed that I can also reproduce the problem by just running one of 
the above two for-loop while putting a lot of load on the machine otherwise, 
e.g. by running a "make -j$(nproc)" to rebuild the whole QEMU sources. So 
it's definitely a race *within* one QEMU process.

  Thomas
Milan Zamazal July 20, 2023, 9:25 a.m. UTC | #8
Thomas Huth <thuth@redhat.com> writes:

> On 19/07/2023 21.56, Milan Zamazal wrote:
>> Thomas Huth <thuth@redhat.com> writes:
>> 
>
>>> On 18/07/2023 14.55, Milan Zamazal wrote:
>>>> Thomas Huth <thuth@redhat.com> writes:
>>>>
>>>
>>>>> On 11/07/2023 01.02, Michael S. Tsirkin wrote:
>>>>>> From: Milan Zamazal <mzamazal@redhat.com>
>>>>>> We don't have a virtio-scmi implementation in QEMU and only support
>>>>>
>>>>>> a
>>>>>> vhost-user backend.  This is very similar to virtio-gpio and we add the same
>>>>>> set of tests, just passing some vhost-user messages over the control socket.
>>>>>> Signed-off-by: Milan Zamazal <mzamazal@redhat.com>
>>>>>> Acked-by: Thomas Huth <thuth@redhat.com>
>>>>>> Message-Id: <20230628100524.342666-4-mzamazal@redhat.com>
>>>>>> Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
>>>>>> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
>>>>>> ---
>>>>>>     tests/qtest/libqos/virtio-scmi.h |  34 ++++++
>>>>>>     tests/qtest/libqos/virtio-scmi.c | 174 +++++++++++++++++++++++++++++++
>>>>>>     tests/qtest/vhost-user-test.c    |  44 ++++++++
>>>>>>     MAINTAINERS                      |   1 +
>>>>>>     tests/qtest/libqos/meson.build   |   1 +
>>>>>>     5 files changed, 254 insertions(+)
>>>>>>     create mode 100644 tests/qtest/libqos/virtio-scmi.h
>>>>>>     create mode 100644 tests/qtest/libqos/virtio-scmi.c
>>>>>
>>>>>    Hi!
>>>>>
>>>>> I'm seeing some random failures with this new scmi test, so far only
>>>>> on non-x86 systems, e.g.:
>>>>>
>>>>>    https://app.travis-ci.com/github/huth/qemu/jobs/606246131#L4774
>>>>>
>>>>> It also reproduces on a s390x host here, but only if I run "make check
>>>>> -j$(nproc)" - if I run the tests single-threaded, the qos-test passes
>>>>> there. Seems like there is a race somewhere in this test?
>>>> Hmm, it's basically the same as virtio-gpio.c test, so it should be
>>>> OK.
>>>> Is it possible that the two tests (virtio-gpio.c & virtio-scmi.c)
>>>> interfere with each other in some way?  Is there possibly a way to
>>>> serialize them to check?
>>>
>>> I think within one qos-test, the sub-tests are already run
>>> serialized.
>> I see, OK.
>> 
>>> But there might be multiple qos-tests running in parallel, e.g. one
>>> for the aarch64 target and one for the ppc64 target. And indeed, I can
>>> reproduce the problem on my x86 laptop by running this in one terminal
>>> window:
>>>
>>> for ((x=0;x<1000;x++)); do \
>>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>>   QTEST_QEMU_BINARY=./qemu-system-ppc64 \
>>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>>   tests/qtest/qos-test -p \
>>>   /ppc64/pseries/spapr-pci-host-bridge/pci-bus-spapr/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>>> \
>>>   || break ; \
>>> done
>>>
>>> And this in another terminal window at the same time:
>>>
>>> for ((x=0;x<1000;x++)); do \
>>>   QTEST_QEMU_STORAGE_DAEMON_BINARY=./storage-daemon/qemu-storage-daemon \
>>>   G_TEST_DBUS_DAEMON=.tests/dbus-vmstate-daemon.sh \
>>>   QTEST_QEMU_BINARY=./qemu-system-aarch64 \
>>>   MALLOC_PERTURB_=188 QTEST_QEMU_IMG=./qemu-img \
>>>   tests/qtest/qos-test -p \
>>>   /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile
>>> \
>>>   || break ; \
>>> done
>>>
>>> After a while, the aarch64 test broke with:
>>>
>>> /aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile:
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost_set_vring_call failed 22
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost_set_vring_call failed 22
>>> qemu-system-aarch64: Failed to write msg. Wrote -1 instead of 20.
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost VQ 0 ring restore failed: -22: Invalid argument (22)
>>> qemu-system-aarch64: Failed to set msg fds.
>>> qemu-system-aarch64: vhost VQ 1 ring restore failed: -22: Invalid argument (22)
>>> qemu-system-aarch64: ../../devel/qemu/hw/pci/msix.c:659:
>>> msix_unset_vector_notifiers: Assertion `dev->msix_vector_use_notifier
>>> && dev->msix_vector_release_notifier' failed.
>>> ../../devel/qemu/tests/qtest/libqtest.c:200: kill_qemu() detected QEMU
>>> death from signal 6 (Aborted) (core dumped)
>>> **
>>> ERROR:../../devel/qemu/tests/qtest/qos-test.c:191:subprocess_run_one_test:
>>> child process
>>> (/aarch64/virt/generic-pcihost/pci-bus-generic/pci-bus/vhost-user-scmi-pci/vhost-user-scmi/vhost-user-scmi-tests/scmi/read-guest-mem/memfile/subprocess
>>> [488457]) failed unexpectedly
>>> Aborted (core dumped)
>> Interesting, good discovery.
>> 
>>> Can you also reproduce it this way?
>> Unfortunately not.  I ran the loops several times and everything
>> passed.
>> I tried to compile and run it in a different distro container and it
>> passed too.  I also haven't been successful in getting any idea how the
>> processes could influence each other.
>> What OS and what QEMU configure flags did you use to compile and run
>> it?
>
> I'm using RHEL 8 on an older laptop ... and maybe the latter is
> related: I just noticed that I can also reproduce the problem by just
> running one of the above two for-loop while putting a lot of load on
> the machine otherwise, e.g. by running a "make -j$(nproc)" to rebuild
> the whole QEMU sources. So it's definitely a race *within* one QEMU
> process.

Ah, great, now I can easily reproduce it by running kernel compilation
in the background.  And I could also check that the supposed fix
remedies the problem.  I'll post the patch soon.

Thank you,
Milan
diff mbox series

Patch

diff --git a/tests/qtest/libqos/virtio-scmi.h b/tests/qtest/libqos/virtio-scmi.h
new file mode 100644
index 0000000000..cb5670da6e
--- /dev/null
+++ b/tests/qtest/libqos/virtio-scmi.h
@@ -0,0 +1,34 @@ 
+/*
+ * virtio-scmi structures
+ *
+ * SPDX-FileCopyrightText: Red Hat, Inc.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#ifndef TESTS_LIBQOS_VIRTIO_SCMI_H
+#define TESTS_LIBQOS_VIRTIO_SCMI_H
+
+#include "qgraph.h"
+#include "virtio.h"
+#include "virtio-pci.h"
+
+typedef struct QVhostUserSCMI QVhostUserSCMI;
+typedef struct QVhostUserSCMIPCI QVhostUserSCMIPCI;
+typedef struct QVhostUserSCMIDevice QVhostUserSCMIDevice;
+
+struct QVhostUserSCMI {
+    QVirtioDevice *vdev;
+    QVirtQueue **queues;
+};
+
+struct QVhostUserSCMIPCI {
+    QVirtioPCIDevice pci_vdev;
+    QVhostUserSCMI scmi;
+};
+
+struct QVhostUserSCMIDevice {
+    QOSGraphObject obj;
+    QVhostUserSCMI scmi;
+};
+
+#endif
diff --git a/tests/qtest/libqos/virtio-scmi.c b/tests/qtest/libqos/virtio-scmi.c
new file mode 100644
index 0000000000..ce8f4d5c06
--- /dev/null
+++ b/tests/qtest/libqos/virtio-scmi.c
@@ -0,0 +1,174 @@ 
+/*
+ * virtio-scmi nodes for testing
+ *
+ * SPDX-FileCopyrightText: Linaro Ltd
+ * SPDX-FileCopyrightText: Red Hat, Inc.
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Based on virtio-gpio.c, doing basically the same thing.
+ */
+
+#include "qemu/osdep.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "../libqtest.h"
+#include "qemu/module.h"
+#include "qgraph.h"
+#include "virtio-scmi.h"
+
+static QGuestAllocator *alloc;
+
+static void virtio_scmi_cleanup(QVhostUserSCMI *scmi)
+{
+    QVirtioDevice *vdev = scmi->vdev;
+    int i;
+
+    for (i = 0; i < 2; i++) {
+        qvirtqueue_cleanup(vdev->bus, scmi->queues[i], alloc);
+    }
+    g_free(scmi->queues);
+}
+
+/*
+ * This handles the VirtIO setup from the point of view of the driver
+ * frontend and therefore doesn't present any vhost specific features
+ * and in fact masks of the re-used bit.
+ */
+static void virtio_scmi_setup(QVhostUserSCMI *scmi)
+{
+    QVirtioDevice *vdev = scmi->vdev;
+    uint64_t features;
+    int i;
+
+    features = qvirtio_get_features(vdev);
+    features &= ~QVIRTIO_F_BAD_FEATURE;
+    qvirtio_set_features(vdev, features);
+
+    scmi->queues = g_new(QVirtQueue *, 2);
+    for (i = 0; i < 2; i++) {
+        scmi->queues[i] = qvirtqueue_setup(vdev, alloc, i);
+    }
+    qvirtio_set_driver_ok(vdev);
+}
+
+static void *qvirtio_scmi_get_driver(QVhostUserSCMI *v_scmi,
+                                     const char *interface)
+{
+    if (!g_strcmp0(interface, "vhost-user-scmi")) {
+        return v_scmi;
+    }
+    if (!g_strcmp0(interface, "virtio")) {
+        return v_scmi->vdev;
+    }
+
+    g_assert_not_reached();
+}
+
+static void *qvirtio_scmi_device_get_driver(void *object,
+                                            const char *interface)
+{
+    QVhostUserSCMIDevice *v_scmi = object;
+    return qvirtio_scmi_get_driver(&v_scmi->scmi, interface);
+}
+
+/* virtio-scmi (mmio) */
+static void qvirtio_scmi_device_destructor(QOSGraphObject *obj)
+{
+    QVhostUserSCMIDevice *scmi_dev = (QVhostUserSCMIDevice *) obj;
+    virtio_scmi_cleanup(&scmi_dev->scmi);
+}
+
+static void qvirtio_scmi_device_start_hw(QOSGraphObject *obj)
+{
+    QVhostUserSCMIDevice *scmi_dev = (QVhostUserSCMIDevice *) obj;
+    virtio_scmi_setup(&scmi_dev->scmi);
+}
+
+static void *virtio_scmi_device_create(void *virtio_dev,
+                                       QGuestAllocator *t_alloc,
+                                       void *addr)
+{
+    QVhostUserSCMIDevice *virtio_device = g_new0(QVhostUserSCMIDevice, 1);
+    QVhostUserSCMI *interface = &virtio_device->scmi;
+
+    interface->vdev = virtio_dev;
+    alloc = t_alloc;
+
+    virtio_device->obj.get_driver = qvirtio_scmi_device_get_driver;
+    virtio_device->obj.start_hw = qvirtio_scmi_device_start_hw;
+    virtio_device->obj.destructor = qvirtio_scmi_device_destructor;
+
+    return &virtio_device->obj;
+}
+
+/* virtio-scmi-pci */
+static void qvirtio_scmi_pci_destructor(QOSGraphObject *obj)
+{
+    QVhostUserSCMIPCI *scmi_pci = (QVhostUserSCMIPCI *) obj;
+    QOSGraphObject *pci_vobj =  &scmi_pci->pci_vdev.obj;
+
+    virtio_scmi_cleanup(&scmi_pci->scmi);
+    qvirtio_pci_destructor(pci_vobj);
+}
+
+static void qvirtio_scmi_pci_start_hw(QOSGraphObject *obj)
+{
+    QVhostUserSCMIPCI *scmi_pci = (QVhostUserSCMIPCI *) obj;
+    QOSGraphObject *pci_vobj =  &scmi_pci->pci_vdev.obj;
+
+    qvirtio_pci_start_hw(pci_vobj);
+    virtio_scmi_setup(&scmi_pci->scmi);
+}
+
+static void *qvirtio_scmi_pci_get_driver(void *object, const char *interface)
+{
+    QVhostUserSCMIPCI *v_scmi = object;
+
+    if (!g_strcmp0(interface, "pci-device")) {
+        return v_scmi->pci_vdev.pdev;
+    }
+    return qvirtio_scmi_get_driver(&v_scmi->scmi, interface);
+}
+
+static void *virtio_scmi_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+                                    void *addr)
+{
+    QVhostUserSCMIPCI *virtio_spci = g_new0(QVhostUserSCMIPCI, 1);
+    QVhostUserSCMI *interface = &virtio_spci->scmi;
+    QOSGraphObject *obj = &virtio_spci->pci_vdev.obj;
+
+    virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr);
+    interface->vdev = &virtio_spci->pci_vdev.vdev;
+    alloc = t_alloc;
+
+    obj->get_driver = qvirtio_scmi_pci_get_driver;
+    obj->start_hw = qvirtio_scmi_pci_start_hw;
+    obj->destructor = qvirtio_scmi_pci_destructor;
+
+    return obj;
+}
+
+static void virtio_scmi_register_nodes(void)
+{
+    QPCIAddress addr = {
+        .devfn = QPCI_DEVFN(4, 0),
+    };
+
+    QOSGraphEdgeOptions edge_opts = { };
+
+    /* vhost-user-scmi-device */
+    edge_opts.extra_device_opts = "id=scmi,chardev=chr-vhost-user-test "
+        "-global virtio-mmio.force-legacy=false";
+    qos_node_create_driver("vhost-user-scmi-device",
+                            virtio_scmi_device_create);
+    qos_node_consumes("vhost-user-scmi-device", "virtio-bus", &edge_opts);
+    qos_node_produces("vhost-user-scmi-device", "vhost-user-scmi");
+
+    /* virtio-scmi-pci */
+    edge_opts.extra_device_opts = "id=scmi,addr=04.0,chardev=chr-vhost-user-test";
+    add_qpci_address(&edge_opts, &addr);
+    qos_node_create_driver("vhost-user-scmi-pci", virtio_scmi_pci_create);
+    qos_node_consumes("vhost-user-scmi-pci", "pci-bus", &edge_opts);
+    qos_node_produces("vhost-user-scmi-pci", "vhost-user-scmi");
+}
+
+libqos_init(virtio_scmi_register_nodes);
diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
index dfb8003597..d4e437265f 100644
--- a/tests/qtest/vhost-user-test.c
+++ b/tests/qtest/vhost-user-test.c
@@ -33,6 +33,7 @@ 
 #include "standard-headers/linux/virtio_ids.h"
 #include "standard-headers/linux/virtio_net.h"
 #include "standard-headers/linux/virtio_gpio.h"
+#include "standard-headers/linux/virtio_scmi.h"
 
 #ifdef CONFIG_LINUX
 #include <sys/vfs.h>
@@ -145,6 +146,7 @@  enum {
 enum {
     VHOST_USER_NET,
     VHOST_USER_GPIO,
+    VHOST_USER_SCMI,
 };
 
 typedef struct TestServer {
@@ -1157,3 +1159,45 @@  static void register_vhost_gpio_test(void)
                  "vhost-user-gpio", test_read_guest_mem, &opts);
 }
 libqos_init(register_vhost_gpio_test);
+
+static uint64_t vu_scmi_get_features(TestServer *s)
+{
+    return 0x1ULL << VIRTIO_F_VERSION_1 |
+        0x1ULL << VIRTIO_SCMI_F_P2A_CHANNELS |
+        0x1ULL << VHOST_USER_F_PROTOCOL_FEATURES;
+}
+
+static void vu_scmi_get_protocol_features(TestServer *s, CharBackend *chr,
+                                          VhostUserMsg *msg)
+{
+    msg->flags |= VHOST_USER_REPLY_MASK;
+    msg->size = sizeof(m.payload.u64);
+    msg->payload.u64 = 1ULL << VHOST_USER_PROTOCOL_F_MQ;
+
+    qemu_chr_fe_write_all(chr, (uint8_t *)msg, VHOST_USER_HDR_SIZE + msg->size);
+}
+
+static struct vhost_user_ops g_vu_scmi_ops = {
+    .type = VHOST_USER_SCMI,
+
+    .append_opts = append_vhost_gpio_opts,
+
+    .get_features = vu_scmi_get_features,
+    .set_features = vu_net_set_features,
+    .get_protocol_features = vu_scmi_get_protocol_features,
+};
+
+static void register_vhost_scmi_test(void)
+{
+    QOSGraphTestOptions opts = {
+        .before = vhost_user_test_setup,
+        .subprocess = true,
+        .arg = &g_vu_scmi_ops,
+    };
+
+    qemu_add_opts(&qemu_chardev_opts);
+
+    qos_add_test("scmi/read-guest-mem/memfile",
+                 "vhost-user-scmi", test_read_guest_mem, &opts);
+}
+libqos_init(register_vhost_scmi_test);
diff --git a/MAINTAINERS b/MAINTAINERS
index 504dddb7dd..8f642141d0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2222,6 +2222,7 @@  R: mzamazal@redhat.com
 S: Supported
 F: hw/virtio/vhost-user-scmi*
 F: include/hw/virtio/vhost-user-scmi.h
+F: tests/qtest/libqos/virtio-scmi.*
 
 virtio-crypto
 M: Gonglei <arei.gonglei@huawei.com>
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index cc209a8de5..90aae42a22 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -46,6 +46,7 @@  libqos_srcs = files(
         'virtio-serial.c',
         'virtio-iommu.c',
         'virtio-gpio.c',
+        'virtio-scmi.c',
         'generic-pcihost.c',
 
         # qgraph machines: