* [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input
@ 2019-02-27 10:30 Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 01/12] libvhost-user: fix clang enum-conversion warning Marc-André Lureau
` (13 more replies)
0 siblings, 14 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Hi,
This series is based on previously discussed "[PATCH v4 00/29]
vhost-user for input & GPU" and "vhost-user: define conventions for
vhost-user backends" work. The GPU part is left off for now.
This series introduces a "vhost-user-backend": an helper object to be
used by vhost-user devices to ease with backend initialization and
handling. As a simple showcase, a "vhost-user-input-pci" device is
introduced, which can be used with the "contrib: add vhost-user-input"
example. vhost-user-input isn't meant to be installed, discovered or
used by libvirt: no installation is done (no vhost-user JSON file is
provided either).
thanks
v4:
- drop "RFC: add explicit can_migrate to vhost_user_backend_dev_init()"
- remove useless "cmd" struct field leftover
v3:
- add previously sent patch "libvhost-user: fix clang enum-conversion
warning" to fix clang build
- "define conventions for vhost-user backends" updates after Eric review
- Drop user-creatable from vhost-user-backend
- Make vhost-user-input-pci take a chardev= (instead of vhost-user=)
v2:
- rebased (VhostUserInputPCI got most of the changes, due to split)
- added "RFC: add explicit can_migrate to
vhost_user_backend_dev_init()" to attempt to address Michael
concerns about migration.
Marc-André Lureau (12):
libvhost-user: fix clang enum-conversion warning
vhost-user: define conventions for vhost-user backends
vhost-user: simplify vhost_user_init/vhost_user_cleanup
libvhost-user: exit by default on VHOST_USER_NONE
vhost-user: wrap some read/write with retry handling
Add vhost-user-backend
vhost-user: split vhost_user_read()
vhost-user: add vhost_user_input_get_config()
libvhost-user-glib: export vug_source_new()
libvhost-user: add vu_queue_unpop()
Add vhost-user-input-pci
contrib: add vhost-user-input
contrib/libvhost-user/libvhost-user-glib.h | 3 +
contrib/libvhost-user/libvhost-user.h | 17 +-
include/hw/virtio/vhost-backend.h | 4 +
include/hw/virtio/vhost-user-blk.h | 2 +-
include/hw/virtio/vhost-user-scsi.h | 2 +-
include/hw/virtio/vhost-user.h | 2 +-
include/hw/virtio/virtio-input.h | 14 +
include/sysemu/vhost-user-backend.h | 58 +++
backends/cryptodev-vhost-user.c | 18 +-
backends/vhost-user.c | 213 +++++++++++
contrib/libvhost-user/libvhost-user-glib.c | 11 +-
contrib/libvhost-user/libvhost-user.c | 19 +-
contrib/vhost-user-input/main.c | 398 +++++++++++++++++++++
hw/block/vhost-user-blk.c | 22 +-
hw/input/vhost-user-input.c | 99 +++++
hw/scsi/vhost-user-scsi.c | 20 +-
hw/virtio/vhost-stub.c | 4 +-
hw/virtio/vhost-user-input-pci.c | 53 +++
hw/virtio/vhost-user.c | 118 +++++-
net/vhost-user.c | 13 +-
MAINTAINERS | 5 +
Makefile | 3 +
Makefile.objs | 1 +
backends/Makefile.objs | 3 +-
configure | 3 +
contrib/vhost-user-input/Makefile.objs | 1 +
default-configs/virtio.mak | 1 +
docs/interop/vhost-user.json | 232 ++++++++++++
docs/interop/vhost-user.txt | 109 +++++-
hw/input/Makefile.objs | 1 +
hw/virtio/Makefile.objs | 1 +
31 files changed, 1363 insertions(+), 87 deletions(-)
create mode 100644 include/sysemu/vhost-user-backend.h
create mode 100644 backends/vhost-user.c
create mode 100644 contrib/vhost-user-input/main.c
create mode 100644 hw/input/vhost-user-input.c
create mode 100644 hw/virtio/vhost-user-input-pci.c
create mode 100644 contrib/vhost-user-input/Makefile.objs
create mode 100644 docs/interop/vhost-user.json
--
2.21.0
^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 01/12] libvhost-user: fix clang enum-conversion warning
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 02/12] vhost-user: define conventions for vhost-user backends Marc-André Lureau
` (12 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Now that the VhostUserMsg.request field is used for both master &
slave requests, since commit d84599f56c820d8c1ac9928a76500dcdfbbf194d:
contrib/libvhost-user/libvhost-user.c:953:20: error: implicit conversion from enumeration type 'enum VhostUserSlaveRequest' to different enumeration type 'VhostUserRequest' (aka 'enum VhostUserRequest') [-Werror,-Wenum-conversion]
.request = VHOST_USER_SLAVE_VRING_HOST_NOTIFIER_MSG,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
contrib/libvhost-user/libvhost-user.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index 4aa55b4d2d..c0133b7f3f 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -145,7 +145,7 @@ typedef struct VhostUserVringArea {
#endif
typedef struct VhostUserMsg {
- VhostUserRequest request;
+ int request;
#define VHOST_USER_VERSION_MASK (0x3)
#define VHOST_USER_REPLY_MASK (0x1 << 2)
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 02/12] vhost-user: define conventions for vhost-user backends
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 01/12] libvhost-user: fix clang enum-conversion warning Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 03/12] vhost-user: simplify vhost_user_init/vhost_user_cleanup Marc-André Lureau
` (11 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
As discussed during "[PATCH v4 00/29] vhost-user for input & GPU"
review, let's define a common set of backend conventions to help with
management layer implementation, and interoperability.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
---
MAINTAINERS | 1 +
docs/interop/vhost-user.json | 232 +++++++++++++++++++++++++++++++++++
docs/interop/vhost-user.txt | 101 ++++++++++++++-
3 files changed, 332 insertions(+), 2 deletions(-)
create mode 100644 docs/interop/vhost-user.json
diff --git a/MAINTAINERS b/MAINTAINERS
index 7be8c578ea..6364a4ea9c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1424,6 +1424,7 @@ vhost
M: Michael S. Tsirkin <mst@redhat.com>
S: Supported
F: hw/*/*vhost*
+F: docs/interop/vhost-user.json
F: docs/interop/vhost-user.txt
F: contrib/vhost-user-*/
diff --git a/docs/interop/vhost-user.json b/docs/interop/vhost-user.json
new file mode 100644
index 0000000000..ae88c03117
--- /dev/null
+++ b/docs/interop/vhost-user.json
@@ -0,0 +1,232 @@
+# -*- Mode: Python -*-
+#
+# Copyright (C) 2018 Red Hat, Inc.
+#
+# Authors:
+# Marc-André Lureau <marcandre.lureau@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.
+
+##
+# = vhost user backend discovery & capabilities
+##
+
+##
+# @VHostUserBackendType:
+#
+# List the various vhost user backend types.
+#
+# @9p: 9p virtio console
+# @balloon: virtio balloon
+# @block: virtio block
+# @caif: virtio caif
+# @console: virtio console
+# @crypto: virtio crypto
+# @gpu: virtio gpu
+# @input: virtio input
+# @net: virtio net
+# @rng: virtio rng
+# @rpmsg: virtio remote processor messaging
+# @rproc-serial: virtio remoteproc serial link
+# @scsi: virtio scsi
+# @vsock: virtio vsock transport
+#
+# Since: 4.0
+##
+{
+ 'enum': 'VHostUserBackendType',
+ 'data': [
+ '9p',
+ 'balloon',
+ 'block',
+ 'caif',
+ 'console',
+ 'crypto',
+ 'gpu',
+ 'input',
+ 'net',
+ 'rng',
+ 'rpmsg',
+ 'rproc-serial',
+ 'scsi',
+ 'vsock'
+ ]
+}
+
+##
+# @VHostUserBackendInputFeature:
+#
+# List of vhost user "input" features.
+#
+# @evdev-path: The --evdev-path command line option is supported.
+# @no-grab: The --no-grab command line option is supported.
+#
+# Since: 4.0
+##
+{
+ 'enum': 'VHostUserBackendInputFeature',
+ 'data': [ 'evdev-path', 'no-grab' ]
+}
+
+##
+# @VHostUserBackendCapabilitiesInput:
+#
+# Capabilities reported by vhost user "input" backends
+#
+# @features: list of supported features.
+#
+# Since: 4.0
+##
+{
+ 'struct': 'VHostUserBackendCapabilitiesInput',
+ 'data': {
+ 'features': [ 'VHostUserBackendInputFeature' ]
+ }
+}
+
+##
+# @VHostUserBackendGPUFeature:
+#
+# List of vhost user "gpu" features.
+#
+# @render-node: The --render-node command line option is supported.
+# @virgl: The --virgl command line option is supported.
+#
+# Since: 4.0
+##
+{
+ 'enum': 'VHostUserBackendGPUFeature',
+ 'data': [ 'render-node', 'virgl' ]
+}
+
+##
+# @VHostUserBackendCapabilitiesGPU:
+#
+# Capabilities reported by vhost user "gpu" backends.
+#
+# @features: list of supported features.
+#
+# Since: 4.0
+##
+{
+ 'struct': 'VHostUserBackendCapabilitiesGPU',
+ 'data': {
+ 'features': [ 'VHostUserBackendGPUFeature' ]
+ }
+}
+
+##
+# @VHostUserBackendCapabilities:
+#
+# Capabilities reported by vhost user backends.
+#
+# @type: The vhost user backend type.
+#
+# Since: 4.0
+##
+{
+ 'union': 'VHostUserBackendCapabilities',
+ 'base': { 'type': 'VHostUserBackendType' },
+ 'discriminator': 'type',
+ 'data': {
+ 'input': 'VHostUserBackendCapabilitiesInput',
+ 'gpu': 'VHostUserBackendCapabilitiesGPU'
+ }
+}
+
+##
+# @VhostUserBackend:
+#
+# Describes a vhost user backend to management software.
+#
+# It is possible for multiple @VhostUserBackend elements to match the
+# search criteria of management software. Applications thus need rules
+# to pick one of the many matches, and users need the ability to
+# override distro defaults.
+#
+# It is recommended to create vhost user backend JSON files (each
+# containing a single @VhostUserBackend root element) with a
+# double-digit prefix, for example "50-qemu-gpu.json",
+# "50-crosvm-gpu.json", etc, so they can be sorted in predictable
+# order. The backend JSON files should be searched for in three
+# directories:
+#
+# - /usr/share/qemu/vhost-user -- populated by distro-provided
+# packages (XDG_DATA_DIRS covers
+# /usr/share by default),
+#
+# - /etc/qemu/vhost-user -- exclusively for sysadmins' local additions,
+#
+# - $XDG_CONFIG_HOME/qemu/vhost-user -- exclusively for per-user local
+# additions (XDG_CONFIG_HOME
+# defaults to $HOME/.config).
+#
+# Top-down, the list of directories goes from general to specific.
+#
+# Management software should build a list of files from all three
+# locations, then sort the list by filename (i.e., basename
+# component). Management software should choose the first JSON file on
+# the sorted list that matches the search criteria. If a more specific
+# directory has a file with same name as a less specific directory,
+# then the file in the more specific directory takes effect. If the
+# more specific file is zero length, it hides the less specific one.
+#
+# For example, if a distro ships
+#
+# - /usr/share/qemu/vhost-user/50-qemu-gpu.json
+#
+# - /usr/share/qemu/vhost-user/50-crosvm-gpu.json
+#
+# then the sysadmin can prevent the default QEMU being used at all with
+#
+# $ touch /etc/qemu/vhost-user/50-qemu-gpu.json
+#
+# The sysadmin can replace/alter the distro default OVMF with
+#
+# $ vim /etc/qemu/vhost-user/50-qemu-gpu.json
+#
+# or they can provide a parallel QEMU GPU with higher priority
+#
+# $ vim /etc/qemu/vhost-user/10-qemu-gpu.json
+#
+# or they can provide a parallel OVMF with lower priority
+#
+# $ vim /etc/qemu/vhost-user/99-qemu-gpu.json
+#
+# @type: The vhost user backend type.
+#
+# @description: Provides a human-readable description of the backend.
+# Management software may or may not display @description.
+#
+# @binary: Absolute path to the backend binary.
+#
+# @tags: An optional list of auxiliary strings associated with the
+# backend for which @description is not appropriate, due to the
+# latter's possible exposure to the end-user. @tags serves
+# development and debugging purposes only, and management
+# software shall explicitly ignore it.
+#
+# Since: 4.0
+#
+# Example:
+#
+# {
+# "description": "QEMU vhost-user-gpu",
+# "type": "gpu",
+# "binary": "/usr/libexec/qemu/vhost-user-gpu",
+# "tags": [
+# "CONFIG_OPENGL_DMABUF=y"
+# ]
+# }
+#
+##
+{
+ 'struct' : 'VhostUserBackend',
+ 'data' : {
+ 'description': 'str',
+ 'type': 'VHostUserBackendType',
+ 'binary': 'str',
+ '*tags': [ 'str' ]
+ }
+}
diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index c2194711d9..9ee2a60cfb 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -17,8 +17,13 @@ The protocol defines 2 sides of the communication, master and slave. Master is
the application that shares its virtqueues, in our case QEMU. Slave is the
consumer of the virtqueues.
-In the current implementation QEMU is the Master, and the Slave is intended to
-be a software Ethernet switch running in user space, such as Snabbswitch.
+In the current implementation QEMU is the Master, and the Slave is the
+external process consuming the virtio queues, for example a software
+Ethernet switch running in user space, such as Snabbswitch, or a block
+device backend processing read & write to a virtual disk. In order to
+facilitate interoperability between various backend implementations,
+it is recommended to follow the "Backend program conventions"
+described in this document.
Master and slave can be either a client (i.e. connecting) or server (listening)
in the socket communication.
@@ -835,3 +840,95 @@ resilient for selective requests.
For the message types that already solicit a reply from the client, the
presence of VHOST_USER_PROTOCOL_F_REPLY_ACK or need_reply bit being set brings
no behavioural change. (See the 'Communication' section for details.)
+
+Backend program conventions
+---------------------------
+
+vhost-user backends can provide various devices & services and may
+need to be configured manually depending on the use case. However, it
+is a good idea to follow the conventions listed here when
+possible. Users, QEMU or libvirt, can then rely on some common
+behaviour to avoid heterogenous configuration and management of the
+backend programs and facilitate interoperability.
+
+Each backend installed on a host system should come with at least one
+JSON file that conforms to the vhost-user.json schema. Each file
+informs the management applications about the backend type, and binary
+location. In addition, it defines rules for management apps for
+picking the highest priority backend when multiple match the search
+criteria (see @VhostUserBackend documentation in the schema file).
+
+If the backend is not capable of enabling a requested feature on the
+host (such as 3D acceleration with virgl), or the initialization
+failed, the backend should fail to start early and exit with a status
+!= 0. It may also print a message to stderr for further details.
+
+The backend program must not daemonize itself, but it may be
+daemonized by the management layer. It may also have a restricted
+access to the system.
+
+File descriptors 0, 1 and 2 will exist, and have regular
+stdin/stdout/stderr usage (they may have been redirected to /dev/null
+by the management layer, or to a log handler).
+
+The backend program must end (as quickly and cleanly as possible) when
+the SIGTERM signal is received. Eventually, it may receive SIGKILL by
+the management layer after a few seconds.
+
+The following command line options have an expected behaviour. They
+are mandatory, unless explicitly said differently:
+
+* --socket-path=PATH
+
+This option specify the location of the vhost-user Unix domain socket.
+It is incompatible with --fd.
+
+* --fd=FDNUM
+
+When this argument is given, the backend program is started with the
+vhost-user socket as file descriptor FDNUM. It is incompatible with
+--socket-path.
+
+* --print-capabilities
+
+Output to stdout the backend capabilities in JSON format, and then
+exit successfully. Other options and arguments should be ignored, and
+the backend program should not perform its normal function. The
+capabilities can be reported dynamically depending on the host
+capabilities.
+
+The JSON output is described in the vhost-user.json schema, by
+@VHostUserBackendCapabilities. Example:
+{
+ "type": "foo",
+ "features": [
+ "feature-a",
+ "feature-b"
+ ]
+}
+
+vhost-user-input
+----------------
+
+Command line options:
+
+* --evdev-path=PATH (optional)
+
+Specify the linux input device.
+
+* --no-grab (optional)
+
+Do no request exclusive access to the input device.
+
+vhost-user-gpu
+--------------
+
+Command line options:
+
+* --render-node=PATH (optional)
+
+Specify the GPU DRM render node.
+
+* --virgl (optional)
+
+Enable virgl rendering support.
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 03/12] vhost-user: simplify vhost_user_init/vhost_user_cleanup
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 01/12] libvhost-user: fix clang enum-conversion warning Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 02/12] vhost-user: define conventions for vhost-user backends Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 04/12] libvhost-user: exit by default on VHOST_USER_NONE Marc-André Lureau
` (10 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Take a VhostUserState* that can be pre-allocated, and initialize it
with the associated chardev.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Tiwei Bie <tiwei.bie@intel.com>
---
include/hw/virtio/vhost-user-blk.h | 2 +-
include/hw/virtio/vhost-user-scsi.h | 2 +-
include/hw/virtio/vhost-user.h | 2 +-
backends/cryptodev-vhost-user.c | 18 ++++--------------
hw/block/vhost-user-blk.c | 22 ++++------------------
hw/scsi/vhost-user-scsi.c | 20 ++++----------------
hw/virtio/vhost-stub.c | 4 ++--
hw/virtio/vhost-user.c | 16 ++++++++++++----
net/vhost-user.c | 13 ++++---------
9 files changed, 33 insertions(+), 66 deletions(-)
diff --git a/include/hw/virtio/vhost-user-blk.h b/include/hw/virtio/vhost-user-blk.h
index d52944aeeb..a8a106eecb 100644
--- a/include/hw/virtio/vhost-user-blk.h
+++ b/include/hw/virtio/vhost-user-blk.h
@@ -36,7 +36,7 @@ typedef struct VHostUserBlk {
uint32_t queue_size;
uint32_t config_wce;
struct vhost_dev dev;
- VhostUserState *vhost_user;
+ VhostUserState vhost_user;
} VHostUserBlk;
#endif
diff --git a/include/hw/virtio/vhost-user-scsi.h b/include/hw/virtio/vhost-user-scsi.h
index e429cacd8e..738f9288bd 100644
--- a/include/hw/virtio/vhost-user-scsi.h
+++ b/include/hw/virtio/vhost-user-scsi.h
@@ -30,7 +30,7 @@
typedef struct VHostUserSCSI {
VHostSCSICommon parent_obj;
- VhostUserState *vhost_user;
+ VhostUserState vhost_user;
} VHostUserSCSI;
#endif /* VHOST_USER_SCSI_H */
diff --git a/include/hw/virtio/vhost-user.h b/include/hw/virtio/vhost-user.h
index fd660393a0..811e325f42 100644
--- a/include/hw/virtio/vhost-user.h
+++ b/include/hw/virtio/vhost-user.h
@@ -22,7 +22,7 @@ typedef struct VhostUserState {
VhostUserHostNotifier notifier[VIRTIO_QUEUE_MAX];
} VhostUserState;
-VhostUserState *vhost_user_init(void);
+bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp);
void vhost_user_cleanup(VhostUserState *user);
#endif
diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-user.c
index d539f14d59..1052a5d0e9 100644
--- a/backends/cryptodev-vhost-user.c
+++ b/backends/cryptodev-vhost-user.c
@@ -47,7 +47,7 @@
typedef struct CryptoDevBackendVhostUser {
CryptoDevBackend parent_obj;
- VhostUserState *vhost_user;
+ VhostUserState vhost_user;
CharBackend chr;
char *chr_name;
bool opened;
@@ -104,7 +104,7 @@ cryptodev_vhost_user_start(int queues,
continue;
}
- options.opaque = s->vhost_user;
+ options.opaque = &s->vhost_user;
options.backend_type = VHOST_BACKEND_TYPE_USER;
options.cc = b->conf.peers.ccs[i];
s->vhost_crypto[i] = cryptodev_vhost_init(&options);
@@ -182,7 +182,6 @@ static void cryptodev_vhost_user_init(
size_t i;
Error *local_err = NULL;
Chardev *chr;
- VhostUserState *user;
CryptoDevBackendClient *cc;
CryptoDevBackendVhostUser *s =
CRYPTODEV_BACKEND_VHOST_USER(backend);
@@ -213,15 +212,10 @@ static void cryptodev_vhost_user_init(
}
}
- user = vhost_user_init();
- if (!user) {
- error_setg(errp, "Failed to init vhost_user");
+ if (!vhost_user_init(&s->vhost_user, &s->chr, errp)) {
return;
}
- user->chr = &s->chr;
- s->vhost_user = user;
-
qemu_chr_fe_set_handlers(&s->chr, NULL, NULL,
cryptodev_vhost_user_event, NULL, s, NULL, true);
@@ -307,11 +301,7 @@ static void cryptodev_vhost_user_cleanup(
}
}
- if (s->vhost_user) {
- vhost_user_cleanup(s->vhost_user);
- g_free(s->vhost_user);
- s->vhost_user = NULL;
- }
+ vhost_user_cleanup(&s->vhost_user);
}
static void cryptodev_vhost_user_set_chardev(Object *obj,
diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c
index 44ac814016..767c734a81 100644
--- a/hw/block/vhost-user-blk.c
+++ b/hw/block/vhost-user-blk.c
@@ -253,7 +253,6 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
{
VirtIODevice *vdev = VIRTIO_DEVICE(dev);
VHostUserBlk *s = VHOST_USER_BLK(vdev);
- VhostUserState *user;
struct vhost_virtqueue *vqs = NULL;
int i, ret;
@@ -272,15 +271,10 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
return;
}
- user = vhost_user_init();
- if (!user) {
- error_setg(errp, "vhost-user-blk: failed to init vhost_user");
+ if (!vhost_user_init(&s->vhost_user, &s->chardev, errp)) {
return;
}
- user->chr = &s->chardev;
- s->vhost_user = user;
-
virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK,
sizeof(struct virtio_blk_config));
@@ -297,7 +291,7 @@ static void vhost_user_blk_device_realize(DeviceState *dev, Error **errp)
vhost_dev_set_config_notifier(&s->dev, &blk_ops);
- ret = vhost_dev_init(&s->dev, s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
+ ret = vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
error_setg(errp, "vhost-user-blk: vhost initialization failed: %s",
strerror(-ret));
@@ -322,10 +316,7 @@ vhost_err:
virtio_err:
g_free(vqs);
virtio_cleanup(vdev);
-
- vhost_user_cleanup(user);
- g_free(user);
- s->vhost_user = NULL;
+ vhost_user_cleanup(&s->vhost_user);
}
static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
@@ -338,12 +329,7 @@ static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp)
vhost_dev_cleanup(&s->dev);
g_free(vqs);
virtio_cleanup(vdev);
-
- if (s->vhost_user) {
- vhost_user_cleanup(s->vhost_user);
- g_free(s->vhost_user);
- s->vhost_user = NULL;
- }
+ vhost_user_cleanup(&s->vhost_user);
}
static void vhost_user_blk_instance_init(Object *obj)
diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c
index 6728878a52..8b1e6876db 100644
--- a/hw/scsi/vhost-user-scsi.c
+++ b/hw/scsi/vhost-user-scsi.c
@@ -69,7 +69,6 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev);
VHostUserSCSI *s = VHOST_USER_SCSI(dev);
VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s);
- VhostUserState *user;
Error *err = NULL;
int ret;
@@ -86,30 +85,24 @@ static void vhost_user_scsi_realize(DeviceState *dev, Error **errp)
return;
}
- user = vhost_user_init();
- if (!user) {
- error_setg(errp, "vhost-user-scsi: failed to init vhost_user");
+ if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev, errp)) {
return;
}
- user->chr = &vs->conf.chardev;
vsc->dev.nvqs = 2 + vs->conf.num_queues;
vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs);
vsc->dev.vq_index = 0;
vsc->dev.backend_features = 0;
- ret = vhost_dev_init(&vsc->dev, user,
+ ret = vhost_dev_init(&vsc->dev, &s->vhost_user,
VHOST_BACKEND_TYPE_USER, 0);
if (ret < 0) {
error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s",
strerror(-ret));
- vhost_user_cleanup(user);
- g_free(user);
+ vhost_user_cleanup(&s->vhost_user);
return;
}
- s->vhost_user = user;
-
/* Channel and lun both are 0 for bootable vhost-user-scsi disk */
vsc->channel = 0;
vsc->lun = 0;
@@ -130,12 +123,7 @@ static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp)
g_free(vqs);
virtio_scsi_common_unrealize(dev, errp);
-
- if (s->vhost_user) {
- vhost_user_cleanup(s->vhost_user);
- g_free(s->vhost_user);
- s->vhost_user = NULL;
- }
+ vhost_user_cleanup(&s->vhost_user);
}
static Property vhost_user_scsi_properties[] = {
diff --git a/hw/virtio/vhost-stub.c b/hw/virtio/vhost-stub.c
index 049089b5e2..c175148fce 100644
--- a/hw/virtio/vhost-stub.c
+++ b/hw/virtio/vhost-stub.c
@@ -7,9 +7,9 @@ bool vhost_has_free_slot(void)
return true;
}
-VhostUserState *vhost_user_init(void)
+bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp)
{
- return NULL;
+ return false;
}
void vhost_user_cleanup(VhostUserState *user)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 564a31d12c..a0e8a81857 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -1739,17 +1739,24 @@ static bool vhost_user_mem_section_filter(struct vhost_dev *dev,
return result;
}
-VhostUserState *vhost_user_init(void)
+bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp)
{
- VhostUserState *user = g_new0(struct VhostUserState, 1);
-
- return user;
+ if (user->chr) {
+ error_setg(errp, "Cannot initialize vhost-user state");
+ return false;
+ }
+ user->chr = chr;
+ return true;
}
void vhost_user_cleanup(VhostUserState *user)
{
int i;
+ if (!user->chr) {
+ return;
+ }
+
for (i = 0; i < VIRTIO_QUEUE_MAX; i++) {
if (user->notifier[i].addr) {
object_unparent(OBJECT(&user->notifier[i].mr));
@@ -1757,6 +1764,7 @@ void vhost_user_cleanup(VhostUserState *user)
user->notifier[i].addr = NULL;
}
}
+ user->chr = NULL;
}
const VhostOps user_ops = {
diff --git a/net/vhost-user.c b/net/vhost-user.c
index a39f9c9974..cea78b81f6 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -291,19 +291,14 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
{
Error *err = NULL;
NetClientState *nc, *nc0 = NULL;
- VhostUserState *user = NULL;
NetVhostUserState *s = NULL;
+ VhostUserState *user;
int i;
assert(name);
assert(queues > 0);
- user = vhost_user_init();
- if (!user) {
- error_report("failed to init vhost_user");
- goto err;
- }
-
+ user = g_new0(struct VhostUserState, 1);
for (i = 0; i < queues; i++) {
nc = qemu_new_net_client(&net_vhost_user_info, peer, device, name);
snprintf(nc->info_str, sizeof(nc->info_str), "vhost-user%d to %s",
@@ -312,11 +307,11 @@ static int net_vhost_user_init(NetClientState *peer, const char *device,
if (!nc0) {
nc0 = nc;
s = DO_UPCAST(NetVhostUserState, nc, nc);
- if (!qemu_chr_fe_init(&s->chr, chr, &err)) {
+ if (!qemu_chr_fe_init(&s->chr, chr, &err) ||
+ !vhost_user_init(user, &s->chr, &err)) {
error_report_err(err);
goto err;
}
- user->chr = &s->chr;
}
s = DO_UPCAST(NetVhostUserState, nc, nc);
s->vhost_user = user;
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 04/12] libvhost-user: exit by default on VHOST_USER_NONE
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (2 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 03/12] vhost-user: simplify vhost_user_init/vhost_user_cleanup Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 05/12] vhost-user: wrap some read/write with retry handling Marc-André Lureau
` (9 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Since commit 2566378d6d13bf4d28c7770bdbda5f7682594bbe, libvhost-user
no longer panics on disconnect (rc == 0), and instead silently ignores
an invalid VHOST_USER_NONE message.
Without extra work from the API user, this will simply busy-loop on
HUP events. The obvious thing to do is to exit(0) instead, while
additional or different work can be done by overriding
iface->process_msg().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Jens Freimann <jfreimann@redhat.com>
---
contrib/libvhost-user/libvhost-user.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index 3f14b4138b..fcf5014240 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1285,7 +1285,8 @@ vu_process_message(VuDev *dev, VhostUserMsg *vmsg)
case VHOST_USER_SET_CONFIG:
return vu_set_config(dev, vmsg);
case VHOST_USER_NONE:
- break;
+ /* if you need processing before exit, override iface->process_msg */
+ exit(0);
case VHOST_USER_POSTCOPY_ADVISE:
return vu_set_postcopy_advise(dev, vmsg);
case VHOST_USER_POSTCOPY_LISTEN:
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 05/12] vhost-user: wrap some read/write with retry handling
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (3 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 04/12] libvhost-user: exit by default on VHOST_USER_NONE Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 06/12] Add vhost-user-backend Marc-André Lureau
` (8 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
---
hw/virtio/vhost-user.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index a0e8a81857..b2e1175c1e 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -964,7 +964,10 @@ static void slave_read(void *opaque)
iov.iov_base = &hdr;
iov.iov_len = VHOST_USER_HDR_SIZE;
- size = recvmsg(u->slave_fd, &msgh, 0);
+ do {
+ size = recvmsg(u->slave_fd, &msgh, 0);
+ } while (size < 0 && (errno == EINTR || errno == EAGAIN));
+
if (size != VHOST_USER_HDR_SIZE) {
error_report("Failed to read from slave.");
goto err;
@@ -993,7 +996,10 @@ static void slave_read(void *opaque)
}
/* Read payload */
- size = read(u->slave_fd, &payload, hdr.size);
+ do {
+ size = read(u->slave_fd, &payload, hdr.size);
+ } while (size < 0 && (errno == EINTR || errno == EAGAIN));
+
if (size != hdr.size) {
error_report("Failed to read payload from slave.");
goto err;
@@ -1041,7 +1047,10 @@ static void slave_read(void *opaque)
iovec[1].iov_base = &payload;
iovec[1].iov_len = hdr.size;
- size = writev(u->slave_fd, iovec, ARRAY_SIZE(iovec));
+ do {
+ size = writev(u->slave_fd, iovec, ARRAY_SIZE(iovec));
+ } while (size < 0 && (errno == EINTR || errno == EAGAIN));
+
if (size != VHOST_USER_HDR_SIZE + hdr.size) {
error_report("Failed to send msg reply to slave.");
goto err;
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 06/12] Add vhost-user-backend
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (4 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 05/12] vhost-user: wrap some read/write with retry handling Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 07/12] vhost-user: split vhost_user_read() Marc-André Lureau
` (7 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Create a vhost-user-backend object that holds a connection to a
vhost-user backend and can be referenced from virtio devices that
support it. See later patches for input & gpu usage.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/sysemu/vhost-user-backend.h | 58 ++++++++
backends/vhost-user.c | 213 ++++++++++++++++++++++++++++
MAINTAINERS | 2 +
backends/Makefile.objs | 3 +-
4 files changed, 275 insertions(+), 1 deletion(-)
create mode 100644 include/sysemu/vhost-user-backend.h
create mode 100644 backends/vhost-user.c
diff --git a/include/sysemu/vhost-user-backend.h b/include/sysemu/vhost-user-backend.h
new file mode 100644
index 0000000000..ee80492323
--- /dev/null
+++ b/include/sysemu/vhost-user-backend.h
@@ -0,0 +1,58 @@
+/*
+ * QEMU vhost-user backend
+ *
+ * Copyright (C) 2018 Red Hat Inc
+ *
+ * Authors:
+ * Marc-André Lureau <marcandre.lureau@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.
+ */
+#ifndef QEMU_VHOST_USER_BACKEND_H
+#define QEMU_VHOST_USER_BACKEND_H
+
+#include "qom/object.h"
+#include "exec/memory.h"
+#include "qemu/option.h"
+#include "qemu/bitmap.h"
+#include "hw/virtio/vhost.h"
+#include "hw/virtio/vhost-user.h"
+#include "chardev/char-fe.h"
+#include "io/channel.h"
+
+#define TYPE_VHOST_USER_BACKEND "vhost-user-backend"
+#define VHOST_USER_BACKEND(obj) \
+ OBJECT_CHECK(VhostUserBackend, (obj), TYPE_VHOST_USER_BACKEND)
+#define VHOST_USER_BACKEND_GET_CLASS(obj) \
+ OBJECT_GET_CLASS(VhostUserBackendClass, (obj), TYPE_VHOST_USER_BACKEND)
+#define VHOST_USER_BACKEND_CLASS(klass) \
+ OBJECT_CLASS_CHECK(VhostUserBackendClass, (klass), TYPE_VHOST_USER_BACKEND)
+
+typedef struct VhostUserBackend VhostUserBackend;
+typedef struct VhostUserBackendClass VhostUserBackendClass;
+
+struct VhostUserBackendClass {
+ ObjectClass parent_class;
+};
+
+struct VhostUserBackend {
+ /* private */
+ Object parent;
+
+ char *chr_name;
+ CharBackend chr;
+ VhostUserState vhost_user;
+ struct vhost_dev dev;
+ QIOChannel *child;
+ VirtIODevice *vdev;
+ bool started;
+ bool completed;
+};
+
+int vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
+ unsigned nvqs, Error **errp);
+void vhost_user_backend_start(VhostUserBackend *b);
+void vhost_user_backend_stop(VhostUserBackend *b);
+
+#endif
diff --git a/backends/vhost-user.c b/backends/vhost-user.c
new file mode 100644
index 0000000000..289dbd9e6d
--- /dev/null
+++ b/backends/vhost-user.c
@@ -0,0 +1,213 @@
+/*
+ * QEMU vhost-user backend
+ *
+ * Copyright (C) 2018 Red Hat Inc
+ *
+ * Authors:
+ * Marc-André Lureau <marcandre.lureau@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.
+ */
+
+
+#include "qemu/osdep.h"
+#include "hw/qdev.h"
+#include "qapi/error.h"
+#include "qapi/qmp/qerror.h"
+#include "qemu/error-report.h"
+#include "qom/object_interfaces.h"
+#include "sysemu/vhost-user-backend.h"
+#include "sysemu/kvm.h"
+#include "io/channel-command.h"
+#include "hw/virtio/virtio-bus.h"
+
+static bool
+ioeventfd_enabled(void)
+{
+ return kvm_enabled() && kvm_eventfds_enabled();
+}
+
+int
+vhost_user_backend_dev_init(VhostUserBackend *b, VirtIODevice *vdev,
+ unsigned nvqs, Error **errp)
+{
+ int ret;
+
+ assert(!b->vdev && vdev);
+
+ if (!ioeventfd_enabled()) {
+ error_setg(errp, "vhost initialization failed: requires kvm");
+ return -1;
+ }
+
+ if (!vhost_user_init(&b->vhost_user, &b->chr, errp)) {
+ return -1;
+ }
+
+ b->vdev = vdev;
+ b->dev.nvqs = nvqs;
+ b->dev.vqs = g_new(struct vhost_virtqueue, nvqs);
+
+ ret = vhost_dev_init(&b->dev, &b->vhost_user, VHOST_BACKEND_TYPE_USER, 0);
+ if (ret < 0) {
+ error_setg_errno(errp, -ret, "vhost initialization failed");
+ return -1;
+ }
+
+ return 0;
+}
+
+void
+vhost_user_backend_start(VhostUserBackend *b)
+{
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(b->vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret, i ;
+
+ if (b->started) {
+ return;
+ }
+
+ if (!k->set_guest_notifiers) {
+ error_report("binding does not support guest notifiers");
+ return;
+ }
+
+ ret = vhost_dev_enable_notifiers(&b->dev, b->vdev);
+ if (ret < 0) {
+ return;
+ }
+
+ ret = k->set_guest_notifiers(qbus->parent, b->dev.nvqs, true);
+ if (ret < 0) {
+ error_report("Error binding guest notifier");
+ goto err_host_notifiers;
+ }
+
+ b->dev.acked_features = b->vdev->guest_features;
+ ret = vhost_dev_start(&b->dev, b->vdev);
+ if (ret < 0) {
+ error_report("Error start vhost dev");
+ goto err_guest_notifiers;
+ }
+
+ /* guest_notifier_mask/pending not used yet, so just unmask
+ * everything here. virtio-pci will do the right thing by
+ * enabling/disabling irqfd.
+ */
+ for (i = 0; i < b->dev.nvqs; i++) {
+ vhost_virtqueue_mask(&b->dev, b->vdev,
+ b->dev.vq_index + i, false);
+ }
+
+ b->started = true;
+ return;
+
+err_guest_notifiers:
+ k->set_guest_notifiers(qbus->parent, b->dev.nvqs, false);
+err_host_notifiers:
+ vhost_dev_disable_notifiers(&b->dev, b->vdev);
+}
+
+void
+vhost_user_backend_stop(VhostUserBackend *b)
+{
+ BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(b->vdev)));
+ VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
+ int ret = 0;
+
+ if (!b->started) {
+ return;
+ }
+
+ vhost_dev_stop(&b->dev, b->vdev);
+
+ if (k->set_guest_notifiers) {
+ ret = k->set_guest_notifiers(qbus->parent,
+ b->dev.nvqs, false);
+ if (ret < 0) {
+ error_report("vhost guest notifier cleanup failed: %d", ret);
+ }
+ }
+ assert(ret >= 0);
+
+ vhost_dev_disable_notifiers(&b->dev, b->vdev);
+ b->started = false;
+}
+
+static void set_chardev(Object *obj, const char *value, Error **errp)
+{
+ VhostUserBackend *b = VHOST_USER_BACKEND(obj);
+ Chardev *chr;
+
+ if (b->completed) {
+ error_setg(errp, QERR_PERMISSION_DENIED);
+ return;
+ }
+
+ g_free(b->chr_name);
+ b->chr_name = g_strdup(value);
+
+ chr = qemu_chr_find(b->chr_name);
+ if (chr == NULL) {
+ error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
+ "Chardev '%s' not found", b->chr_name);
+ return;
+ }
+
+ if (!qemu_chr_fe_init(&b->chr, chr, errp)) {
+ return;
+ }
+
+ b->completed = true;
+ /* could call vhost_dev_init() so early message can be exchanged */
+}
+
+static char *get_chardev(Object *obj, Error **errp)
+{
+ VhostUserBackend *b = VHOST_USER_BACKEND(obj);
+ Chardev *chr = qemu_chr_fe_get_driver(&b->chr);
+
+ if (chr && chr->label) {
+ return g_strdup(chr->label);
+ }
+
+ return NULL;
+}
+
+static void vhost_user_backend_init(Object *obj)
+{
+ object_property_add_str(obj, "chardev", get_chardev, set_chardev, NULL);
+}
+
+static void vhost_user_backend_finalize(Object *obj)
+{
+ VhostUserBackend *b = VHOST_USER_BACKEND(obj);
+
+ g_free(b->dev.vqs);
+ g_free(b->chr_name);
+
+ vhost_user_cleanup(&b->vhost_user);
+ qemu_chr_fe_deinit(&b->chr, true);
+
+ if (b->child) {
+ object_unref(OBJECT(b->child));
+ }
+}
+
+static const TypeInfo vhost_user_backend_info = {
+ .name = TYPE_VHOST_USER_BACKEND,
+ .parent = TYPE_OBJECT,
+ .instance_size = sizeof(VhostUserBackend),
+ .instance_init = vhost_user_backend_init,
+ .instance_finalize = vhost_user_backend_finalize,
+ .class_size = sizeof(VhostUserBackendClass),
+};
+
+static void register_types(void)
+{
+ type_register_static(&vhost_user_backend_info);
+}
+
+type_init(register_types);
diff --git a/MAINTAINERS b/MAINTAINERS
index 6364a4ea9c..dbe71e6c1e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1427,6 +1427,8 @@ F: hw/*/*vhost*
F: docs/interop/vhost-user.json
F: docs/interop/vhost-user.txt
F: contrib/vhost-user-*/
+F: backends/vhost-user.c
+F: include/sysemu/vhost-user-backend.h
virtio
M: Michael S. Tsirkin <mst@redhat.com>
diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 717fcbdae4..a5ec0bf907 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -12,7 +12,8 @@ common-obj-y += cryptodev-builtin.o
ifeq ($(CONFIG_VIRTIO),y)
common-obj-y += cryptodev-vhost.o
common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) += \
- cryptodev-vhost-user.o
+ cryptodev-vhost-user.o \
+ vhost-user.o
endif
common-obj-$(CONFIG_LINUX) += hostmem-memfd.o
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 07/12] vhost-user: split vhost_user_read()
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (5 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 06/12] Add vhost-user-backend Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 08/12] vhost-user: add vhost_user_input_get_config() Marc-André Lureau
` (6 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Split vhost_user_read(), so only header can be read with
vhost_user_read_header().
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/virtio/vhost-user.c | 27 +++++++++++++++++++--------
1 file changed, 19 insertions(+), 8 deletions(-)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b2e1175c1e..0acf56fe96 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -210,7 +210,7 @@ static bool ioeventfd_enabled(void)
return !kvm_enabled() || kvm_eventfds_enabled();
}
-static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
+static int vhost_user_read_header(struct vhost_dev *dev, VhostUserMsg *msg)
{
struct vhost_user *u = dev->opaque;
CharBackend *chr = u->user->chr;
@@ -221,7 +221,7 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
if (r != size) {
error_report("Failed to read msg header. Read %d instead of %d."
" Original request %d.", r, size, msg->hdr.request);
- goto fail;
+ return -1;
}
/* validate received flags */
@@ -229,7 +229,21 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
error_report("Failed to read msg header."
" Flags 0x%x instead of 0x%x.", msg->hdr.flags,
VHOST_USER_REPLY_MASK | VHOST_USER_VERSION);
- goto fail;
+ return -1;
+ }
+
+ return 0;
+}
+
+static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
+{
+ struct vhost_user *u = dev->opaque;
+ CharBackend *chr = u->user->chr;
+ uint8_t *p = (uint8_t *) msg;
+ int r, size;
+
+ if (vhost_user_read_header(dev, msg) < 0) {
+ return -1;
}
/* validate message size is sane */
@@ -237,7 +251,7 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
error_report("Failed to read msg header."
" Size %d exceeds the maximum %zu.", msg->hdr.size,
VHOST_USER_PAYLOAD_SIZE);
- goto fail;
+ return -1;
}
if (msg->hdr.size) {
@@ -247,14 +261,11 @@ static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)
if (r != size) {
error_report("Failed to read msg payload."
" Read %d instead of %d.", r, msg->hdr.size);
- goto fail;
+ return -1;
}
}
return 0;
-
-fail:
- return -1;
}
static int process_message_reply(struct vhost_dev *dev,
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 08/12] vhost-user: add vhost_user_input_get_config()
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (6 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 07/12] vhost-user: split vhost_user_read() Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 09/12] libvhost-user-glib: export vug_source_new() Marc-André Lureau
` (5 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Ask vhost user input backend the list of virtio_input_config.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
---
contrib/libvhost-user/libvhost-user.h | 1 +
include/hw/virtio/vhost-backend.h | 4 ++
hw/virtio/vhost-user.c | 60 +++++++++++++++++++++++++++
docs/interop/vhost-user.txt | 8 ++++
4 files changed, 73 insertions(+)
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index c0133b7f3f..b0c798fa1a 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -91,6 +91,7 @@ typedef enum VhostUserRequest {
VHOST_USER_POSTCOPY_ADVISE = 28,
VHOST_USER_POSTCOPY_LISTEN = 29,
VHOST_USER_POSTCOPY_END = 30,
+ VHOST_USER_INPUT_GET_CONFIG = 31,
VHOST_USER_MAX
} VhostUserRequest;
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index 81283ec50f..1fca321d8a 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -12,6 +12,7 @@
#define VHOST_BACKEND_H
#include "exec/memory.h"
+#include "standard-headers/linux/virtio_input.h"
typedef enum VhostBackendType {
VHOST_BACKEND_TYPE_NONE = 0,
@@ -160,4 +161,7 @@ int vhost_backend_invalidate_device_iotlb(struct vhost_dev *dev,
int vhost_backend_handle_iotlb_msg(struct vhost_dev *dev,
struct vhost_iotlb_msg *imsg);
+int vhost_user_input_get_config(struct vhost_dev *dev,
+ struct virtio_input_config **config);
+
#endif /* VHOST_BACKEND_H */
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 0acf56fe96..272985adf2 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -89,6 +89,7 @@ typedef enum VhostUserRequest {
VHOST_USER_POSTCOPY_ADVISE = 28,
VHOST_USER_POSTCOPY_LISTEN = 29,
VHOST_USER_POSTCOPY_END = 30,
+ VHOST_USER_INPUT_GET_CONFIG = 31,
VHOST_USER_MAX
} VhostUserRequest;
@@ -338,6 +339,65 @@ static int vhost_user_write(struct vhost_dev *dev, VhostUserMsg *msg,
return 0;
}
+static void *vhost_user_read_size(struct vhost_dev *dev, uint32_t size)
+{
+ struct vhost_user *u = dev->opaque;
+ CharBackend *chr = u->user->chr;
+ int r;
+ uint8_t *p = g_malloc(size);
+
+ r = qemu_chr_fe_read_all(chr, p, size);
+ if (r != size) {
+ error_report("Failed to read msg payload."
+ " Read %d instead of %u.", r, size);
+ g_free(p);
+ return NULL;
+ }
+
+ return p;
+}
+
+int vhost_user_input_get_config(struct vhost_dev *dev,
+ struct virtio_input_config **config)
+{
+ void *p = NULL;
+ VhostUserMsg msg = {
+ .hdr.request = VHOST_USER_INPUT_GET_CONFIG,
+ .hdr.flags = VHOST_USER_VERSION,
+ };
+
+ if (vhost_user_write(dev, &msg, NULL, 0) < 0) {
+ goto err;
+ }
+
+ if (vhost_user_read_header(dev, &msg) < 0) {
+ goto err;
+ }
+
+ if (msg.hdr.request != VHOST_USER_INPUT_GET_CONFIG) {
+ error_report("Received unexpected msg type. Expected %d received %d",
+ VHOST_USER_INPUT_GET_CONFIG, msg.hdr.request);
+ goto err;
+ }
+
+ if (msg.hdr.size % sizeof(struct virtio_input_config)) {
+ error_report("Invalid msg size");
+ goto err;
+ }
+
+ p = vhost_user_read_size(dev, msg.hdr.size);
+ if (!p) {
+ goto err;
+ }
+
+ *config = p;
+ return msg.hdr.size / sizeof(struct virtio_input_config);
+
+err:
+ g_free(p);
+ return -1;
+}
+
static int vhost_user_set_log_base(struct vhost_dev *dev, uint64_t base,
struct vhost_log *log)
{
diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt
index 9ee2a60cfb..e145b3ec55 100644
--- a/docs/interop/vhost-user.txt
+++ b/docs/interop/vhost-user.txt
@@ -766,6 +766,14 @@ Master message types
was previously sent.
The value returned is an error indication; 0 is success.
+ * VHOST_USER_INPUT_GET_CONFIG
+ Id: 31
+ Master payload: N/A
+ Slave payload: (struct virtio_input_config)*
+
+ Ask vhost user input backend the list of virtio_input_config, in
+ host endianness.
+
Slave message types
-------------------
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 09/12] libvhost-user-glib: export vug_source_new()
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (7 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 08/12] vhost-user: add vhost_user_input_get_config() Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 10/12] libvhost-user: add vu_queue_unpop() Marc-André Lureau
` (4 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Simplify the creation of FD sources for other users. This is just
convenience to avoid duplicating similar code elsewhere.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
contrib/libvhost-user/libvhost-user-glib.h | 3 +++
contrib/libvhost-user/libvhost-user-glib.c | 11 ++++++-----
2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/contrib/libvhost-user/libvhost-user-glib.h b/contrib/libvhost-user/libvhost-user-glib.h
index 6b2110b94c..d3200f3afc 100644
--- a/contrib/libvhost-user/libvhost-user-glib.h
+++ b/contrib/libvhost-user/libvhost-user-glib.h
@@ -29,4 +29,7 @@ void vug_init(VugDev *dev, int socket,
vu_panic_cb panic, const VuDevIface *iface);
void vug_deinit(VugDev *dev);
+GSource *vug_source_new(VugDev *dev, int fd, GIOCondition cond,
+ vu_watch_cb vu_cb, gpointer data);
+
#endif /* LIBVHOST_USER_GLIB_H */
diff --git a/contrib/libvhost-user/libvhost-user-glib.c b/contrib/libvhost-user/libvhost-user-glib.c
index 545f089587..42660a1b36 100644
--- a/contrib/libvhost-user/libvhost-user-glib.c
+++ b/contrib/libvhost-user/libvhost-user-glib.c
@@ -68,15 +68,16 @@ static GSourceFuncs vug_src_funcs = {
NULL
};
-static GSource *
-vug_source_new(VuDev *dev, int fd, GIOCondition cond,
+GSource *
+vug_source_new(VugDev *gdev, int fd, GIOCondition cond,
vu_watch_cb vu_cb, gpointer data)
{
+ VuDev *dev = &gdev->parent;
GSource *gsrc;
VugSrc *src;
guint id;
- g_assert(dev);
+ g_assert(gdev);
g_assert(fd >= 0);
g_assert(vu_cb);
@@ -106,7 +107,7 @@ set_watch(VuDev *vu_dev, int fd, int vu_evt, vu_watch_cb cb, void *pvt)
g_assert(cb);
dev = container_of(vu_dev, VugDev, parent);
- src = vug_source_new(vu_dev, fd, vu_evt, cb, pvt);
+ src = vug_source_new(dev, fd, vu_evt, cb, pvt);
g_hash_table_replace(dev->fdmap, GINT_TO_POINTER(fd), src);
}
@@ -141,7 +142,7 @@ vug_init(VugDev *dev, int socket,
dev->fdmap = g_hash_table_new_full(NULL, NULL, NULL,
(GDestroyNotify) g_source_destroy);
- dev->src = vug_source_new(&dev->parent, socket, G_IO_IN, vug_watch, NULL);
+ dev->src = vug_source_new(dev, socket, G_IO_IN, vug_watch, NULL);
}
void
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 10/12] libvhost-user: add vu_queue_unpop()
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (8 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 09/12] libvhost-user-glib: export vug_source_new() Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci Marc-André Lureau
` (3 subsequent siblings)
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
vhost-user-input will make use of this function to undo some queue pop
in case the virtio queue does not have enough room.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
contrib/libvhost-user/libvhost-user.h | 14 ++++++++++++++
contrib/libvhost-user/libvhost-user.c | 16 ++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/contrib/libvhost-user/libvhost-user.h b/contrib/libvhost-user/libvhost-user.h
index b0c798fa1a..01738bf44a 100644
--- a/contrib/libvhost-user/libvhost-user.h
+++ b/contrib/libvhost-user/libvhost-user.h
@@ -459,6 +459,20 @@ void vu_queue_notify(VuDev *dev, VuVirtq *vq);
*/
void *vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz);
+
+/**
+ * vu_queue_unpop:
+ * @dev: a VuDev context
+ * @vq: a VuVirtq queue
+ * @elem: The #VuVirtqElement
+ * @len: number of bytes written
+ *
+ * Pretend the most recent element wasn't popped from the virtqueue. The next
+ * call to vu_queue_pop() will refetch the element.
+ */
+void vu_queue_unpop(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem,
+ size_t len);
+
/**
* vu_queue_rewind:
* @dev: a VuDev context
diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-user/libvhost-user.c
index fcf5014240..df72d3e440 100644
--- a/contrib/libvhost-user/libvhost-user.c
+++ b/contrib/libvhost-user/libvhost-user.c
@@ -1966,6 +1966,22 @@ vu_queue_pop(VuDev *dev, VuVirtq *vq, size_t sz)
return elem;
}
+static void
+vu_queue_detach_element(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem,
+ size_t len)
+{
+ vq->inuse--;
+ /* unmap, when DMA support is added */
+}
+
+void
+vu_queue_unpop(VuDev *dev, VuVirtq *vq, VuVirtqElement *elem,
+ size_t len)
+{
+ vq->last_avail_idx--;
+ vu_queue_detach_element(dev, vq, elem, len);
+}
+
bool
vu_queue_rewind(VuDev *dev, VuVirtq *vq, unsigned int num)
{
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (9 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 10/12] libvhost-user: add vu_queue_unpop() Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 13:13 ` Gerd Hoffmann
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input Marc-André Lureau
` (2 subsequent siblings)
13 siblings, 1 reply; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
Add a new virtio-input device, which connects to a vhost-user
backend.
vhost-user-input is similar to virtio-input-host, it is wrapped by
vhost-user-input-pci. Instead of reading configuration directly from
an input device / evdev, it reads it over vhost-user protocol with
INPUT_GET_CONFIG message. Then vhost-user-backend takes care of
interfacing the virtio device with the backend, for the queue & events
processing.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
include/hw/virtio/virtio-input.h | 14 +++++
hw/input/vhost-user-input.c | 99 ++++++++++++++++++++++++++++++++
hw/virtio/vhost-user-input-pci.c | 53 +++++++++++++++++
MAINTAINERS | 1 +
default-configs/virtio.mak | 1 +
hw/input/Makefile.objs | 1 +
hw/virtio/Makefile.objs | 1 +
7 files changed, 170 insertions(+)
create mode 100644 hw/input/vhost-user-input.c
create mode 100644 hw/virtio/vhost-user-input-pci.c
diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h
index 054c38836f..4fca03e796 100644
--- a/include/hw/virtio/virtio-input.h
+++ b/include/hw/virtio/virtio-input.h
@@ -2,6 +2,7 @@
#define QEMU_VIRTIO_INPUT_H
#include "ui/input.h"
+#include "sysemu/vhost-user-backend.h"
/* ----------------------------------------------------------------- */
/* virtio input protocol */
@@ -42,11 +43,18 @@ typedef struct virtio_input_event virtio_input_event;
#define VIRTIO_INPUT_HOST_GET_PARENT_CLASS(obj) \
OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_INPUT_HOST)
+#define TYPE_VHOST_USER_INPUT "vhost-user-input"
+#define VHOST_USER_INPUT(obj) \
+ OBJECT_CHECK(VHostUserInput, (obj), TYPE_VHOST_USER_INPUT)
+#define VHOST_USER_INPUT_GET_PARENT_CLASS(obj) \
+ OBJECT_GET_PARENT_CLASS(obj, TYPE_VHOST_USER_INPUT)
+
typedef struct VirtIOInput VirtIOInput;
typedef struct VirtIOInputClass VirtIOInputClass;
typedef struct VirtIOInputConfig VirtIOInputConfig;
typedef struct VirtIOInputHID VirtIOInputHID;
typedef struct VirtIOInputHost VirtIOInputHost;
+typedef struct VHostUserInput VHostUserInput;
struct VirtIOInputConfig {
virtio_input_config config;
@@ -98,6 +106,12 @@ struct VirtIOInputHost {
int fd;
};
+struct VHostUserInput {
+ VirtIOInput parent_obj;
+
+ VhostUserBackend *vhost;
+};
+
void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event);
void virtio_input_init_config(VirtIOInput *vinput,
virtio_input_config *config);
diff --git a/hw/input/vhost-user-input.c b/hw/input/vhost-user-input.c
new file mode 100644
index 0000000000..41c25d2398
--- /dev/null
+++ b/hw/input/vhost-user-input.c
@@ -0,0 +1,99 @@
+/*
+ * 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 "qapi/error.h"
+#include "qemu-common.h"
+
+#include "hw/qdev.h"
+#include "hw/virtio/virtio-input.h"
+
+static void vhost_input_realize(DeviceState *dev, Error **errp)
+{
+ VHostUserInput *vhi = VHOST_USER_INPUT(dev);
+ VirtIOInput *vinput = VIRTIO_INPUT(dev);
+ VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+ virtio_input_config *config;
+ int i, ret;
+
+ if (vhost_user_backend_dev_init(vhi->vhost, vdev, 2, errp) == -1) {
+ return;
+ }
+
+ ret = vhost_user_input_get_config(&vhi->vhost->dev, &config);
+ if (ret < 0) {
+ error_setg(errp, "failed to get input config");
+ return;
+ }
+ for (i = 0; i < ret; i++) {
+ virtio_input_add_config(vinput, &config[i]);
+ }
+ g_free(config);
+}
+
+static void vhost_input_change_active(VirtIOInput *vinput)
+{
+ VHostUserInput *vhi = VHOST_USER_INPUT(vinput);
+
+ if (vinput->active) {
+ vhost_user_backend_start(vhi->vhost);
+ } else {
+ vhost_user_backend_stop(vhi->vhost);
+ }
+}
+
+static const VMStateDescription vmstate_vhost_input = {
+ .name = "vhost-user-input",
+ .unmigratable = 1,
+};
+
+static void vhost_input_class_init(ObjectClass *klass, void *data)
+{
+ VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass);
+ DeviceClass *dc = DEVICE_CLASS(klass);
+
+ dc->vmsd = &vmstate_vhost_input;
+ vic->realize = vhost_input_realize;
+ vic->change_active = vhost_input_change_active;
+}
+
+static void vhost_input_init(Object *obj)
+{
+ VHostUserInput *vhi = VHOST_USER_INPUT(obj);
+ VirtIOInput *vinput = VIRTIO_INPUT(obj);
+ struct virtio_input_config vhost_input_config[] = { { /* empty list */ } };
+
+ virtio_input_init_config(vinput, vhost_input_config);
+
+ vhi->vhost = VHOST_USER_BACKEND(object_new(TYPE_VHOST_USER_BACKEND));
+ object_property_add_alias(obj, "chardev",
+ OBJECT(vhi->vhost), "chardev", &error_abort);
+}
+
+static void vhost_input_finalize(Object *obj)
+{
+ VHostUserInput *vhi = VHOST_USER_INPUT(obj);
+
+ object_unref(OBJECT(vhi->vhost));
+}
+
+static const TypeInfo vhost_input_info = {
+ .name = TYPE_VHOST_USER_INPUT,
+ .parent = TYPE_VIRTIO_INPUT,
+ .instance_size = sizeof(VHostUserInput),
+ .instance_init = vhost_input_init,
+ .instance_finalize = vhost_input_finalize,
+ .class_init = vhost_input_class_init,
+};
+
+/* ----------------------------------------------------------------- */
+
+static void vhost_input_register_types(void)
+{
+ type_register_static(&vhost_input_info);
+}
+
+type_init(vhost_input_register_types)
diff --git a/hw/virtio/vhost-user-input-pci.c b/hw/virtio/vhost-user-input-pci.c
new file mode 100644
index 0000000000..3d1b7a85fd
--- /dev/null
+++ b/hw/virtio/vhost-user-input-pci.c
@@ -0,0 +1,53 @@
+/*
+ * This work is licensed under the terms of the GNU LGPL, version 2 or
+ * later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-input.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+#include "virtio-pci.h"
+
+typedef struct VHostUserInputPCI VHostUserInputPCI;
+
+#define TYPE_VHOST_USER_INPUT_PCI "vhost-user-input-pci-base"
+
+#define VHOST_USER_INPUT_PCI(obj) \
+ OBJECT_CHECK(VHostUserInputPCI, (obj), TYPE_VHOST_USER_INPUT_PCI)
+
+struct VHostUserInputPCI {
+ VirtIOPCIProxy parent_obj;
+ VHostUserInput vhi;
+};
+
+static void vhost_user_input_pci_instance_init(Object *obj)
+{
+ VHostUserInputPCI *dev = VHOST_USER_INPUT_PCI(obj);
+
+ virtio_instance_init_common(obj, &dev->vhi, sizeof(dev->vhi),
+ TYPE_VHOST_USER_INPUT);
+
+ object_property_add_alias(obj, "chardev",
+ OBJECT(&dev->vhi), "chardev",
+ &error_abort);
+}
+
+static const VirtioPCIDeviceTypeInfo vhost_user_input_pci_info = {
+ .base_name = TYPE_VHOST_USER_INPUT_PCI,
+ .generic_name = "vhost-user-input-pci",
+ .transitional_name = "vhost-user-input-pci-transitional",
+ .non_transitional_name = "vhost-user-input-pci-non-transitional",
+ .parent = TYPE_VIRTIO_INPUT_PCI,
+ .instance_size = sizeof(VHostUserInputPCI),
+ .instance_init = vhost_user_input_pci_instance_init,
+};
+
+static void vhost_user_input_pci_register(void)
+{
+ virtio_pci_types_register(&vhost_user_input_pci_info);
+}
+
+type_init(vhost_user_input_pci_register)
diff --git a/MAINTAINERS b/MAINTAINERS
index dbe71e6c1e..c3eb708306 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1470,6 +1470,7 @@ L: qemu-s390x@nongnu.org
virtio-input
M: Gerd Hoffmann <kraxel@redhat.com>
S: Maintained
+F: hw/input/vhost-user-input.c
F: hw/input/virtio-input*.c
F: include/hw/virtio/virtio-input.h
diff --git a/default-configs/virtio.mak b/default-configs/virtio.mak
index ecb4420e74..5f5266ef8b 100644
--- a/default-configs/virtio.mak
+++ b/default-configs/virtio.mak
@@ -13,3 +13,4 @@ CONFIG_SCSI=y
CONFIG_VIRTIO_SCSI=y
CONFIG_VIRTIO_SERIAL=y
CONFIG_VIRTIO_INPUT_HOST=$(CONFIG_LINUX)
+CONFIG_VHOST_USER_INPUT=$(call land,$(CONFIG_VHOST_USER),$(CONFIG_VIRTIO_INPUT))
diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs
index c8b00f71ec..9511e3102f 100644
--- a/hw/input/Makefile.objs
+++ b/hw/input/Makefile.objs
@@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_INPUT) += virtio-input.o
common-obj-$(CONFIG_VIRTIO_INPUT) += virtio-input-hid.o
ifeq ($(CONFIG_LINUX),y)
common-obj-$(CONFIG_VIRTIO_INPUT) += virtio-input-host.o
+common-obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input.o
endif
obj-$(CONFIG_MILKYMIST) += milkymist-softusb.o
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index d335dd0a6a..7462051ba3 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -14,6 +14,7 @@ obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
ifeq ($(CONFIG_VIRTIO_PCI),y)
obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock-pci.o
obj-$(CONFIG_VHOST_USER_BLK) += vhost-user-blk-pci.o
+obj-$(CONFIG_VHOST_USER_INPUT) += vhost-user-input-pci.o
obj-$(CONFIG_VHOST_USER_SCSI) += vhost-user-scsi-pci.o
obj-$(CONFIG_VHOST_SCSI) += vhost-scsi-pci.o
obj-$(CONFIG_VIRTIO_INPUT_HOST) += virtio-input-host-pci.o
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (10 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci Marc-André Lureau
@ 2019-02-27 10:30 ` Marc-André Lureau
2019-02-27 13:14 ` Gerd Hoffmann
2019-02-27 10:46 ` [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
2019-03-05 20:56 ` Michael S. Tsirkin
13 siblings, 1 reply; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:30 UTC (permalink / raw)
To: qemu-devel; +Cc: kraxel, mst
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
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
contrib/vhost-user-input/main.c | 398 +++++++++++++++++++++++++
MAINTAINERS | 1 +
Makefile | 3 +
Makefile.objs | 1 +
configure | 3 +
contrib/vhost-user-input/Makefile.objs | 1 +
6 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/contrib/vhost-user-input/main.c b/contrib/vhost-user-input/main.c
new file mode 100644
index 0000000000..bef44f163d
--- /dev/null
+++ b/contrib/vhost-user-input/main.c
@@ -0,0 +1,398 @@
+/*
+ * 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 "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;
+ 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 int
+vi_process_msg(VuDev *dev, VhostUserMsg *vmsg, int *do_reply)
+{
+ VuInput *vi = container_of(dev, VuInput, dev.parent);
+
+ switch (vmsg->request) {
+ case VHOST_USER_INPUT_GET_CONFIG:
+ vmsg->size = vi->config->len * sizeof(virtio_input_config);
+ vmsg->data = g_memdup(vi->config->data, vmsg->size);
+ *do_reply = true;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static const VuDevIface vuiface = {
+ .queue_set_started = vi_queue_set_started,
+ .process_msg = vi_process_msg,
+};
+
+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 int unix_sock_new(char *path)
+{
+ int sock;
+ struct sockaddr_un un;
+ size_t len;
+
+ sock = socket(AF_UNIX, SOCK_STREAM, 0);
+ if (sock <= 0) {
+ perror("socket");
+ return -1;
+ }
+
+ un.sun_family = AF_UNIX;
+ snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
+ len = sizeof(un.sun_family) + strlen(un.sun_path);
+
+ unlink(path);
+ if (bind(sock, (struct sockaddr *)&un, len) < 0) {
+ perror("bind");
+ goto fail;
+ }
+
+ if (listen(sock, 1) < 0) {
+ perror("listen");
+ goto fail;
+ }
+
+ return sock;
+
+fail:
+ close(sock);
+
+ return -1;
+}
+
+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_sock_new(opt_socket_path);
+ 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 c3eb708306..df4461d457 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1473,6 +1473,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/Makefile b/Makefile
index 7fa04e0821..9e53a8295b 100644
--- a/Makefile
+++ b/Makefile
@@ -370,6 +370,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 \
@@ -590,6 +591,8 @@ vhost-user-blk$(EXESUF): $(vhost-user-blk-obj-y) libvhost-user.a
rdmacm-mux$(EXESUF): LIBS += "-libumad"
rdmacm-mux$(EXESUF): $(rdmacm-mux-obj-y) $(COMMON_LDADDS)
$(call LINK, $^)
+vhost-user-input$(EXESUF): $(vhost-user-input-obj-y) libvhost-user.a libqemuutil.a
+ $(call LINK, $^)
module_block.h: $(SRC_PATH)/scripts/modules/module_block.py config-host.mak
$(call quiet-command,$(PYTHON) $< $@ \
diff --git a/Makefile.objs b/Makefile.objs
index 6e91ee5674..8084d9270c 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -124,6 +124,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/configure b/configure
index 694088a4ec..6afa99e72c 100755
--- a/configure
+++ b/configure
@@ -5833,6 +5833,9 @@ if test "$want_tools" = "yes" ; then
if [ "$curl" = "yes" ]; then
tools="elf2dmp\$(EXESUF) $tools"
fi
+ if [ "$vhost_user" = "yes" ] && [ "$linux" = "yes" ] ; then
+ tools="vhost-user-input\$(EXESUF) $tools"
+ fi
fi
if test "$softmmu" = yes ; then
if test "$linux" = yes; then
diff --git a/contrib/vhost-user-input/Makefile.objs b/contrib/vhost-user-input/Makefile.objs
new file mode 100644
index 0000000000..b1fad90d51
--- /dev/null
+++ b/contrib/vhost-user-input/Makefile.objs
@@ -0,0 +1 @@
+vhost-user-input-obj-y = main.o
--
2.21.0
^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (11 preceding siblings ...)
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input Marc-André Lureau
@ 2019-02-27 10:46 ` Marc-André Lureau
2019-03-05 20:56 ` Michael S. Tsirkin
13 siblings, 0 replies; 17+ messages in thread
From: Marc-André Lureau @ 2019-02-27 10:46 UTC (permalink / raw)
To: QEMU; +Cc: Gerd Hoffmann, Michael S. Tsirkin
Hi,
On Wed, Feb 27, 2019 at 11:38 AM Marc-André Lureau
<marcandre.lureau@redhat.com> wrote:
>
> Hi,
>
> This series is based on previously discussed "[PATCH v4 00/29]
> vhost-user for input & GPU" and "vhost-user: define conventions for
> vhost-user backends" work. The GPU part is left off for now.
>
> This series introduces a "vhost-user-backend": an helper object to be
> used by vhost-user devices to ease with backend initialization and
> handling. As a simple showcase, a "vhost-user-input-pci" device is
> introduced, which can be used with the "contrib: add vhost-user-input"
> example. vhost-user-input isn't meant to be installed, discovered or
> used by libvirt: no installation is done (no vhost-user JSON file is
> provided either).
>
> thanks
>
> v4:
> - drop "RFC: add explicit can_migrate to vhost_user_backend_dev_init()"
> - remove useless "cmd" struct field leftover
I suggest to apply this series through the virtio & vhost-user tree,
which Michael maintains.
The upcoming vhost-user-gpu series should more naturally fall under
Gerd responsability.
>
> v3:
> - add previously sent patch "libvhost-user: fix clang enum-conversion
> warning" to fix clang build
> - "define conventions for vhost-user backends" updates after Eric review
> - Drop user-creatable from vhost-user-backend
> - Make vhost-user-input-pci take a chardev= (instead of vhost-user=)
>
> v2:
> - rebased (VhostUserInputPCI got most of the changes, due to split)
> - added "RFC: add explicit can_migrate to
> vhost_user_backend_dev_init()" to attempt to address Michael
> concerns about migration.
>
> Marc-André Lureau (12):
> libvhost-user: fix clang enum-conversion warning
> vhost-user: define conventions for vhost-user backends
> vhost-user: simplify vhost_user_init/vhost_user_cleanup
> libvhost-user: exit by default on VHOST_USER_NONE
> vhost-user: wrap some read/write with retry handling
> Add vhost-user-backend
> vhost-user: split vhost_user_read()
> vhost-user: add vhost_user_input_get_config()
> libvhost-user-glib: export vug_source_new()
> libvhost-user: add vu_queue_unpop()
> Add vhost-user-input-pci
> contrib: add vhost-user-input
>
> contrib/libvhost-user/libvhost-user-glib.h | 3 +
> contrib/libvhost-user/libvhost-user.h | 17 +-
> include/hw/virtio/vhost-backend.h | 4 +
> include/hw/virtio/vhost-user-blk.h | 2 +-
> include/hw/virtio/vhost-user-scsi.h | 2 +-
> include/hw/virtio/vhost-user.h | 2 +-
> include/hw/virtio/virtio-input.h | 14 +
> include/sysemu/vhost-user-backend.h | 58 +++
> backends/cryptodev-vhost-user.c | 18 +-
> backends/vhost-user.c | 213 +++++++++++
> contrib/libvhost-user/libvhost-user-glib.c | 11 +-
> contrib/libvhost-user/libvhost-user.c | 19 +-
> contrib/vhost-user-input/main.c | 398 +++++++++++++++++++++
> hw/block/vhost-user-blk.c | 22 +-
> hw/input/vhost-user-input.c | 99 +++++
> hw/scsi/vhost-user-scsi.c | 20 +-
> hw/virtio/vhost-stub.c | 4 +-
> hw/virtio/vhost-user-input-pci.c | 53 +++
> hw/virtio/vhost-user.c | 118 +++++-
> net/vhost-user.c | 13 +-
> MAINTAINERS | 5 +
> Makefile | 3 +
> Makefile.objs | 1 +
> backends/Makefile.objs | 3 +-
> configure | 3 +
> contrib/vhost-user-input/Makefile.objs | 1 +
> default-configs/virtio.mak | 1 +
> docs/interop/vhost-user.json | 232 ++++++++++++
> docs/interop/vhost-user.txt | 109 +++++-
> hw/input/Makefile.objs | 1 +
> hw/virtio/Makefile.objs | 1 +
> 31 files changed, 1363 insertions(+), 87 deletions(-)
> create mode 100644 include/sysemu/vhost-user-backend.h
> create mode 100644 backends/vhost-user.c
> create mode 100644 contrib/vhost-user-input/main.c
> create mode 100644 hw/input/vhost-user-input.c
> create mode 100644 hw/virtio/vhost-user-input-pci.c
> create mode 100644 contrib/vhost-user-input/Makefile.objs
> create mode 100644 docs/interop/vhost-user.json
>
> --
> 2.21.0
>
>
--
Marc-André Lureau
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci Marc-André Lureau
@ 2019-02-27 13:13 ` Gerd Hoffmann
0 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2019-02-27 13:13 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, mst
On Wed, Feb 27, 2019 at 11:30:16AM +0100, Marc-André Lureau wrote:
> Add a new virtio-input device, which connects to a vhost-user
> backend.
>
> vhost-user-input is similar to virtio-input-host, it is wrapped by
> vhost-user-input-pci. Instead of reading configuration directly from
> an input device / evdev, it reads it over vhost-user protocol with
> INPUT_GET_CONFIG message. Then vhost-user-backend takes care of
> interfacing the virtio device with the backend, for the queue & events
> processing.
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input Marc-André Lureau
@ 2019-02-27 13:14 ` Gerd Hoffmann
0 siblings, 0 replies; 17+ messages in thread
From: Gerd Hoffmann @ 2019-02-27 13:14 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, mst
On Wed, Feb 27, 2019 at 11:30:17AM +0100, Marc-André Lureau wrote:
> 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
>
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Gerd Hoffmann <kraxel@redhat.com>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
` (12 preceding siblings ...)
2019-02-27 10:46 ` [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
@ 2019-03-05 20:56 ` Michael S. Tsirkin
13 siblings, 0 replies; 17+ messages in thread
From: Michael S. Tsirkin @ 2019-03-05 20:56 UTC (permalink / raw)
To: Marc-André Lureau; +Cc: qemu-devel, kraxel
On Wed, Feb 27, 2019 at 11:30:05AM +0100, Marc-André Lureau wrote:
> Hi,
>
> This series is based on previously discussed "[PATCH v4 00/29]
> vhost-user for input & GPU" and "vhost-user: define conventions for
> vhost-user backends" work. The GPU part is left off for now.
>
> This series introduces a "vhost-user-backend": an helper object to be
> used by vhost-user devices to ease with backend initialization and
> handling. As a simple showcase, a "vhost-user-input-pci" device is
> introduced, which can be used with the "contrib: add vhost-user-input"
> example. vhost-user-input isn't meant to be installed, discovered or
> used by libvirt: no installation is done (no vhost-user JSON file is
> provided either).
>
> thanks
can you rebase on top of master pls?
> v4:
> - drop "RFC: add explicit can_migrate to vhost_user_backend_dev_init()"
> - remove useless "cmd" struct field leftover
>
> v3:
> - add previously sent patch "libvhost-user: fix clang enum-conversion
> warning" to fix clang build
> - "define conventions for vhost-user backends" updates after Eric review
> - Drop user-creatable from vhost-user-backend
> - Make vhost-user-input-pci take a chardev= (instead of vhost-user=)
>
> v2:
> - rebased (VhostUserInputPCI got most of the changes, due to split)
> - added "RFC: add explicit can_migrate to
> vhost_user_backend_dev_init()" to attempt to address Michael
> concerns about migration.
>
> Marc-André Lureau (12):
> libvhost-user: fix clang enum-conversion warning
> vhost-user: define conventions for vhost-user backends
> vhost-user: simplify vhost_user_init/vhost_user_cleanup
> libvhost-user: exit by default on VHOST_USER_NONE
> vhost-user: wrap some read/write with retry handling
> Add vhost-user-backend
> vhost-user: split vhost_user_read()
> vhost-user: add vhost_user_input_get_config()
> libvhost-user-glib: export vug_source_new()
> libvhost-user: add vu_queue_unpop()
> Add vhost-user-input-pci
> contrib: add vhost-user-input
>
> contrib/libvhost-user/libvhost-user-glib.h | 3 +
> contrib/libvhost-user/libvhost-user.h | 17 +-
> include/hw/virtio/vhost-backend.h | 4 +
> include/hw/virtio/vhost-user-blk.h | 2 +-
> include/hw/virtio/vhost-user-scsi.h | 2 +-
> include/hw/virtio/vhost-user.h | 2 +-
> include/hw/virtio/virtio-input.h | 14 +
> include/sysemu/vhost-user-backend.h | 58 +++
> backends/cryptodev-vhost-user.c | 18 +-
> backends/vhost-user.c | 213 +++++++++++
> contrib/libvhost-user/libvhost-user-glib.c | 11 +-
> contrib/libvhost-user/libvhost-user.c | 19 +-
> contrib/vhost-user-input/main.c | 398 +++++++++++++++++++++
> hw/block/vhost-user-blk.c | 22 +-
> hw/input/vhost-user-input.c | 99 +++++
> hw/scsi/vhost-user-scsi.c | 20 +-
> hw/virtio/vhost-stub.c | 4 +-
> hw/virtio/vhost-user-input-pci.c | 53 +++
> hw/virtio/vhost-user.c | 118 +++++-
> net/vhost-user.c | 13 +-
> MAINTAINERS | 5 +
> Makefile | 3 +
> Makefile.objs | 1 +
> backends/Makefile.objs | 3 +-
> configure | 3 +
> contrib/vhost-user-input/Makefile.objs | 1 +
> default-configs/virtio.mak | 1 +
> docs/interop/vhost-user.json | 232 ++++++++++++
> docs/interop/vhost-user.txt | 109 +++++-
> hw/input/Makefile.objs | 1 +
> hw/virtio/Makefile.objs | 1 +
> 31 files changed, 1363 insertions(+), 87 deletions(-)
> create mode 100644 include/sysemu/vhost-user-backend.h
> create mode 100644 backends/vhost-user.c
> create mode 100644 contrib/vhost-user-input/main.c
> create mode 100644 hw/input/vhost-user-input.c
> create mode 100644 hw/virtio/vhost-user-input-pci.c
> create mode 100644 contrib/vhost-user-input/Makefile.objs
> create mode 100644 docs/interop/vhost-user.json
>
> --
> 2.21.0
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2019-03-05 20:56 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-27 10:30 [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 01/12] libvhost-user: fix clang enum-conversion warning Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 02/12] vhost-user: define conventions for vhost-user backends Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 03/12] vhost-user: simplify vhost_user_init/vhost_user_cleanup Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 04/12] libvhost-user: exit by default on VHOST_USER_NONE Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 05/12] vhost-user: wrap some read/write with retry handling Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 06/12] Add vhost-user-backend Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 07/12] vhost-user: split vhost_user_read() Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 08/12] vhost-user: add vhost_user_input_get_config() Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 09/12] libvhost-user-glib: export vug_source_new() Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 10/12] libvhost-user: add vu_queue_unpop() Marc-André Lureau
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 11/12] Add vhost-user-input-pci Marc-André Lureau
2019-02-27 13:13 ` Gerd Hoffmann
2019-02-27 10:30 ` [Qemu-devel] [PATCH v4 12/12] contrib: add vhost-user-input Marc-André Lureau
2019-02-27 13:14 ` Gerd Hoffmann
2019-02-27 10:46 ` [Qemu-devel] [PATCH v4 00/12] vhost-user-backend & vhost-user-input Marc-André Lureau
2019-03-05 20:56 ` Michael S. Tsirkin
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.