From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236504714852.4789106526762; Mon, 26 Nov 2018 04:48:24 -0800 (PST) Received: from localhost ([::1]:35533 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGJF-00023d-Re for importer@patchew.org; Mon, 26 Nov 2018 07:48:17 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49098) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGEX-00075W-IC for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:27 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGET-0006Yf-G2 for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:25 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35638) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGET-0006W4-7k for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:21 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 132B0308FED0 for ; Mon, 26 Nov 2018 12:43:19 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 73AF753B31; Mon, 26 Nov 2018 12:43:08 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:40 +0400 Message-Id: <20181126124250.29985-2-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Mon, 26 Nov 2018 12:43:19 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 01/11] vhost-user: define conventions for vhost-user backends X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 Acked-by: Gerd Hoffmann --- MAINTAINERS | 1 + docs/interop/vhost-user.json | 219 +++++++++++++++++++++++++++++++++++ docs/interop/vhost-user.txt | 101 +++++++++++++++- 3 files changed, 319 insertions(+), 2 deletions(-) create mode 100644 docs/interop/vhost-user.json diff --git a/MAINTAINERS b/MAINTAINERS index 1032406c56..81e4368a43 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1335,6 +1335,7 @@ vhost M: Michael S. Tsirkin S: Supported F: hw/*/*vhost* +F: docs/interop/vhost-user.json F: docs/interop/vhost-user.txt =20 virtio diff --git a/docs/interop/vhost-user.json b/docs/interop/vhost-user.json new file mode 100644 index 0000000000..91b5bf499e --- /dev/null +++ b/docs/interop/vhost-user.json @@ -0,0 +1,219 @@ +# -*- Mode: Python -*- +# +# Copyright (C) 2018 Red Hat, Inc. +# +# Authors: +# Marc-Andr=C3=A9 Lureau +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + +## +# =3D vhost user backend discovery & capabilities +## + +## +# @VHostUserBackendType: +# +# List the various vhost user backend types. +# +# @net: virtio net +# @block: virtio block +# @console: virtio console +# @rng: virtio rng +# @balloon: virtio balloon +# @rpmsg: virtio remote processor messaging +# @scsi: virtio scsi +# @9p: 9p virtio console +# @rproc-serial: virtio remoteproc serial link +# @caif: virtio caif +# @gpu: virtio gpu +# @input: virtio input +# @vsock: virtio vsock transport +# @crypto: virtio crypto +# +# Since: 3.2 +## +{ + 'enum': 'VHostUserBackendType', + 'data': [ 'net', 'block', 'console', 'rng', 'balloon', 'rpmsg', + 'scsi', '9p', 'rproc-serial', 'caif', 'gpu', 'input', 'vsock', + 'crypto' ] +} + +## +# @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: 3.2 +## +{ + 'enum': 'VHostUserBackendInputFeature', + 'data': [ 'evdev-path', 'no-grab' ] +} + +## +# @VHostUserBackendCapabilitiesInput: +# +# Capabilities reported by vhost user "input" backends +# +# @features: list of supported features. +# +# Since: 3.2 +## +{ + '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: 3.2 +## +{ + 'enum': 'VHostUserBackendGPUFeature', + 'data': [ 'render-node', 'virgl' ] +} + +## +# @VHostUserBackendCapabilitiesGPU: +# +# Capabilities reported by vhost user "gpu" backends. +# +# @features: list of supported features. +# +# Since: 3.2 +## +{ + 'struct': 'VHostUserBackendCapabilitiesGPU', + 'data': { + 'features': [ 'VHostUserBackendGPUFeature' ] + } +} + +## +# @VHostUserBackendCapabilities: +# +# Capabilities reported by vhost user backends. +# +# @type: The vhost user backend type. +# +# Since: 3.2 +## +{ + '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., last pathname +# 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: 3.2 +# +# Example: +# +# { +# "description": "QEMU vhost-user-gpu", +# "type": "gpu", +# "binary": "/usr/libexec/qemu/vhost-user-gpu", +# "tags": [ +# "CONFIG_OPENGL_DMABUF=3Dy" +# ] +# } +# +## +{ + '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..cefec9ffe1 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, maste= r and slave. Master is the application that shares its virtqueues, in our case QEMU. Slave is the consumer of the virtqueues. =20 -In the current implementation QEMU is the Master, and the Slave is intende= d 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. =20 Master and slave can be either a client (i.e. connecting) or server (liste= ning) 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 br= ings 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 +!=3D 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 be 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=3DPATH + +This option specify the location of the vhost-user Unix domain socket. +It is incompatible with --fd. + +* --fd=3DFDNUM + +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=3DPATH (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=3DPATH (optional) + +Specify the GPU DRM render node. + +* --virgl (optional) + +Enable virgl rendering support. --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236360829657.4528876242914; Mon, 26 Nov 2018 04:46:00 -0800 (PST) Received: from localhost ([::1]:35521 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGGv-0000BG-Ip for importer@patchew.org; Mon, 26 Nov 2018 07:45:53 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49433) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGF0-0007Qn-3k for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:56 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGEy-0007C5-Kg for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:57198) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGEs-000753-Tl; Mon, 26 Nov 2018 07:43:47 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3556185A07; Mon, 26 Nov 2018 12:43:46 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0E2B7608C3; Mon, 26 Nov 2018 12:43:22 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:41 +0400 Message-Id: <20181126124250.29985-3-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Mon, 26 Nov 2018 12:43:46 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 02/11] vhost-user: simplify vhost_user_init/vhost_user_cleanup X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Fam Zheng , "open list:Block layer core" , Tiwei Bie , "Michael S. Tsirkin" , Jason Wang , Max Reitz , Gonglei , kraxel@redhat.com, Paolo Bonzini , =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Take a VhostUserState* that can be pre-allocated, and initialize it with the associated chardev. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Tiwei Bie --- 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-u= ser-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; =20 #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 @@ =20 typedef struct VHostUserSCSI { VHostSCSICommon parent_obj; - VhostUserState *vhost_user; + VhostUserState vhost_user; } VHostUserSCSI; =20 #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; =20 -VhostUserState *vhost_user_init(void); +bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp); void vhost_user_cleanup(VhostUserState *user); =20 #endif diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.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; =20 - VhostUserState *vhost_user; + VhostUserState vhost_user; CharBackend chr; char *chr_name; bool opened; @@ -104,7 +104,7 @@ cryptodev_vhost_user_start(int queues, continue; } =20 - options.opaque =3D s->vhost_user; + options.opaque =3D &s->vhost_user; options.backend_type =3D VHOST_BACKEND_TYPE_USER; options.cc =3D b->conf.peers.ccs[i]; s->vhost_crypto[i] =3D cryptodev_vhost_init(&options); @@ -182,7 +182,6 @@ static void cryptodev_vhost_user_init( size_t i; Error *local_err =3D NULL; Chardev *chr; - VhostUserState *user; CryptoDevBackendClient *cc; CryptoDevBackendVhostUser *s =3D CRYPTODEV_BACKEND_VHOST_USER(backend); @@ -213,15 +212,10 @@ static void cryptodev_vhost_user_init( } } =20 - user =3D vhost_user_init(); - if (!user) { - error_setg(errp, "Failed to init vhost_user"); + if (!vhost_user_init(&s->vhost_user, &s->chr, errp)) { return; } =20 - user->chr =3D &s->chr; - s->vhost_user =3D user; - qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, cryptodev_vhost_user_event, NULL, s, NULL, true); =20 @@ -307,11 +301,7 @@ static void cryptodev_vhost_user_cleanup( } } =20 - if (s->vhost_user) { - vhost_user_cleanup(s->vhost_user); - g_free(s->vhost_user); - s->vhost_user =3D NULL; - } + vhost_user_cleanup(&s->vhost_user); } =20 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 1451940845..e728fbe7f9 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -249,7 +249,6 @@ static void vhost_user_blk_device_realize(DeviceState *= dev, Error **errp) { VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); VHostUserBlk *s =3D VHOST_USER_BLK(vdev); - VhostUserState *user; int i, ret; =20 if (!s->chardev.chr) { @@ -267,15 +266,10 @@ static void vhost_user_blk_device_realize(DeviceState= *dev, Error **errp) return; } =20 - user =3D 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; } =20 - user->chr =3D &s->chardev; - s->vhost_user =3D user; - virtio_init(vdev, "virtio-blk", VIRTIO_ID_BLOCK, sizeof(struct virtio_blk_config)); =20 @@ -291,7 +285,7 @@ static void vhost_user_blk_device_realize(DeviceState *= dev, Error **errp) =20 vhost_dev_set_config_notifier(&s->dev, &blk_ops); =20 - ret =3D vhost_dev_init(&s->dev, s->vhost_user, VHOST_BACKEND_TYPE_USER= , 0); + ret =3D vhost_dev_init(&s->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USE= R, 0); if (ret < 0) { error_setg(errp, "vhost-user-blk: vhost initialization failed: %s", strerror(-ret)); @@ -316,10 +310,7 @@ vhost_err: virtio_err: g_free(s->dev.vqs); virtio_cleanup(vdev); - - vhost_user_cleanup(user); - g_free(user); - s->vhost_user =3D NULL; + vhost_user_cleanup(&s->vhost_user); } =20 static void vhost_user_blk_device_unrealize(DeviceState *dev, Error **errp) @@ -331,12 +322,7 @@ static void vhost_user_blk_device_unrealize(DeviceStat= e *dev, Error **errp) vhost_dev_cleanup(&s->dev); g_free(s->dev.vqs); virtio_cleanup(vdev); - - if (s->vhost_user) { - vhost_user_cleanup(s->vhost_user); - g_free(s->vhost_user); - s->vhost_user =3D NULL; - } + vhost_user_cleanup(&s->vhost_user); } =20 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 2e1ba4a87b..fb73c36c44 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, Err= or **errp) VirtIOSCSICommon *vs =3D VIRTIO_SCSI_COMMON(dev); VHostUserSCSI *s =3D VHOST_USER_SCSI(dev); VHostSCSICommon *vsc =3D VHOST_SCSI_COMMON(s); - VhostUserState *user; Error *err =3D NULL; int ret; =20 @@ -86,30 +85,24 @@ static void vhost_user_scsi_realize(DeviceState *dev, E= rror **errp) return; } =20 - user =3D 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 =3D &vs->conf.chardev; =20 vsc->dev.nvqs =3D 2 + vs->conf.num_queues; vsc->dev.vqs =3D g_new(struct vhost_virtqueue, vsc->dev.nvqs); vsc->dev.vq_index =3D 0; vsc->dev.backend_features =3D 0; =20 - ret =3D vhost_dev_init(&vsc->dev, user, + ret =3D 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; } =20 - s->vhost_user =3D user; - /* Channel and lun both are 0 for bootable vhost-user-scsi disk */ vsc->channel =3D 0; vsc->lun =3D 0; @@ -129,12 +122,7 @@ static void vhost_user_scsi_unrealize(DeviceState *dev= , Error **errp) g_free(vsc->dev.vqs); =20 virtio_scsi_common_unrealize(dev, errp); - - if (s->vhost_user) { - vhost_user_cleanup(s->vhost_user); - g_free(s->vhost_user); - s->vhost_user =3D NULL; - } + vhost_user_cleanup(&s->vhost_user); } =20 static Property vhost_user_scsi_properties[] =3D { 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; } =20 -VhostUserState *vhost_user_init(void) +bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp) { - return NULL; + return false; } =20 void vhost_user_cleanup(VhostUserState *user) diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index e09bed0e4a..90a9492bcf 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 vh= ost_dev *dev, return result; } =20 -VhostUserState *vhost_user_init(void) +bool vhost_user_init(VhostUserState *user, CharBackend *chr, Error **errp) { - VhostUserState *user =3D g_new0(struct VhostUserState, 1); - - return user; + if (user->chr) { + error_setg(errp, "Cannot initialize vhost-user state"); + return false; + } + user->chr =3D chr; + return true; } =20 void vhost_user_cleanup(VhostUserState *user) { int i; =20 + if (!user->chr) { + return; + } + for (i =3D 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 =3D NULL; } } + user->chr =3D NULL; } =20 const VhostOps user_ops =3D { 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 =3D NULL; NetClientState *nc, *nc0 =3D NULL; - VhostUserState *user =3D NULL; NetVhostUserState *s =3D NULL; + VhostUserState *user; int i; =20 assert(name); assert(queues > 0); =20 - user =3D vhost_user_init(); - if (!user) { - error_report("failed to init vhost_user"); - goto err; - } - + user =3D g_new0(struct VhostUserState, 1); for (i =3D 0; i < queues; i++) { nc =3D qemu_new_net_client(&net_vhost_user_info, peer, device, nam= e); 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 =3D nc; s =3D 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 =3D &s->chr; } s =3D DO_UPCAST(NetVhostUserState, nc, nc); s->vhost_user =3D user; --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154323636078821.11719350586816; Mon, 26 Nov 2018 04:46:00 -0800 (PST) Received: from localhost ([::1]:35522 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGH1-0000GU-D8 for importer@patchew.org; Mon, 26 Nov 2018 07:45:59 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49483) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGF8-0007Y5-UT for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:03 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGF4-0007JL-Vp for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:02 -0500 Received: from mx1.redhat.com ([209.132.183.28]:35904) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGF4-0007IW-R6 for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:43:58 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2DC27308FE92 for ; Mon, 26 Nov 2018 12:43:58 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 242DE608C3; Mon, 26 Nov 2018 12:43:49 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:42 +0400 Message-Id: <20181126124250.29985-4-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.49]); Mon, 26 Nov 2018 12:43:58 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 03/11] libvhost-user: exit by default on VHOST_USER_NONE X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Jens Freimann , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Since commit 2566378d6d13bf4d28c7770bdbda5f7682594bbe, libvhost-user no longer panics on disconnect (rc =3D=3D 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=C3=A9 Lureau Reviewed-by: Jens Freimann --- 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 a6b46cdc03..41470daf57 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: --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 154323655113629.75253534869853; Mon, 26 Nov 2018 04:49:11 -0800 (PST) Received: from localhost ([::1]:35538 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGK6-0003oS-1N for importer@patchew.org; Mon, 26 Nov 2018 07:49:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49610) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGFN-0007ir-1O for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:18 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGFJ-0007b1-2A for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:16 -0500 Received: from mx1.redhat.com ([209.132.183.28]:56614) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGFI-0007aO-S7 for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:13 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1FA4F2D809; Mon, 26 Nov 2018 12:44:12 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 43E4B1055007; Mon, 26 Nov 2018 12:44:01 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:43 +0400 Message-Id: <20181126124250.29985-5-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 26 Nov 2018 12:44:12 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 04/11] vhost-user: wrap some read/write with retry handling X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , "Michael S. Tsirkin" , kraxel@redhat.com, =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Philippe Mathieu-Daud=C3=A9 --- 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 90a9492bcf..0131bbb0fc 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 =3D &hdr; iov.iov_len =3D VHOST_USER_HDR_SIZE; =20 - size =3D recvmsg(u->slave_fd, &msgh, 0); + do { + size =3D recvmsg(u->slave_fd, &msgh, 0); + } while (size < 0 && (errno =3D=3D EINTR || errno =3D=3D EAGAIN)); + if (size !=3D VHOST_USER_HDR_SIZE) { error_report("Failed to read from slave."); goto err; @@ -993,7 +996,10 @@ static void slave_read(void *opaque) } =20 /* Read payload */ - size =3D read(u->slave_fd, &payload, hdr.size); + do { + size =3D read(u->slave_fd, &payload, hdr.size); + } while (size < 0 && (errno =3D=3D EINTR || errno =3D=3D EAGAIN)); + if (size !=3D 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 =3D &payload; iovec[1].iov_len =3D hdr.size; =20 - size =3D writev(u->slave_fd, iovec, ARRAY_SIZE(iovec)); + do { + size =3D writev(u->slave_fd, iovec, ARRAY_SIZE(iovec)); + } while (size < 0 && (errno =3D=3D EINTR || errno =3D=3D EAGAIN)); + if (size !=3D VHOST_USER_HDR_SIZE + hdr.size) { error_report("Failed to send msg reply to slave."); goto err; --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236429226616.2392230795654; Mon, 26 Nov 2018 04:47:09 -0800 (PST) Received: from localhost ([::1]:35528 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGI7-0001Dx-Rz for importer@patchew.org; Mon, 26 Nov 2018 07:47:07 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49650) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGFQ-0007l6-FP for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGFP-0007fB-3I for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:20 -0500 Received: from mx1.redhat.com ([209.132.183.28]:34338) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGFO-0007ep-RX for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:19 -0500 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2634730014A7 for ; Mon, 26 Nov 2018 12:44:18 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 63804100190B; Mon, 26 Nov 2018 12:44:16 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:44 +0400 Message-Id: <20181126124250.29985-6-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.45]); Mon, 26 Nov 2018 12:44:18 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 05/11] Add vhost-user-backend X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , Paolo Bonzini , kraxel@redhat.com, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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. A chardev must be specified to communicate with the vhost-user backend, ex: -chardev socket,id=3Dchar0,path=3D/tmp/foo.sock -object vhost-user-backend,id=3Dvuid,chardev=3Dchar0. Signed-off-by: Marc-Andr=C3=A9 Lureau --- include/sysemu/vhost-user-backend.h | 60 +++++++ backends/vhost-user.c | 244 ++++++++++++++++++++++++++++ vl.c | 3 +- MAINTAINERS | 2 + backends/Makefile.objs | 3 +- qemu-options.hx | 20 +++ 6 files changed, 330 insertions(+), 2 deletions(-) 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-use= r-backend.h new file mode 100644 index 0000000000..60f811cae7 --- /dev/null +++ b/include/sysemu/vhost-user-backend.h @@ -0,0 +1,60 @@ +/* + * QEMU vhost-user backend + * + * Copyright (C) 2018 Red Hat Inc + * + * Authors: + * Marc-Andr=C3=A9 Lureau + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * 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_BAC= KEND) + +typedef struct VhostUserBackend VhostUserBackend; +typedef struct VhostUserBackendClass VhostUserBackendClass; + +struct VhostUserBackendClass { + ObjectClass parent_class; +}; + +struct VhostUserBackend { + /* private */ + Object parent; + + char *cmd; + 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..bf39c0751d --- /dev/null +++ b/backends/vhost-user.c @@ -0,0 +1,244 @@ +/* + * QEMU vhost-user backend + * + * Copyright (C) 2018 Red Hat Inc + * + * Authors: + * Marc-Andr=C3=A9 Lureau + * + * This work is licensed under the terms of the GNU GPL, version 2 or late= r. + * 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 =3D vdev; + b->dev.nvqs =3D nvqs; + b->dev.vqs =3D g_new(struct vhost_virtqueue, nvqs); + + ret =3D vhost_dev_init(&b->dev, &b->vhost_user, VHOST_BACKEND_TYPE_USE= R, 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 =3D BUS(qdev_get_parent_bus(DEVICE(b->vdev))); + VirtioBusClass *k =3D 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 =3D vhost_dev_enable_notifiers(&b->dev, b->vdev); + if (ret < 0) { + return; + } + + ret =3D 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 =3D b->vdev->guest_features; + ret =3D 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 =3D 0; i < b->dev.nvqs; i++) { + vhost_virtqueue_mask(&b->dev, b->vdev, + b->dev.vq_index + i, false); + } + + b->started =3D 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 =3D BUS(qdev_get_parent_bus(DEVICE(b->vdev))); + VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(qbus); + int ret =3D 0; + + if (!b->started) { + return; + } + + vhost_dev_stop(&b->dev, b->vdev); + + if (k->set_guest_notifiers) { + ret =3D k->set_guest_notifiers(qbus->parent, + b->dev.nvqs, false); + if (ret < 0) { + error_report("vhost guest notifier cleanup failed: %d", ret); + } + } + assert(ret >=3D 0); + + vhost_dev_disable_notifiers(&b->dev, b->vdev); + b->started =3D false; +} + +static void +vhost_user_backend_complete(UserCreatable *uc, Error **errp) +{ + VhostUserBackend *b =3D VHOST_USER_BACKEND(uc); + Chardev *chr; + + if (!b->chr_name) { + error_setg(errp, "You must specificy 'chardev'."); + return; + } + + chr =3D qemu_chr_find(b->chr_name); + if (chr =3D=3D 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 =3D true; + /* could vhost_dev_init() happen here, so early vhost-user message + * can be exchanged */ +} + +static void set_chardev(Object *obj, const char *value, Error **errp) +{ + VhostUserBackend *b =3D VHOST_USER_BACKEND(obj); + + if (b->completed) { + error_setg(errp, QERR_PERMISSION_DENIED); + } else { + g_free(b->chr_name); + b->chr_name =3D g_strdup(value); + } +} + +static char *get_chardev(Object *obj, Error **errp) +{ + VhostUserBackend *b =3D VHOST_USER_BACKEND(obj); + Chardev *chr =3D 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 =3D 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 bool +vhost_user_backend_can_be_deleted(UserCreatable *uc) +{ + return true; +} + +static void +vhost_user_backend_class_init(ObjectClass *oc, void *data) +{ + UserCreatableClass *ucc =3D USER_CREATABLE_CLASS(oc); + + ucc->complete =3D vhost_user_backend_complete; + ucc->can_be_deleted =3D vhost_user_backend_can_be_deleted; +} + +static const TypeInfo vhost_user_backend_info =3D { + .name =3D TYPE_VHOST_USER_BACKEND, + .parent =3D TYPE_OBJECT, + .instance_size =3D sizeof(VhostUserBackend), + .instance_init =3D vhost_user_backend_init, + .instance_finalize =3D vhost_user_backend_finalize, + .class_size =3D sizeof(VhostUserBackendClass), + .class_init =3D vhost_user_backend_class_init, + .interfaces =3D (InterfaceInfo[]) { + { TYPE_USER_CREATABLE }, + { } + } +}; + +static void register_types(void) +{ + type_register_static(&vhost_user_backend_info); +} + +type_init(register_types); diff --git a/vl.c b/vl.c index fa25d1ae2d..903ea9a445 100644 --- a/vl.c +++ b/vl.c @@ -2798,7 +2798,8 @@ static bool object_create_initial(const char *type, Q= emuOpts *opts) } =20 #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) - if (g_str_equal(type, "cryptodev-vhost-user")) { + if (g_str_equal(type, "cryptodev-vhost-user") || + g_str_equal(type, "vhost-user-backend")) { return false; } #endif diff --git a/MAINTAINERS b/MAINTAINERS index 81e4368a43..1507f941dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1337,6 +1337,8 @@ S: Supported F: hw/*/*vhost* F: docs/interop/vhost-user.json F: docs/interop/vhost-user.txt +F: backends/vhost-user.c +F: include/sysemu/vhost-user-backend.h =20 virtio M: Michael S. Tsirkin 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 +=3D cryptodev-builtin.o ifeq ($(CONFIG_VIRTIO),y) common-obj-y +=3D cryptodev-vhost.o common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) +=3D \ - cryptodev-vhost-user.o + cryptodev-vhost-user.o \ + vhost-user.o endif =20 common-obj-$(CONFIG_LINUX) +=3D hostmem-memfd.o diff --git a/qemu-options.hx b/qemu-options.hx index f7df472f43..2346521703 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4241,6 +4241,26 @@ secondary: If you want to know the detail of above command line, you can read the colo-compare git log. =20 +@item -object vhost-user-backend,id=3Did=3D@var{id},chardev=3D@var{chardev= id} + +Create a vhost-user-backend object that holds a connection to a +vhost-user backend and can be referenced from virtio/vhost-user +devices that support it. + +The @var{id} parameter is a unique ID that will be used to reference +this vhost-user backend from the @option{vhost-user} device. The +@var{chardev} parameter is the unique ID of a character device backend +that provides the connection to the vhost-user slave process. (Since 3.2) + +@example + + # qemu-system-x86_64 \ + [...] \ + -object vhost-user-backend,id=3Dvuid,chardev=3Dchar0 \ + -device vhost-user-input-pci,vhost-user=3Dvuid + [...] +@end example + @item -object cryptodev-backend-builtin,id=3D@var{id}[,queues=3D@var{queue= s}] =20 Creates a cryptodev backend which executes crypto opreation from --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236688651948.6488715144452; Mon, 26 Nov 2018 04:51:28 -0800 (PST) Received: from localhost ([::1]:35552 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGMH-0005Xw-J5 for importer@patchew.org; Mon, 26 Nov 2018 07:51:25 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49778) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGFk-00084c-0k for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:40 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGFe-0007zj-8X for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:26277) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGFe-0007zB-0H for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:34 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 61C6E356DA for ; Mon, 26 Nov 2018 12:44:33 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 874A452FC0; Mon, 26 Nov 2018 12:44:22 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:45 +0400 Message-Id: <20181126124250.29985-7-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Mon, 26 Nov 2018 12:44:33 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 06/11] vhost-user: split vhost_user_read() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Split vhost_user_read(), so only header can be read with vhost_user_read_header(). Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Daniel P. Berrang=C3=A9 --- 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 0131bbb0fc..9256364e30 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(); } =20 -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 =3D dev->opaque; CharBackend *chr =3D u->user->chr; @@ -221,7 +221,7 @@ static int vhost_user_read(struct vhost_dev *dev, Vhost= UserMsg *msg) if (r !=3D 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; } =20 /* validate received flags */ @@ -229,7 +229,21 @@ static int vhost_user_read(struct vhost_dev *dev, Vhos= tUserMsg *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 =3D dev->opaque; + CharBackend *chr =3D u->user->chr; + uint8_t *p =3D (uint8_t *) msg; + int r, size; + + if (vhost_user_read_header(dev, msg) < 0) { + return -1; } =20 /* validate message size is sane */ @@ -237,7 +251,7 @@ static int vhost_user_read(struct vhost_dev *dev, Vhost= UserMsg *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; } =20 if (msg->hdr.size) { @@ -247,14 +261,11 @@ static int vhost_user_read(struct vhost_dev *dev, Vho= stUserMsg *msg) if (r !=3D size) { error_report("Failed to read msg payload." " Read %d instead of %d.", r, msg->hdr.size); - goto fail; + return -1; } } =20 return 0; - -fail: - return -1; } =20 static int process_message_reply(struct vhost_dev *dev, --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 154323683144733.70730094976352; Mon, 26 Nov 2018 04:53:51 -0800 (PST) Received: from localhost ([::1]:35563 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGOU-00075T-6L for importer@patchew.org; Mon, 26 Nov 2018 07:53:42 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49826) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGFs-0008CO-4s for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGFo-0008IE-5l for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:48 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60000) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGFn-0008HT-Rg for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:44 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3AB623099FC7 for ; Mon, 26 Nov 2018 12:44:43 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 626685C888; Mon, 26 Nov 2018 12:44:37 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:46 +0400 Message-Id: <20181126124250.29985-8-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.41]); Mon, 26 Nov 2018 12:44:43 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 07/11] vhost-user: add vhost_user_input_get_config() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Ask vhost user input backend the list of virtio_input_config. Signed-off-by: Marc-Andr=C3=A9 Lureau Reviewed-by: Gerd Hoffmann --- 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 4aa55b4d2d..a4afbc3a46 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 =3D 28, VHOST_USER_POSTCOPY_LISTEN =3D 29, VHOST_USER_POSTCOPY_END =3D 30, + VHOST_USER_INPUT_GET_CONFIG =3D 31, VHOST_USER_MAX } VhostUserRequest; =20 diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-ba= ckend.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 =20 #include "exec/memory.h" +#include "standard-headers/linux/virtio_input.h" =20 typedef enum VhostBackendType { VHOST_BACKEND_TYPE_NONE =3D 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); =20 +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 9256364e30..d51d1087f6 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -89,6 +89,7 @@ typedef enum VhostUserRequest { VHOST_USER_POSTCOPY_ADVISE =3D 28, VHOST_USER_POSTCOPY_LISTEN =3D 29, VHOST_USER_POSTCOPY_END =3D 30, + VHOST_USER_INPUT_GET_CONFIG =3D 31, VHOST_USER_MAX } VhostUserRequest; =20 @@ -338,6 +339,65 @@ static int vhost_user_write(struct vhost_dev *dev, Vho= stUserMsg *msg, return 0; } =20 +static void *vhost_user_read_size(struct vhost_dev *dev, uint32_t size) +{ + struct vhost_user *u =3D dev->opaque; + CharBackend *chr =3D u->user->chr; + int r; + uint8_t *p =3D g_malloc(size); + + r =3D qemu_chr_fe_read_all(chr, p, size); + if (r !=3D 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 =3D NULL; + VhostUserMsg msg =3D { + .hdr.request =3D VHOST_USER_INPUT_GET_CONFIG, + .hdr.flags =3D 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 !=3D 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 =3D vhost_user_read_size(dev, msg.hdr.size); + if (!p) { + goto err; + } + + *config =3D 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 cefec9ffe1..95720be81b 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. =20 + * 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 ------------------- =20 --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 154323654837699.81488908464576; Mon, 26 Nov 2018 04:49:08 -0800 (PST) Received: from localhost ([::1]:35537 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGJw-0003h8-2T for importer@patchew.org; Mon, 26 Nov 2018 07:49:00 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49930) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGG1-0008K1-Vs for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGFz-0008R8-2R for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:57 -0500 Received: from mx1.redhat.com ([209.132.183.28]:55868) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGFy-0008QM-TX for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:44:55 -0500 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 300754E8B7 for ; Mon, 26 Nov 2018 12:44:54 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 51A9051F05; Mon, 26 Nov 2018 12:44:46 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:47 +0400 Message-Id: <20181126124250.29985-9-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Mon, 26 Nov 2018 12:44:54 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 08/11] libvhost-user-glib: export vug_source_new() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Simplify the creation of FD sources for other users. This is just convenience to avoid duplicating similar code elsewhere. Signed-off-by: Marc-Andr=C3=A9 Lureau --- 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); =20 +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 =3D { NULL }; =20 -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 =3D &gdev->parent; GSource *gsrc; VugSrc *src; guint id; =20 - g_assert(dev); + g_assert(gdev); g_assert(fd >=3D 0); g_assert(vu_cb); =20 @@ -106,7 +107,7 @@ set_watch(VuDev *vu_dev, int fd, int vu_evt, vu_watch_c= b cb, void *pvt) g_assert(cb); =20 dev =3D container_of(vu_dev, VugDev, parent); - src =3D vug_source_new(vu_dev, fd, vu_evt, cb, pvt); + src =3D vug_source_new(dev, fd, vu_evt, cb, pvt); g_hash_table_replace(dev->fdmap, GINT_TO_POINTER(fd), src); } =20 @@ -141,7 +142,7 @@ vug_init(VugDev *dev, int socket, dev->fdmap =3D g_hash_table_new_full(NULL, NULL, NULL, (GDestroyNotify) g_source_destroy); =20 - dev->src =3D vug_source_new(&dev->parent, socket, G_IO_IN, vug_watch, = NULL); + dev->src =3D vug_source_new(dev, socket, G_IO_IN, vug_watch, NULL); } =20 void --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236724221639.2882820939587; Mon, 26 Nov 2018 04:52:04 -0800 (PST) Received: from localhost ([::1]:35554 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGMt-00061W-4H for importer@patchew.org; Mon, 26 Nov 2018 07:52:03 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50045) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGGF-0008VJ-KB for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGGB-00009X-PY for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:11 -0500 Received: from mx1.redhat.com ([209.132.183.28]:44030) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGGB-00008m-Jh for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:07 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C575D30832D0 for ; Mon, 26 Nov 2018 12:45:06 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id EB30D2D1ED; Mon, 26 Nov 2018 12:44:58 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:48 +0400 Message-Id: <20181126124250.29985-10-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.44]); Mon, 26 Nov 2018 12:45:06 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 09/11] libvhost-user: add vu_queue_unpop() X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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=C3=A9 Lureau --- 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 a4afbc3a46..6c7cbe14b6 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); =20 + +/** + * 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 41470daf57..e011a6ed1c 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; } =20 +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) { --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543236929958233.08349561805437; Mon, 26 Nov 2018 04:55:29 -0800 (PST) Received: from localhost ([::1]:35575 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGQ7-0008QB-QA for importer@patchew.org; Mon, 26 Nov 2018 07:55:23 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50286) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGGl-0000ai-8t for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:44 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGGh-0000mA-7x for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:38318) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGGg-0000lL-WD for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:45:39 -0500 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3980DC04A5B1 for ; Mon, 26 Nov 2018 12:45:38 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id C022E608F3; Mon, 26 Nov 2018 12:45:10 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:49 +0400 Message-Id: <20181126124250.29985-11-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Mon, 26 Nov 2018 12:45:38 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 10/11] Add vhost-user-input-pci X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com, "Michael S. Tsirkin" Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add a new virtio-input device, which connects to a vhost-user backend. Usage: -object vhost-user-backend,id=3Dvuid,chardev=3D... \ -device vhost-user-input-pci,vhost-user=3Dvuid 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=C3=A9 Lureau Reviewed-by: Gerd Hoffmann --- hw/virtio/virtio-pci.h | 10 +++ include/hw/virtio/virtio-input.h | 14 ++++ hw/input/vhost-user-input.c | 110 +++++++++++++++++++++++++++++++ hw/virtio/virtio-pci.c | 22 +++++++ MAINTAINERS | 1 + hw/input/Makefile.objs | 1 + 6 files changed, 158 insertions(+) create mode 100644 hw/input/vhost-user-input.c diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h index 813082b0d7..c7e28e1b9c 100644 --- a/hw/virtio/virtio-pci.h +++ b/hw/virtio/virtio-pci.h @@ -54,6 +54,7 @@ typedef struct VirtIORngPCI VirtIORngPCI; typedef struct VirtIOInputPCI VirtIOInputPCI; typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI; typedef struct VirtIOInputHostPCI VirtIOInputHostPCI; +typedef struct VHostUserInputPCI VHostUserInputPCI; typedef struct VirtIOGPUPCI VirtIOGPUPCI; typedef struct VHostVSockPCI VHostVSockPCI; typedef struct VirtIOCryptoPCI VirtIOCryptoPCI; @@ -376,6 +377,15 @@ struct VirtIOInputHostPCI { =20 #endif =20 +#define TYPE_VHOST_USER_INPUT_PCI "vhost-user-input-pci" +#define VHOST_USER_INPUT_PCI(obj) \ + OBJECT_CHECK(VHostUserInputPCI, (obj), TYPE_VHOST_USER_INPUT_PCI) + +struct VHostUserInputPCI { + VirtIOPCIProxy parent_obj; + VHostUserInput vhi; +}; + /* * virtio-gpu-pci: This extends VirtioPCIProxy. */ diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-in= put.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 =20 #include "ui/input.h" +#include "sysemu/vhost-user-backend.h" =20 /* ----------------------------------------------------------------- */ /* 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) =20 +#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; =20 struct VirtIOInputConfig { virtio_input_config config; @@ -98,6 +106,12 @@ struct VirtIOInputHost { int fd; }; =20 +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..ef1b23a8b2 --- /dev/null +++ b/hw/input/vhost-user-input.c @@ -0,0 +1,110 @@ +/* + * 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 =3D VHOST_USER_INPUT(dev); + VirtIOInput *vinput =3D VIRTIO_INPUT(dev); + VirtIODevice *vdev =3D VIRTIO_DEVICE(dev); + virtio_input_config *config; + int i, ret; + + if (!vhi->vhost) { + error_setg(errp, "'vhost-user' property is required"); + return; + } + + if (vhost_user_backend_dev_init(vhi->vhost, vdev, 2, errp) =3D=3D -1) { + return; + } + + ret =3D vhost_user_input_get_config(&vhi->vhost->dev, &config); + if (ret < 0) { + error_setg(errp, "failed to get input config"); + return; + } + for (i =3D 0; i < ret; i++) { + virtio_input_add_config(vinput, &config[i]); + } + g_free(config); +} + +static void vhost_input_change_active(VirtIOInput *vinput) +{ + VHostUserInput *vhi =3D 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 =3D { + .name =3D "vhost-user-input", + .unmigratable =3D 1, +}; + +static void vhost_input_class_init(ObjectClass *klass, void *data) +{ + VirtIOInputClass *vic =3D VIRTIO_INPUT_CLASS(klass); + DeviceClass *dc =3D DEVICE_CLASS(klass); + + dc->vmsd =3D &vmstate_vhost_input; + vic->realize =3D vhost_input_realize; + vic->change_active =3D vhost_input_change_active; +} + +static void vhost_input_is_busy(const Object *obj, const char *name, + Object *val, Error **errp) +{ + VHostUserInput *vhi =3D VHOST_USER_INPUT(obj); + + if (vhi->vhost) { + error_setg(errp, "can't use already busy vhost-user"); + } else { + qdev_prop_allow_set_link_before_realize(obj, name, val, errp); + } +} + +static void vhost_input_init(Object *obj) +{ + VHostUserInput *vhi =3D VHOST_USER_INPUT(obj); + VirtIOInput *vinput =3D VIRTIO_INPUT(obj); + struct virtio_input_config vhost_input_config[] =3D { { /* empty list = */ } }; + + virtio_input_init_config(vinput, vhost_input_config); + + object_property_add_link(obj, "vhost-user", TYPE_VHOST_USER_BACKEND, + (Object **)&vhi->vhost, + vhost_input_is_busy, + OBJ_PROP_LINK_STRONG, + &error_abort); +} + +static const TypeInfo vhost_input_info =3D { + .name =3D TYPE_VHOST_USER_INPUT, + .parent =3D TYPE_VIRTIO_INPUT, + .instance_size =3D sizeof(VHostUserInput), + .instance_init =3D vhost_input_init, + .class_init =3D 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/virtio-pci.c b/hw/virtio/virtio-pci.c index a954799267..ec912db48d 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -2645,6 +2645,27 @@ static const TypeInfo virtio_host_pci_info =3D { }; #endif =20 +#ifdef CONFIG_VHOST_USER +static void vhost_user_input_pci_initfn(Object *obj) +{ + VHostUserInputPCI *dev =3D VHOST_USER_INPUT_PCI(obj); + + virtio_instance_init_common(obj, &dev->vhi, sizeof(dev->vhi), + TYPE_VHOST_USER_INPUT); + + object_property_add_alias(obj, "vhost-user", + OBJECT(&dev->vhi), "vhost-user", + &error_abort); +} + +static const TypeInfo vhost_user_input_pci_info =3D { + .name =3D TYPE_VHOST_USER_INPUT_PCI, + .parent =3D TYPE_VIRTIO_INPUT_PCI, + .instance_size =3D sizeof(VHostUserInputPCI), + .instance_init =3D vhost_user_input_pci_initfn, +}; +#endif + /* virtio-pci-bus */ =20 static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, @@ -2719,6 +2740,7 @@ static void virtio_pci_register_types(void) #endif #if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) type_register_static(&vhost_user_scsi_pci_info); + type_register_static(&vhost_user_input_pci_info); #endif #ifdef CONFIG_VHOST_VSOCK type_register_static(&vhost_vsock_pci_info); diff --git a/MAINTAINERS b/MAINTAINERS index 1507f941dc..4fcdd399db 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1380,6 +1380,7 @@ L: qemu-s390x@nongnu.org virtio-input M: Gerd Hoffmann S: Maintained +F: hw/input/vhost-user-input.c F: hw/input/virtio-input*.c F: include/hw/virtio/virtio-input.h =20 diff --git a/hw/input/Makefile.objs b/hw/input/Makefile.objs index c8b00f71ec..6adc308cdd 100644 --- a/hw/input/Makefile.objs +++ b/hw/input/Makefile.objs @@ -11,6 +11,7 @@ common-obj-$(CONFIG_VIRTIO_INPUT) +=3D virtio-input.o common-obj-$(CONFIG_VIRTIO_INPUT) +=3D virtio-input-hid.o ifeq ($(CONFIG_LINUX),y) common-obj-$(CONFIG_VIRTIO_INPUT) +=3D virtio-input-host.o +common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_VIRTIO_INPUT)) +=3D v= host-user-input.o endif =20 obj-$(CONFIG_MILKYMIST) +=3D milkymist-softusb.o --=20 2.20.0.rc1 From nobody Sat May 4 23:24:42 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1543237051504276.21604235527843; Mon, 26 Nov 2018 04:57:31 -0800 (PST) Received: from localhost ([::1]:35587 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGSA-0001dG-53 for importer@patchew.org; Mon, 26 Nov 2018 07:57:30 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50420) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gRGHA-0000vu-Ve for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:46:12 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gRGH9-0001yR-2N for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:46:08 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60069) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1gRGH7-0001wm-H9 for qemu-devel@nongnu.org; Mon, 26 Nov 2018 07:46:06 -0500 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D31FE80F90 for ; Mon, 26 Nov 2018 12:46:04 +0000 (UTC) Received: from localhost (ovpn-112-28.ams2.redhat.com [10.36.112.28]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3553E2D1ED; Mon, 26 Nov 2018 12:45:41 +0000 (UTC) From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= To: qemu-devel@nongnu.org Date: Mon, 26 Nov 2018 16:42:50 +0400 Message-Id: <20181126124250.29985-12-marcandre.lureau@redhat.com> In-Reply-To: <20181126124250.29985-1-marcandre.lureau@redhat.com> References: <20181126124250.29985-1-marcandre.lureau@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Mon, 26 Nov 2018 12:46:04 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH for-3.2 11/11] contrib: add vhost-user-input X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= , kraxel@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" 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-backend object, for example via a unix socket: $ vhost-user-input -p /dev/input/eventX -s /tmp/vui.sock $ qemu ... -chardev socket,id=3Dvuic,path=3D/tmp/vui.sock -object vhost-user-backend,chardev=3Dvuic Signed-off-by: Marc-Andr=C3=A9 Lureau --- 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/mai= n.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 +#include + +#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 =3D &vi->dev.parent; + VuVirtq *vq =3D vu_get_queue(dev, 0); + VuVirtqElement *elem; + int i, len; + + /* queue up events ... */ + if (vi->qindex =3D=3D vi->qsize) { + vi->qsize++; + vi->queue =3D g_realloc_n(vi->queue, vi->qsize, sizeof(vi->queue[0= ])); + } + vi->queue[vi->qindex++].event =3D *event; + + /* ... until we see a report sync ... */ + if (event->type !=3D htole16(EV_SYN) || + event->code !=3D htole16(SYN_REPORT)) { + return; + } + + /* ... then check available space ... */ + for (i =3D 0; i < vi->qindex; i++) { + elem =3D vu_queue_pop(dev, vq, sizeof(VuVirtqElement)); + if (!elem) { + while (--i >=3D 0) { + vu_queue_unpop(dev, vq, vi->queue[i].elem, 0); + } + vi->qindex =3D 0; + g_warning("virtio-input queue full"); + return; + } + vi->queue[i].elem =3D elem; + } + + /* ... and finally pass them to the guest */ + for (i =3D 0; i < vi->qindex; i++) { + elem =3D vi->queue[i].elem; + len =3D iov_from_buf(elem->in_sg, elem->in_num, + 0, &vi->queue[i].event, sizeof(virtio_input_eve= nt)); + vu_queue_push(dev, vq, elem, len); + g_free(elem); + } + + vu_queue_notify(&vi->dev.parent, vq); + vi->qindex =3D 0; +} + +static void +vi_evdev_watch(VuDev *dev, int condition, void *data) +{ + VuInput *vi =3D data; + int fd =3D vi->evdevfd; + + g_debug("Got evdev condition %x", condition); + + struct virtio_input_event virtio; + struct input_event evdev; + int rc; + + for (;;) { + rc =3D read(fd, &evdev, sizeof(evdev)); + if (rc !=3D sizeof(evdev)) { + break; + } + + g_debug("input %d %d %d", evdev.type, evdev.code, evdev.value); + + virtio.type =3D htole16(evdev.type); + virtio.code =3D htole16(evdev.code); + virtio.value =3D 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 =3D le16toh(event->type); + evdev.code =3D le16toh(event->code); + evdev.value =3D le32toh(event->value); + + rc =3D write(vi->evdevfd, &evdev, sizeof(evdev)); + if (rc =3D=3D -1) { + perror("vi_host_handle_status: write"); + } +} + +static void vi_handle_sts(VuDev *dev, int qidx) +{ + VuInput *vi =3D container_of(dev, VuInput, dev.parent); + VuVirtq *vq =3D vu_get_queue(dev, qidx); + virtio_input_event event; + VuVirtqElement *elem; + int len; + + g_debug("%s", G_STRFUNC); + + for (;;) { + elem =3D vu_queue_pop(dev, vq, sizeof(VuVirtqElement)); + if (!elem) { + break; + } + + memset(&event, 0, sizeof(event)); + len =3D 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 =3D container_of(dev, VuInput, dev.parent); + VuVirtq *vq =3D vu_get_queue(dev, qidx); + + g_debug("queue started %d:%d", qidx, started); + + if (qidx =3D=3D 1) { + vu_set_queue_handler(dev, vq, started ? vi_handle_sts : NULL); + } + + started =3D vu_queue_started(dev, vu_get_queue(dev, 0)) && + vu_queue_started(dev, vu_get_queue(dev, 1)); + + if (started && !vi->evsrc) { + vi->evsrc =3D 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 =3D NULL; + } +} + +static int +vi_process_msg(VuDev *dev, VhostUserMsg *vmsg, int *do_reply) +{ + VuInput *vi =3D container_of(dev, VuInput, dev.parent); + + switch (vmsg->request) { + case VHOST_USER_INPUT_GET_CONFIG: + vmsg->size =3D vi->config->len * sizeof(virtio_input_config); + vmsg->data =3D g_memdup(vi->config->data, vmsg->size); + *do_reply =3D true; + return 1; + default: + return 0; + } +} + +static const VuDevIface vuiface =3D { + .queue_set_started =3D vi_queue_set_started, + .process_msg =3D vi_process_msg, +}; + +static void +vi_bits_config(VuInput *vi, int type, int count) +{ + virtio_input_config bits; + int rc, i, size =3D 0; + + memset(&bits, 0, sizeof(bits)); + rc =3D ioctl(vi->evdevfd, EVIOCGBIT(type, count / 8), bits.u.bitmap); + if (rc < 0) { + return; + } + + for (i =3D 0; i < count / 8; i++) { + if (bits.u.bitmap[i]) { + size =3D i + 1; + } + } + if (size =3D=3D 0) { + return; + } + + bits.select =3D VIRTIO_INPUT_CFG_EV_BITS; + bits.subsel =3D type; + bits.size =3D 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 =3D socket(AF_UNIX, SOCK_STREAM, 0); + if (sock <=3D 0) { + perror("socket"); + return -1; + } + + un.sun_family =3D AF_UNIX; + snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); + len =3D 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 =3D -1; +static char *opt_socket_path; +static gboolean opt_nograb; +static gboolean opt_print_caps; + +static GOptionEntry entries[] =3D { + { "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 =3D NULL; + VuInput vi =3D { 0, }; + int rc, ver, fd; + virtio_input_config id; + struct input_id ids; + GError *error =3D NULL; + GOptionContext *context; + + context =3D 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 !=3D -1)) !=3D 1) { + g_printerr("Please specify either --fd or --socket-path\n"); + exit(EXIT_FAILURE); + } + + vi.evdevfd =3D open(opt_evdev, O_RDWR); + if (vi.evdevfd < 0) { + g_printerr("Failed to open evdev: %s\n", g_strerror(errno)); + exit(EXIT_FAILURE); + } + + rc =3D 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 =3D ioctl(vi.evdevfd, EVIOCGRAB, 1); + if (rc < 0) { + g_printerr("Failed to grab device\n"); + exit(EXIT_FAILURE); + } + } + + vi.config =3D 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 =3D VIRTIO_INPUT_CFG_ID_NAME; + id.size =3D strlen(id.u.string); + g_array_append_val(vi.config, id); + + if (ioctl(vi.evdevfd, EVIOCGID, &ids) =3D=3D 0) { + memset(&id, 0, sizeof(id)); + id.select =3D VIRTIO_INPUT_CFG_ID_DEVIDS; + id.size =3D sizeof(struct virtio_input_devids); + id.u.ids.bustype =3D cpu_to_le16(ids.bustype); + id.u.ids.vendor =3D cpu_to_le16(ids.vendor); + id.u.ids.product =3D cpu_to_le16(ids.product); + id.u.ids.version =3D 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 =3D unix_sock_new(opt_socket_path); + fd =3D accept(lsock, NULL, NULL); + close(lsock); + } else { + fd =3D opt_fdnum; + } + if (fd =3D=3D -1) { + g_printerr("Invalid socket"); + exit(EXIT_FAILURE); + } + vug_init(&vi.dev, fd, vi_panic, &vuiface); + + loop =3D 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 4fcdd399db..0536428b0b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1383,6 +1383,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/* =20 virtio-serial M: Amit Shah diff --git a/Makefile b/Makefile index f2947186a4..f047b5ccaf 100644 --- a/Makefile +++ b/Makefile @@ -421,6 +421,7 @@ dummy :=3D $(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 \ @@ -725,6 +726,8 @@ vhost-user-scsi$(EXESUF): $(vhost-user-scsi-obj-y) libv= host-user.a $(call LINK, $^) vhost-user-blk$(EXESUF): $(vhost-user-blk-obj-y) libvhost-user.a $(call LINK, $^) +vhost-user-input$(EXESUF): $(vhost-user-input-obj-y) libvhost-user.a libqe= muutil.a + $(call LINK, $^) =20 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 1e1ff387d7..eca7c0a7c4 100644 --- a/Makefile.objs +++ b/Makefile.objs @@ -194,6 +194,7 @@ vhost-user-scsi.o-cflags :=3D $(LIBISCSI_CFLAGS) vhost-user-scsi.o-libs :=3D $(LIBISCSI_LIBS) vhost-user-scsi-obj-y =3D contrib/vhost-user-scsi/ vhost-user-blk-obj-y =3D contrib/vhost-user-blk/ +vhost-user-input-obj-y =3D contrib/vhost-user-input/ =20 ###################################################################### trace-events-subdirs =3D diff --git a/configure b/configure index 0a3c6a72c3..b64ca58fbe 100755 --- a/configure +++ b/configure @@ -5725,6 +5725,9 @@ if test "$want_tools" =3D "yes" ; then if [ "$posix" =3D "yes" ] && [ "$curl" =3D "yes" ]; then tools=3D"elf2dmp $tools" fi + if [ "$vhost_user" =3D "yes" ] && [ "$linux" =3D "yes" ] ; then + tools=3D"vhost-user-input\$(EXESUF) $tools" + fi fi if test "$softmmu" =3D yes ; then if test "$linux" =3D yes; then diff --git a/contrib/vhost-user-input/Makefile.objs b/contrib/vhost-user-in= put/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 =3D main.o --=20 2.20.0.rc1