All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/3] Input 20190522 patches
@ 2019-05-22  8:27 Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 1/3] libvhost-user: fix cast warnings on 32 bits Gerd Hoffmann
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2019-05-22  8:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann, Michael S. Tsirkin

The following changes since commit a4f667b6714916683408b983cfe0a615a725775f:

  Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3' into staging (2019-05-21 16:30:13 +0100)

are available in the Git repository at:

  git://git.kraxel.org/qemu tags/input-20190522-pull-request

for you to fetch changes up to 06914c97d3ade856371c9a59cbe6a9b13422471f:

  contrib: add vhost-user-input (2019-05-22 07:16:58 +0200)

----------------------------------------------------------------
input: add vhost-user-input to contrib.

----------------------------------------------------------------

Marc-André Lureau (3):
  libvhost-user: fix cast warnings on 32 bits
  libvhost-user: fix -Werror=format= on ppc64
  contrib: add vhost-user-input

 Makefile                               |  11 +
 Makefile.objs                          |   1 +
 contrib/libvhost-user/libvhost-user.c  |  12 +-
 contrib/vhost-user-input/main.c        | 393 +++++++++++++++++++++++++
 MAINTAINERS                            |   1 +
 contrib/vhost-user-input/Makefile.objs |   1 +
 6 files changed, 414 insertions(+), 5 deletions(-)
 create mode 100644 contrib/vhost-user-input/main.c
 create mode 100644 contrib/vhost-user-input/Makefile.objs

-- 
2.18.1



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL 1/3] libvhost-user: fix cast warnings on 32 bits
  2019-05-22  8:27 [Qemu-devel] [PULL 0/3] Input 20190522 patches Gerd Hoffmann
@ 2019-05-22  8:27 ` Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 2/3] libvhost-user: fix -Werror=format= on ppc64 Gerd Hoffmann
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2019-05-22  8:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann, Michael S. Tsirkin

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Fixes warnings:
 warning: cast to pointer from integer of different size
 [-Wint-to-pointer-cast]

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190514104126.6294-2-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/libvhost-user/libvhost-user.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 3825b1cacff5..0ffa0f45c890 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -621,7 +621,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
          * data that's already arrived in the shared process.
          * TODO: How to do hugepage
          */
-        ret = madvise((void *)dev_region->mmap_addr,
+        ret = madvise((void *)(uintptr_t)dev_region->mmap_addr,
                       dev_region->size + dev_region->mmap_offset,
                       MADV_DONTNEED);
         if (ret) {
@@ -633,7 +633,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
          * in neighbouring pages.
          * TODO: Turn this backon later.
          */
-        ret = madvise((void *)dev_region->mmap_addr,
+        ret = madvise((void *)(uintptr_t)dev_region->mmap_addr,
                       dev_region->size + dev_region->mmap_offset,
                       MADV_NOHUGEPAGE);
         if (ret) {
@@ -666,7 +666,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
         DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
                 __func__, i, reg_struct.range.start, reg_struct.range.len);
         /* Now it's registered we can let the client at it */
-        if (mprotect((void *)dev_region->mmap_addr,
+        if (mprotect((void *)(uintptr_t)dev_region->mmap_addr,
                      dev_region->size + dev_region->mmap_offset,
                      PROT_READ | PROT_WRITE)) {
             vu_panic(dev, "failed to mprotect region %d for postcopy (%s)",
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL 2/3] libvhost-user: fix -Werror=format= on ppc64
  2019-05-22  8:27 [Qemu-devel] [PULL 0/3] Input 20190522 patches Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 1/3] libvhost-user: fix cast warnings on 32 bits Gerd Hoffmann
@ 2019-05-22  8:27 ` Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input Gerd Hoffmann
  2019-05-23 10:21 ` [Qemu-devel] [PULL 0/3] Input 20190522 patches Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Gerd Hoffmann @ 2019-05-22  8:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann, Michael S. Tsirkin

From: Marc-André Lureau <marcandre.lureau@redhat.com>

That should fix the following warning:

/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c: In function
‘vu_set_mem_table_exec_postcopy’:
/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c:666:9: error:
format ‘%llx’ expects argument of type ‘long long unsigned int’, but
argument 5 has type ‘__u64’ [-Werror=format=]
         DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
         ^
/home/pm215/qemu/contrib/libvhost-user/libvhost-user.c:666:9: error:
format ‘%llx’ expects argument of type ‘long long unsigned int’, but
argument 6 has type ‘__u64’ [-Werror=format=]
cc1: all warnings being treated as errors

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Message-id: 20190514104126.6294-3-marcandre.lureau@redhat.com

{ kraxel: s/PRIu64/PRIx64/ ]

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 contrib/libvhost-user/libvhost-user.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 0ffa0f45c890..c56f2dfe44a4 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -663,8 +663,10 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserMsg *vmsg)
                      __func__, i);
             return false;
         }
-        DPRINT("%s: region %d: Registered userfault for %llx + %llx\n",
-                __func__, i, reg_struct.range.start, reg_struct.range.len);
+        DPRINT("%s: region %d: Registered userfault for %"
+               PRIx64 " + %" PRIx64 "\n", __func__, i,
+               (uint64_t)reg_struct.range.start,
+               (uint64_t)reg_struct.range.len);
         /* Now it's registered we can let the client at it */
         if (mprotect((void *)(uintptr_t)dev_region->mmap_addr,
                      dev_region->size + dev_region->mmap_offset,
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input
  2019-05-22  8:27 [Qemu-devel] [PULL 0/3] Input 20190522 patches Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 1/3] libvhost-user: fix cast warnings on 32 bits Gerd Hoffmann
  2019-05-22  8:27 ` [Qemu-devel] [PULL 2/3] libvhost-user: fix -Werror=format= on ppc64 Gerd Hoffmann
