(expanding the CC list for help, anyone have a better idea about how
vhost-user qtests should work/see obvious issues with this patch?)

Alex Bennée <alex.ben...@linaro.org> writes:

> We don't have a virtio-gpio implementation in QEMU and only
> support a vhost-user backend. The QEMU side of the code is minimal so
> it should be enough to instantiate the device and pass some vhost-user
> messages over the control socket. To do this we hook into the existing
> vhost-user-test code and just add the bits required for gpio.
>
> Based-on: 20220118203833.316741-1-eric.au...@redhat.com
> Signed-off-by: Alex Bennée <alex.ben...@linaro.org>
> Cc: Viresh Kumar <viresh.ku...@linaro.org>
> Cc: Paolo Bonzini <pbonz...@redhat.com>
>
> ---
>
> This goes as far as to add things to the QOS tree but so far it's
> failing to properly start QEMU with the chardev socket needed to
> communicate between the mock vhost-user daemon and QEMU itself.
> ---
>  tests/qtest/libqos/virtio-gpio.h | 34 +++++++++++
>  tests/qtest/libqos/virtio-gpio.c | 98 ++++++++++++++++++++++++++++++++
>  tests/qtest/vhost-user-test.c    | 34 +++++++++++
>  tests/qtest/libqos/meson.build   |  1 +
>  4 files changed, 167 insertions(+)
>  create mode 100644 tests/qtest/libqos/virtio-gpio.h
>  create mode 100644 tests/qtest/libqos/virtio-gpio.c
>
> diff --git a/tests/qtest/libqos/virtio-gpio.h 
> b/tests/qtest/libqos/virtio-gpio.h
> new file mode 100644
> index 0000000000..abe6967ae9
> --- /dev/null
> +++ b/tests/qtest/libqos/virtio-gpio.h
> @@ -0,0 +1,34 @@
> +/*
> + * virtio-gpio structures
> + *
> + * Copyright (c) 2022 Linaro Ltd
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#ifndef TESTS_LIBQOS_VIRTIO_GPIO_H
> +#define TESTS_LIBQOS_VIRTIO_GPIO_H
> +
> +#include "qgraph.h"
> +#include "virtio.h"
> +#include "virtio-pci.h"
> +
> +typedef struct QVhostUserGPIO QVhostUserGPIO;
> +typedef struct QVhostUserGPIOPCI QVhostUserGPIOPCI;
> +typedef struct QVhostUserGPIODevice QVhostUserGPIODevice;
> +
> +struct QVhostUserGPIO {
> +    QVirtioDevice *vdev;
> +};
> +
> +struct QVhostUserGPIOPCI {
> +    QVirtioPCIDevice pci_vdev;
> +    QVhostUserGPIO gpio;
> +};
> +
> +struct QVhostUserGPIODevice {
> +    QOSGraphObject obj;
> +    QVhostUserGPIO gpio;
> +};
> +
> +#endif
> diff --git a/tests/qtest/libqos/virtio-gpio.c 
> b/tests/qtest/libqos/virtio-gpio.c
> new file mode 100644
> index 0000000000..62c8074777
> --- /dev/null
> +++ b/tests/qtest/libqos/virtio-gpio.c
> @@ -0,0 +1,98 @@
> +/*
> + * virtio-gpio nodes for testing
> + *
> + * Copyright (c) 2022 Linaro Ltd
> + *
> + * SPDX-License-Identifier: GPL-2.0-or-later
> + */
> +
> +#include "qemu/osdep.h"
> +#include "libqtest.h"
> +#include "qemu/module.h"
> +#include "qgraph.h"
> +#include "virtio-gpio.h"
> +
> +static void *qvirtio_gpio_get_driver(QVhostUserGPIO *v_gpio,
> +                                       const char *interface)
> +{
> +    if (!g_strcmp0(interface, "vhost-user-gpio")) {
> +        return v_gpio;
> +    }
> +    if (!g_strcmp0(interface, "virtio")) {
> +        return v_gpio->vdev;
> +    }
> +
> +    fprintf(stderr, "%s not present in virtio-gpio-device\n", interface);
> +    g_assert_not_reached();
> +}
> +
> +static void *qvirtio_gpio_device_get_driver(void *object,
> +                                              const char *interface)
> +{
> +    QVhostUserGPIODevice *v_gpio = object;
> +    return qvirtio_gpio_get_driver(&v_gpio->gpio, interface);
> +}
> +
> +static void *virtio_gpio_device_create(void *virtio_dev,
> +                                         QGuestAllocator *t_alloc,
> +                                         void *addr)
> +{
> +    QVhostUserGPIODevice *virtio_device = g_new0(QVhostUserGPIODevice, 1);
> +    QVhostUserGPIO *interface = &virtio_device->gpio;
> +
> +    interface->vdev = virtio_dev;
> +
> +    virtio_device->obj.get_driver = qvirtio_gpio_device_get_driver;
> +
> +    return &virtio_device->obj;
> +}
> +
> +/* virtio-gpio-pci */
> +static void *qvirtio_gpio_pci_get_driver(void *object, const char *interface)
> +{
> +    QVhostUserGPIOPCI *v_gpio = object;
> +    if (!g_strcmp0(interface, "pci-device")) {
> +        return v_gpio->pci_vdev.pdev;
> +    }
> +    return qvirtio_gpio_get_driver(&v_gpio->gpio, interface);
> +}
> +
> +static void *virtio_gpio_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
> +                                      void *addr)
> +{
> +    QVhostUserGPIOPCI *virtio_spci = g_new0(QVhostUserGPIOPCI, 1);
> +    QVhostUserGPIO *interface = &virtio_spci->gpio;
> +    QOSGraphObject *obj = &virtio_spci->pci_vdev.obj;
> +
> +    virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr);
> +    interface->vdev = &virtio_spci->pci_vdev.vdev;
> +
> +    obj->get_driver = qvirtio_gpio_pci_get_driver;
> +
> +    return obj;
> +}
> +
> +static void virtio_gpio_register_nodes(void)
> +{
> +    QPCIAddress addr = {
> +        .devfn = QPCI_DEVFN(4, 0),
> +    };
> +
> +    QOSGraphEdgeOptions edge_opts = { };
> +
> +    /* vhost-user-gpio-device */
> +    edge_opts.extra_device_opts = "id=gpio0,chardev=vhgpio0";
> +    qos_node_create_driver("vhost-user-gpio-device",
> +                            virtio_gpio_device_create);
> +    qos_node_consumes("vhost-user-gpio-device", "virtio-bus", &edge_opts);
> +    qos_node_produces("vhost-user-gpio-device", "vhost-user-gpio");
> +
> +    /* virtio-gpio-pci */
> +    edge_opts.extra_device_opts = "id=gpio0,addr=04.0,chardev=vhgpio0";
> +    add_qpci_address(&edge_opts, &addr);
> +    qos_node_create_driver("vhost-user-gpio-pci", virtio_gpio_pci_create);
> +    qos_node_consumes("vhost-user-gpio-pci", "pci-bus", &edge_opts);
> +    qos_node_produces("vhost-user-gpio-pci", "vhost-user-gpio");
> +}
> +
> +libqos_init(virtio_gpio_register_nodes);
> diff --git a/tests/qtest/vhost-user-test.c b/tests/qtest/vhost-user-test.c
> index ee30f54796..4f8789424b 100644
> --- a/tests/qtest/vhost-user-test.c
> +++ b/tests/qtest/vhost-user-test.c
> @@ -43,6 +43,7 @@
>                          " -numa node,memdev=mem"
>  #define QEMU_CMD_CHR    " -chardev socket,id=%s,path=%s%s"
>  #define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce=on"
> +#define QEMU_CMD_GPIO   " -device 
> vhost-user-gpio-pci,id=gpio0,chardev=%s,vhostforce=on"
>  
>  #define HUGETLBFS_MAGIC       0x958458f6
>  
> @@ -137,6 +138,7 @@ enum {
>  
>  enum {
>      VHOST_USER_NET,
> +    VHOST_USER_GPIO,
>  };
>  
>  typedef struct TestServer {
> @@ -194,6 +196,14 @@ static void append_vhost_net_opts(TestServer *s, GString 
> *cmd_line,
>                             chr_opts, s->chr_name);
>  }
>  
> +static void append_vhost_gpio_opts(TestServer *s, GString *cmd_line,
> +                             const char *chr_opts)
> +{
> +    g_string_append_printf(cmd_line, QEMU_CMD_CHR QEMU_CMD_GPIO,
> +                           s->chr_name, s->socket_path,
> +                           chr_opts, s->chr_name);
> +}
> +
>  static void append_mem_opts(TestServer *server, GString *cmd_line,
>                              int size, enum test_memfd memfd)
>  {
> @@ -1014,3 +1024,27 @@ static void register_vhost_user_test(void)
>                   test_multiqueue, &opts);
>  }
>  libqos_init(register_vhost_user_test);
> +
> +static struct vhost_user_ops g_vu_gpio_ops = {
> +    .type = VHOST_USER_GPIO,
> +
> +    .append_opts = append_vhost_gpio_opts,
> +
> +    .set_features = vu_net_set_features,
> +    .get_protocol_features = vu_net_get_protocol_features,
> +};
> +
> +static void register_vhost_gpio_test(void)
> +{
> +    QOSGraphTestOptions opts = {
> +        .before = vhost_user_test_setup,
> +        .subprocess = true,
> +        .arg = &g_vu_gpio_ops,
> +    };
> +
> +    qemu_add_opts(&qemu_chardev_opts);
> +
> +    qos_add_test("read-guest-mem/memfile",
> +                 "vhost-user-gpio", test_read_guest_mem, &opts);
> +}
> +libqos_init(register_vhost_gpio_test);
> diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
> index 8c8ee15553..f581330d8b 100644
> --- a/tests/qtest/libqos/meson.build
> +++ b/tests/qtest/libqos/meson.build
> @@ -42,6 +42,7 @@ libqos_srcs = files('../libqtest.c',
>          'virtio-scsi.c',
>          'virtio-serial.c',
>          'virtio-iommu.c',
> +        'virtio-gpio.c',
>          'generic-pcihost.c',
>  
>          # qgraph machines:


-- 
Alex Bennée

Reply via email to