@ 2019-05-22  8:27 ` Gerd Hoffmann
  2019-05-30 11:16   ` Peter Maydell
  2019-05-23 10:21 ` [Qemu-devel] [PULL 0/3] Input 20190522 patches Peter Maydell
  3 siblings, 1 reply; 7+ messages in thread
From: Gerd Hoffmann @ 2019-05-22  8:27 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Gerd Hoffmann, Michael S. Tsirkin

From: Marc-André Lureau <marcandre.lureau@redhat.com>

Add a vhost-user input backend example, based on virtio-input-host
device. It takes an evdev path as argument, and can be associated with
a vhost-user-input device via a UNIX socket:

$ vhost-user-input -p /dev/input/eventX -s /tmp/vui.sock

$ qemu ... -chardev socket,id=vuic,path=/tmp/vui.sock
  -device vhost-user-input-pci,chardev=vuic

This example is intentionally not included in $TOOLS, and not
installed by default.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20190514104126.6294-4-marcandre.lureau@redhat.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 Makefile                               |  11 +
 Makefile.objs                          |   1 +
 contrib/vhost-user-input/main.c        | 393 +++++++++++++++++++++++++
 MAINTAINERS                            |   1 +
 contrib/vhost-user-input/Makefile.objs |   1 +
 5 files changed, 407 insertions(+)
 create mode 100644 contrib/vhost-user-input/main.c
 create mode 100644 contrib/vhost-user-input/Makefile.objs

diff --git a/Makefile b/Makefile
index 155f066a206f..8598ab9ec482 100644
--- a/Makefile
+++ b/Makefile
@@ -408,6 +408,7 @@ dummy := $(call unnest-vars,, \
                 libvhost-user-obj-y \
                 vhost-user-scsi-obj-y \
                 vhost-user-blk-obj-y \
+                vhost-user-input-obj-y \
                 qga-vss-dll-obj-y \
                 block-obj-y \
                 block-obj-m \
@@ -618,6 +619,16 @@ rdmacm-mux$(EXESUF): LIBS += "-libumad"
 rdmacm-mux$(EXESUF): $(rdmacm-mux-obj-y) $(COMMON_LDADDS)
 	$(call LINK, $^)
 
+ifdef CONFIG_VHOST_USER_INPUT
+ifdef CONFIG_LINUX
+vhost-user-input$(EXESUF): $(vhost-user-input-obj-y) libvhost-user.a libqemuutil.a
+	$(call LINK, $^)
+
+# build by default, do not install
+all: vhost-user-input$(EXESUF)
+endif
+endif
+
 module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-host.mak
 	$(call quiet-command,$(PYTHON) $< $@ \
 	$(addprefix $(SRC_PATH)/,$(patsubst %.mo,%.c,$(block-obj-m))), \
diff --git a/Makefile.objs b/Makefile.objs
index 2b0793ecc9ff..485f9624191a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -122,6 +122,7 @@ vhost-user-scsi.o-libs := $(LIBISCSI_LIBS)
 vhost-user-scsi-obj-y = contrib/vhost-user-scsi/
 vhost-user-blk-obj-y = contrib/vhost-user-blk/
 rdmacm-mux-obj-y = contrib/rdmacm-mux/
+vhost-user-input-obj-y = contrib/vhost-user-input/
 
 ######################################################################
 trace-events-subdirs =
diff --git a/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c
new file mode 100644
index 000000000000..8d493f598e02
--- /dev/null
+++ b/contrib/vhost-user-input/main.c
@@ -0,0 +1,393 @@
+/*
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * (at your option) any later version.  See the COPYING file in the
+ * top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include <glib.h>
+#include <linux/input.h>
+
+#include "qemu/iov.h"
+#include "qemu/bswap.h"
+#include "qemu/sockets.h"
+#include "contrib/libvhost-user/libvhost-user.h"
+#include "contrib/libvhost-user/libvhost-user-glib.h"
+#include "standard-headers/linux/virtio_input.h"
+#include "qapi/error.h"
+
+typedef struct virtio_input_event virtio_input_event;
+typedef struct virtio_input_config virtio_input_config;
+
+typedef struct VuInput {
+    VugDev dev;
+    GSource *evsrc;
+    int evdevfd;
+    GArray *config;
+    virtio_input_config *sel_config;
+    struct {
+        virtio_input_event event;
+        VuVirtqElement *elem;
+    } *queue;
+    uint32_t qindex, qsize;
+} VuInput;
+
+static void vi_input_send(VuInput *vi, struct virtio_input_event *event)
+{
+    VuDev *dev = &vi->dev.parent;
+    VuVirtq *vq = vu_get_queue(dev, 0);
+    VuVirtqElement *elem;
+    int i, len;
+
+    /* queue up events ... */
+    if (vi->qindex == vi->qsize) {
+        vi->qsize++;
+        vi->queue = g_realloc_n(vi->queue, vi->qsize, sizeof(vi->queue[0]));
+    }
+    vi->queue[vi->qindex++].event = *event;
+
+    /* ... until we see a report sync ... */
+    if (event->type != htole16(EV_SYN) ||
+        event->code != htole16(SYN_REPORT)) {
+        return;
+    }
+
+    /* ... then check available space ... */
+    for (i = 0; i < vi->qindex; i++) {
+        elem = vu_queue_pop(dev, vq, sizeof(VuVirtqElement));
+        if (!elem) {
+            while (--i >= 0) {
+                vu_queue_unpop(dev, vq, vi->queue[i].elem, 0);
+            }
+            vi->qindex = 0;
+            g_warning("virtio-input queue full");
+            return;
+        }
+        vi->queue[i].elem = elem;
+    }
+
+    /* ... and finally pass them to the guest */
+    for (i = 0; i < vi->qindex; i++) {
+        elem = vi->queue[i].elem;
+        len = iov_from_buf(elem->in_sg, elem->in_num,
+                           0, &vi->queue[i].event, sizeof(virtio_input_event));
+        vu_queue_push(dev, vq, elem, len);
+        g_free(elem);
+    }
+
+    vu_queue_notify(&vi->dev.parent, vq);
+    vi->qindex = 0;
+}
+
+static void
+vi_evdev_watch(VuDev *dev, int condition, void *data)
+{
+    VuInput *vi = data;
+    int fd = vi->evdevfd;
+
+    g_debug("Got evdev condition %x", condition);
+
+    struct virtio_input_event virtio;
+    struct input_event evdev;
+    int rc;
+
+    for (;;) {
+        rc = read(fd, &evdev, sizeof(evdev));
+        if (rc != sizeof(evdev)) {
+            break;
+        }
+
+        g_debug("input %d %d %d", evdev.type, evdev.code, evdev.value);
+
+        virtio.type  = htole16(evdev.type);
+        virtio.code  = htole16(evdev.code);
+        virtio.value = htole32(evdev.value);
+        vi_input_send(vi, &virtio);
+    }
+}
+
+
+static void vi_handle_status(VuInput *vi, virtio_input_event *event)
+{
+    struct input_event evdev;
+    int rc;
+
+    if (gettimeofday(&evdev.time, NULL)) {
+        perror("vi_handle_status: gettimeofday");
+        return;
+    }
+
+    evdev.type = le16toh(event->type);
+    evdev.code = le16toh(event->code);
+    evdev.value = le32toh(event->value);
+
+    rc = write(vi->evdevfd, &evdev, sizeof(evdev));
+    if (rc == -1) {
+        perror("vi_host_handle_status: write");
+    }
+}
+
+static void vi_handle_sts(VuDev *dev, int qidx)
+{
+    VuInput *vi = container_of(dev, VuInput, dev.parent);
+    VuVirtq *vq = vu_get_queue(dev, qidx);
+    virtio_input_event event;
+    VuVirtqElement *elem;
+    int len;
+
+    g_debug("%s", G_STRFUNC);
+
+    for (;;) {
+        elem = vu_queue_pop(dev, vq, sizeof(VuVirtqElement));
+        if (!elem) {
+            break;
+        }
+
+        memset(&event, 0, sizeof(event));
+        len = iov_to_buf(elem->out_sg, elem->out_num,
+                         0, &event, sizeof(event));
+        vi_handle_status(vi, &event);
+        vu_queue_push(dev, vq, elem, len);
+        g_free(elem);
+    }
+
+    vu_queue_notify(&vi->dev.parent, vq);
+}
+
+static void
+vi_panic(VuDev *dev, const char *msg)
+{
+    g_critical("%s\n", msg);
+    exit(EXIT_FAILURE);
+}
+
+static void
+vi_queue_set_started(VuDev *dev, int qidx, bool started)
+{
+    VuInput *vi = container_of(dev, VuInput, dev.parent);
+    VuVirtq *vq = vu_get_queue(dev, qidx);
+
+    g_debug("queue started %d:%d", qidx, started);
+
+    if (qidx == 1) {
+        vu_set_queue_handler(dev, vq, started ? vi_handle_sts : NULL);
+    }
+
+    started = vu_queue_started(dev, vu_get_queue(dev, 0)) &&
+        vu_queue_started(dev, vu_get_queue(dev, 1));
+
+    if (started && !vi->evsrc) {
+        vi->evsrc = vug_source_new(&vi->dev, vi->evdevfd,
+                                   G_IO_IN, vi_evdev_watch, vi);
+    }
+
+    if (!started && vi->evsrc) {
+        g_source_destroy(vi->evsrc);
+        vi->evsrc = NULL;
+    }
+}
+
+static virtio_input_config *
+vi_find_config(VuInput *vi, uint8_t select, uint8_t subsel)
+{
+    virtio_input_config *cfg;
+    int i;
+
+    for (i = 0; i < vi->config->len; i++) {
+        cfg = &g_array_index(vi->config, virtio_input_config, i);
+        if (select == cfg->select && subsel == cfg->subsel) {
+            return cfg;
+        }
+    }
+
+    return NULL;
+}
+
+static int vi_get_config(VuDev *dev, uint8_t *config, uint32_t len)
+{
+    VuInput *vi = container_of(dev, VuInput, dev.parent);
+
+    g_return_val_if_fail(len <= sizeof(*vi->sel_config), -1);
+
+    if (vi->sel_config) {
+        memcpy(config, vi->sel_config, len);
+    } else {
+        memset(config, 0, len);
+    }
+
+    return 0;
+}
+
+static int vi_set_config(VuDev *dev, const uint8_t *data,
+                         uint32_t offset, uint32_t size,
+                         uint32_t flags)
+{
+    VuInput *vi = container_of(dev, VuInput, dev.parent);
+    virtio_input_config *config = (virtio_input_config *)data;
+
+    vi->sel_config = vi_find_config(vi, config->select, config->subsel);
+
+    return 0;
+}
+
+static const VuDevIface vuiface = {
+    .queue_set_started = vi_queue_set_started,
+    .get_config = vi_get_config,
+    .set_config = vi_set_config,
+};
+
+static void
+vi_bits_config(VuInput *vi, int type, int count)
+{
+    virtio_input_config bits;
+    int rc, i, size = 0;
+
+    memset(&bits, 0, sizeof(bits));
+    rc = ioctl(vi->evdevfd, EVIOCGBIT(type, count / 8), bits.u.bitmap);
+    if (rc < 0) {
+        return;
+    }
+
+    for (i = 0; i < count / 8; i++) {
+        if (bits.u.bitmap[i]) {
+            size = i + 1;
+        }
+    }
+    if (size == 0) {
+        return;
+    }
+
+    bits.select = VIRTIO_INPUT_CFG_EV_BITS;
+    bits.subsel = type;
+    bits.size   = size;
+    g_array_append_val(vi->config, bits);
+}
+
+static char *opt_evdev;
+static int opt_fdnum = -1;
+static char *opt_socket_path;
+static gboolean opt_nograb;
+static gboolean opt_print_caps;
+
+static GOptionEntry entries[] = {
+    { "print-capabilities", 'c', 0, G_OPTION_ARG_NONE, &opt_print_caps,
+      "Print capabilities", NULL },
+    { "no-grab", 'n', 0, G_OPTION_ARG_NONE, &opt_nograb,
+      "Don't grab device", NULL },
+    { "fd", 'f', 0, G_OPTION_ARG_INT, &opt_fdnum,
+      "Use inherited fd socket", "FDNUM" },
+    { "socket-path", 's', 0, G_OPTION_ARG_FILENAME, &opt_socket_path,
+      "Use UNIX socket path", "PATH" },
+    { "evdev-path", 'p', 0, G_OPTION_ARG_FILENAME, &opt_evdev,
+      "evdev input device path", "PATH" },
+    { NULL, }
+};
+
+int
+main(int argc, char *argv[])
+{
+    GMainLoop *loop = NULL;
+    VuInput vi = { 0, };
+    int rc, ver, fd;
+    virtio_input_config id;
+    struct input_id ids;
+    GError *error = NULL;
+    GOptionContext *context;
+
+    context = g_option_context_new(NULL);
+    g_option_context_add_main_entries(context, entries, NULL);
+    if (!g_option_context_parse(context, &argc, &argv, &error)) {
+        g_printerr("Option parsing failed: %s\n", error->message);
+        exit(EXIT_FAILURE);
+    }
+    if (opt_print_caps) {
+        g_print("{\n");
+        g_print("  \"type\": \"input\",\n");
+        g_print("  \"features\": [\n");
+        g_print("    \"evdev-path\",\n");
+        g_print("    \"no-grab\"\n");
+        g_print("  ]\n");
+        g_print("}\n");
+        exit(EXIT_SUCCESS);
+    }
+    if (!opt_evdev) {
+        g_printerr("Please specify an evdev path\n");
+        exit(EXIT_FAILURE);
+    }
+    if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) {
+        g_printerr("Please specify either --fd or --socket-path\n");
+        exit(EXIT_FAILURE);
+    }
+
+    vi.evdevfd = open(opt_evdev, O_RDWR);
+    if (vi.evdevfd < 0) {
+        g_printerr("Failed to open evdev: %s\n", g_strerror(errno));
+        exit(EXIT_FAILURE);
+    }
+
+    rc = ioctl(vi.evdevfd, EVIOCGVERSION, &ver);
+    if (rc < 0) {
+        g_printerr("%s: is not an evdev device\n", argv[1]);
+        exit(EXIT_FAILURE);
+    }
+
+    if (!opt_nograb) {
+        rc = ioctl(vi.evdevfd, EVIOCGRAB, 1);
+        if (rc < 0) {
+            g_printerr("Failed to grab device\n");
+            exit(EXIT_FAILURE);
+        }
+    }
+
+    vi.config = g_array_new(false, false, sizeof(virtio_input_config));
+    memset(&id, 0, sizeof(id));
+    ioctl(vi.evdevfd, EVIOCGNAME(sizeof(id.u.string) - 1), id.u.string);
+    id.select = VIRTIO_INPUT_CFG_ID_NAME;
+    id.size = strlen(id.u.string);
+    g_array_append_val(vi.config, id);
+
+    if (ioctl(vi.evdevfd, EVIOCGID, &ids) == 0) {
+        memset(&id, 0, sizeof(id));
+        id.select = VIRTIO_INPUT_CFG_ID_DEVIDS;
+        id.size = sizeof(struct virtio_input_devids);
+        id.u.ids.bustype = cpu_to_le16(ids.bustype);
+        id.u.ids.vendor  = cpu_to_le16(ids.vendor);
+        id.u.ids.product = cpu_to_le16(ids.product);
+        id.u.ids.version = cpu_to_le16(ids.version);
+        g_array_append_val(vi.config, id);
+    }
+
+    vi_bits_config(&vi, EV_KEY, KEY_CNT);
+    vi_bits_config(&vi, EV_REL, REL_CNT);
+    vi_bits_config(&vi, EV_ABS, ABS_CNT);
+    vi_bits_config(&vi, EV_MSC, MSC_CNT);
+    vi_bits_config(&vi, EV_SW,  SW_CNT);
+    g_debug("config length: %u", vi.config->len);
+
+    if (opt_socket_path) {
+        int lsock = unix_listen(opt_socket_path, &error_fatal);
+        fd = accept(lsock, NULL, NULL);
+        close(lsock);
+    } else {
+        fd = opt_fdnum;
+    }
+    if (fd == -1) {
+        g_printerr("Invalid socket");
+        exit(EXIT_FAILURE);
+    }
+    vug_init(&vi.dev, fd, vi_panic, &vuiface);
+
+    loop = g_main_loop_new(NULL, FALSE);
+    g_main_loop_run(loop);
+    g_main_loop_unref(loop);
+
+    vug_deinit(&vi.dev);
+
+    if (vi.evsrc) {
+        g_source_unref(vi.evsrc);
+    }
+    g_array_free(vi.config, TRUE);
+    g_free(vi.queue);
+    return 0;
+}
diff --git a/MAINTAINERS b/MAINTAINERS
index a6948ebc63bc..73a010508251 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1532,6 +1532,7 @@ S: Maintained
 F: hw/input/vhost-user-input.c
 F: hw/input/virtio-input*.c
 F: include/hw/virtio/virtio-input.h
+F: contrib/vhost-user-input/*
 
 virtio-serial
 M: Amit Shah <amit@kernel.org>
diff --git a/contrib/vhost-user-input/Makefile.objs b/contrib/vhost-user-input/Makefile.objs
new file mode 100644
index 000000000000..b1fad90d51b6
--- /dev/null
+++ b/contrib/vhost-user-input/Makefile.objs
@@ -0,0 +1 @@
+vhost-user-input-obj-y = main.o
-- 
2.18.1



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PULL 0/3] Input 20190522 patches
  2019-05-22  8:27 [Qemu-devel] [PULL 0/3] Input 20190522 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2019-05-22  8:27 ` [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input Gerd Hoffmann
@ 2019-05-23 10:21 ` Peter Maydell
  3 siblings, 0 replies; 7+ messages in thread
From: Peter Maydell @ 2019-05-23 10:21 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers, Michael S. Tsirkin

On Wed, 22 May 2019 at 09:32, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> The following changes since commit a4f667b6714916683408b983cfe0a615a725775f:
>
>   Merge remote-tracking branch 'remotes/cohuck/tags/s390x-20190521-3' into staging (2019-05-21 16:30:13 +0100)
>
> are available in the Git repository at:
>
>   git://git.kraxel.org/qemu tags/input-20190522-pull-request
>
> for you to fetch changes up to 06914c97d3ade856371c9a59cbe6a9b13422471f:
>
>   contrib: add vhost-user-input (2019-05-22 07:16:58 +0200)
>
> ----------------------------------------------------------------
> input: add vhost-user-input to contrib.
>
> ----------------------------------------------------------------


Applied, thanks.

Please update the changelog at https://wiki.qemu.org/ChangeLog/4.1
for any user-visible changes.

-- PMM


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input
  2019-05-22  8:27 ` [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input Gerd Hoffmann
@ 2019-05-30 11:16   ` Peter Maydell
  2019-06-05 13:49     ` Marc-André Lureau
  0 siblings, 1 reply; 7+ messages in thread
From: Peter Maydell @ 2019-05-30 11:16 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: Marc-André Lureau, QEMU Developers, Michael S. Tsirkin

On Wed, 22 May 2019 at 09:29, Gerd Hoffmann <kraxel@redhat.com> wrote:
>
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
>
> Add a vhost-user input backend example, based on virtio-input-host
> device. It takes an evdev path as argument, and can be associated with
> a vhost-user-input device via a UNIX socket:
>
> $ vhost-user-input -p /dev/input/eventX -s /tmp/vui.sock
>
> $ qemu ... -chardev socket,id=vuic,path=/tmp/vui.sock
>   -device vhost-user-input-pci,chardev=vuic
>
> This example is intentionally not included in $TOOLS, and not
> installed by default.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> Message-id: 20190514104126.6294-4-marcandre.lureau@redhat.com
> Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>

Hi; Coverity spotted a problem with this patch:

> +int
> +main(int argc, char *argv[])
> +{
> +    GMainLoop *loop = NULL;
> +    VuInput vi = { 0, };
> +    int rc, ver, fd;
> +    virtio_input_config id;
> +    struct input_id ids;
> +    GError *error = NULL;
> +    GOptionContext *context;
> +
> +    context = g_option_context_new(NULL);
> +    g_option_context_add_main_entries(context, entries, NULL);
> +    if (!g_option_context_parse(context, &argc, &argv, &error)) {
> +        g_printerr("Option parsing failed: %s\n", error->message);
> +        exit(EXIT_FAILURE);
> +    }
> +    if (opt_print_caps) {
> +        g_print("{\n");
> +        g_print("  \"type\": \"input\",\n");
> +        g_print("  \"features\": [\n");
> +        g_print("    \"evdev-path\",\n");
> +        g_print("    \"no-grab\"\n");
> +        g_print("  ]\n");
> +        g_print("}\n");
> +        exit(EXIT_SUCCESS);
> +    }
> +    if (!opt_evdev) {
> +        g_printerr("Please specify an evdev path\n");
> +        exit(EXIT_FAILURE);
> +    }
> +    if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) {
> +        g_printerr("Please specify either --fd or --socket-path\n");
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    vi.evdevfd = open(opt_evdev, O_RDWR);
> +    if (vi.evdevfd < 0) {
> +        g_printerr("Failed to open evdev: %s\n", g_strerror(errno));
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    rc = ioctl(vi.evdevfd, EVIOCGVERSION, &ver);
> +    if (rc < 0) {
> +        g_printerr("%s: is not an evdev device\n", argv[1]);
> +        exit(EXIT_FAILURE);
> +    }
> +
> +    if (!opt_nograb) {
> +        rc = ioctl(vi.evdevfd, EVIOCGRAB, 1);
> +        if (rc < 0) {
> +            g_printerr("Failed to grab device\n");
> +            exit(EXIT_FAILURE);
> +        }
> +    }
> +
> +    vi.config = g_array_new(false, false, sizeof(virtio_input_config));
> +    memset(&id, 0, sizeof(id));
> +    ioctl(vi.evdevfd, EVIOCGNAME(sizeof(id.u.string) - 1), id.u.string);

CID 1401704 -- we don't check the return value from ioctl().

> +    id.select = VIRTIO_INPUT_CFG_ID_NAME;
> +    id.size = strlen(id.u.string);
> +    g_array_append_val(vi.config, id);
> +
> +    if (ioctl(vi.evdevfd, EVIOCGID, &ids) == 0) {
> +        memset(&id, 0, sizeof(id));
> +        id.select = VIRTIO_INPUT_CFG_ID_DEVIDS;
> +        id.size = sizeof(struct virtio_input_devids);
> +        id.u.ids.bustype = cpu_to_le16(ids.bustype);
> +        id.u.ids.vendor  = cpu_to_le16(ids.vendor);
> +        id.u.ids.product = cpu_to_le16(ids.product);
> +        id.u.ids.version = cpu_to_le16(ids.version);
> +        g_array_append_val(vi.config, id);
> +    }
> +
> +    vi_bits_config(&vi, EV_KEY, KEY_CNT);
> +    vi_bits_config(&vi, EV_REL, REL_CNT);
> +    vi_bits_config(&vi, EV_ABS, ABS_CNT);
> +    vi_bits_config(&vi, EV_MSC, MSC_CNT);
> +    vi_bits_config(&vi, EV_SW,  SW_CNT);
> +    g_debug("config length: %u", vi.config->len);
> +
> +    if (opt_socket_path) {
> +        int lsock = unix_listen(opt_socket_path, &error_fatal);
> +        fd = accept(lsock, NULL, NULL);
> +        close(lsock);

This is CID 1401705 -- failure to check return value from
unix_listen() -- which I just realised I probably replied
to the wrong version of the patch to point out, so I mention
it again here.

> +    } else {
> +        fd = opt_fdnum;
> +    }

thanks
-- PMM


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input
  2019-05-30 11:16   ` Peter Maydell
@ 2019-06-05 13:49     ` Marc-André Lureau
  0 siblings, 0 replies; 7+ messages in thread
From: Marc-André Lureau @ 2019-06-05 13:49 UTC (permalink / raw)
  To: Peter Maydell; +Cc: Michael S. Tsirkin, Gerd Hoffmann, QEMU Developers

Hi

On Thu, May 30, 2019 at 1:17 PM Peter Maydell <peter.maydell@linaro.org> wrote:
>
> On Wed, 22 May 2019 at 09:29, Gerd Hoffmann <kraxel@redhat.com> wrote:
> >
> > From: Marc-André Lureau <marcandre.lureau@redhat.com>
> >
> > Add a vhost-user input backend example, based on virtio-input-host
> > device. It takes an evdev path as argument, and can be associated with
> > a vhost-user-input device via a UNIX socket:
> >
> > $ vhost-user-input -p /dev/input/eventX -s /tmp/vui.sock
> >
> > $ qemu ... -chardev socket,id=vuic,path=/tmp/vui.sock
> >   -device vhost-user-input-pci,chardev=vuic
> >
> > This example is intentionally not included in $TOOLS, and not
> > installed by default.
> >
> > Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> > Message-id: 20190514104126.6294-4-marcandre.lureau@redhat.com
> > Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
>
> Hi; Coverity spotted a problem with this patch:
>
> > +int
> > +main(int argc, char *argv[])
> > +{
> > +    GMainLoop *loop = NULL;
> > +    VuInput vi = { 0, };
> > +    int rc, ver, fd;
> > +    virtio_input_config id;
> > +    struct input_id ids;
> > +    GError *error = NULL;
> > +    GOptionContext *context;
> > +
> > +    context = g_option_context_new(NULL);
> > +    g_option_context_add_main_entries(context, entries, NULL);
> > +    if (!g_option_context_parse(context, &argc, &argv, &error)) {
> > +        g_printerr("Option parsing failed: %s\n", error->message);
> > +        exit(EXIT_FAILURE);
> > +    }
> > +    if (opt_print_caps) {
> > +        g_print("{\n");
> > +        g_print("  \"type\": \"input\",\n");
> > +        g_print("  \"features\": [\n");
> > +        g_print("    \"evdev-path\",\n");
> > +        g_print("    \"no-grab\"\n");
> > +        g_print("  ]\n");
> > +        g_print("}\n");
> > +        exit(EXIT_SUCCESS);
> > +    }
> > +    if (!opt_evdev) {
> > +        g_printerr("Please specify an evdev path\n");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +    if ((!!opt_socket_path + (opt_fdnum != -1)) != 1) {
> > +        g_printerr("Please specify either --fd or --socket-path\n");
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    vi.evdevfd = open(opt_evdev, O_RDWR);
> > +    if (vi.evdevfd < 0) {
> > +        g_printerr("Failed to open evdev: %s\n", g_strerror(errno));
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    rc = ioctl(vi.evdevfd, EVIOCGVERSION, &ver);
> > +    if (rc < 0) {
> > +        g_printerr("%s: is not an evdev device\n", argv[1]);
> > +        exit(EXIT_FAILURE);
> > +    }
> > +
> > +    if (!opt_nograb) {
> > +        rc = ioctl(vi.evdevfd, EVIOCGRAB, 1);
> > +        if (rc < 0) {
> > +            g_printerr("Failed to grab device\n");
> > +            exit(EXIT_FAILURE);
> > +        }
> > +    }
> > +
> > +    vi.config = g_array_new(false, false, sizeof(virtio_input_config));
> > +    memset(&id, 0, sizeof(id));
> > +    ioctl(vi.evdevfd, EVIOCGNAME(sizeof(id.u.string) - 1), id.u.string);
>
> CID 1401704 -- we don't check the return value from ioctl().

ok, I'll send a fix

>
> > +    id.select = VIRTIO_INPUT_CFG_ID_NAME;
> > +    id.size = strlen(id.u.string);
> > +    g_array_append_val(vi.config, id);
> > +
> > +    if (ioctl(vi.evdevfd, EVIOCGID, &ids) == 0) {
> > +        memset(&id, 0, sizeof(id));
> > +        id.select = VIRTIO_INPUT_CFG_ID_DEVIDS;
> > +        id.size = sizeof(struct virtio_input_devids);
> > +        id.u.ids.bustype = cpu_to_le16(ids.bustype);
> > +        id.u.ids.vendor  = cpu_to_le16(ids.vendor);
> > +        id.u.ids.product = cpu_to_le16(ids.product);
> > +        id.u.ids.version = cpu_to_le16(ids.version);
> > +        g_array_append_val(vi.config, id);
> > +    }
> > +
> > +    vi_bits_config(&vi, EV_KEY, KEY_CNT);
> > +    vi_bits_config(&vi, EV_REL, REL_CNT);
> > +    vi_bits_config(&vi, EV_ABS, ABS_CNT);
> > +    vi_bits_config(&vi, EV_MSC, MSC_CNT);
> > +    vi_bits_config(&vi, EV_SW,  SW_CNT);
> > +    g_debug("config length: %u", vi.config->len);
> > +
> > +    if (opt_socket_path) {
> > +        int lsock = unix_listen(opt_socket_path, &error_fatal);
> > +        fd = accept(lsock, NULL, NULL);
> > +        close(lsock);
>
> This is CID 1401705 -- failure to check return value from
> unix_listen() -- which I just realised I probably replied
> to the wrong version of the patch to point out, so I mention
> it again here.

coverity should realize that passing &error_fatal will not return, no?

Can we mark this as false-positive?

>
> > +    } else {
> > +        fd = opt_fdnum;
> > +    }
>
> thanks
> -- PMM


^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2019-06-05 13:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-22  8:27 [Qemu-devel] [PULL 0/3] Input 20190522 patches Gerd Hoffmann
2019-05-22  8:27 ` [Qemu-devel] [PULL 1/3] libvhost-user: fix cast warnings on 32 bits Gerd Hoffmann
2019-05-22  8:27 ` [Qemu-devel] [PULL 2/3] libvhost-user: fix -Werror=format= on ppc64 Gerd Hoffmann
2019-05-22  8:27 ` [Qemu-devel] [PULL 3/3] contrib: add vhost-user-input Gerd Hoffmann
2019-05-30 11:16   ` Peter Maydell
2019-06-05 13:49     ` Marc-André Lureau
2019-05-23 10:21 ` [Qemu-devel] [PULL 0/3] Input 20190522 patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.