From nobody Thu May 2 07:43:13 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516539486944626.9071470424593; Sun, 21 Jan 2018 04:58:06 -0800 (PST) Received: from localhost ([::1]:54922 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFCE-0006WT-9r for importer@patchew.org; Sun, 21 Jan 2018 07:58:02 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48677) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFAE-0005PZ-OD for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edFAA-0000pZ-O3 for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:55:58 -0500 Received: from [45.249.212.35] (port=34135 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edFA9-0000ml-Sc for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:55:54 -0500 Received: from DGGEMS411-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 2C7F9F3B155DE; Sun, 21 Jan 2018 20:55:47 +0800 (CST) Received: from localhost (10.177.19.14) by DGGEMS411-HUB.china.huawei.com (10.3.19.211) with Microsoft SMTP Server id 14.3.361.1; Sun, 21 Jan 2018 20:55:39 +0800 From: Jay Zhou To: Date: Sun, 21 Jan 2018 20:54:47 +0800 Message-ID: X-Mailer: git-send-email 2.6.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.177.19.14] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.35 Subject: [Qemu-devel] [PATCH v6 1/4] cryptodev: add vhost-user as a new cryptodev 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: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com, mst@redhat.com, wangxinxin.wang@huawei.com, xin.zeng@intel.com, arei.gonglei@huawei.com, roy.fan.zhang@intel.com, stefanha@redhat.com, jianjay.zhou@huawei.com, pbonzini@redhat.com, longpeng2@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gonglei Usage: -chardev socket,id=3Dcharcrypto0,path=3D/path/to/your/socket -object cryptodev-vhost-user,id=3Dcryptodev0,chardev=3Dcharcrypto0 -device virtio-crypto-pci,id=3Dcrypto0,cryptodev=3Dcryptodev0 Signed-off-by: Gonglei Signed-off-by: Longpeng(Mike) Signed-off-by: Jay Zhou --- backends/Makefile.objs | 6 + backends/cryptodev-vhost-user.c | 333 +++++++++++++++++++++++++++++++++++= ++++ backends/cryptodev-vhost.c | 89 +++++++++++ configure | 15 ++ include/sysemu/cryptodev-vhost.h | 154 ++++++++++++++++++ qemu-options.hx | 21 +++ vl.c | 6 + 7 files changed, 624 insertions(+) create mode 100644 backends/cryptodev-vhost-user.c create mode 100644 backends/cryptodev-vhost.c create mode 100644 include/sysemu/cryptodev-vhost.h diff --git a/backends/Makefile.objs b/backends/Makefile.objs index 0400799..a13020b 100644 --- a/backends/Makefile.objs +++ b/backends/Makefile.objs @@ -8,3 +8,9 @@ common-obj-$(CONFIG_LINUX) +=3D hostmem-file.o =20 common-obj-y +=3D cryptodev.o common-obj-y +=3D cryptodev-builtin.o + +ifeq ($(CONFIG_VIRTIO),y) +common-obj-$(CONFIG_LINUX) +=3D cryptodev-vhost.o +common-obj-$(call land,$(CONFIG_VHOST_USER),$(CONFIG_LINUX)) +=3D \ + cryptodev-vhost-user.o +endif diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.c new file mode 100644 index 0000000..4e63ece --- /dev/null +++ b/backends/cryptodev-vhost-user.c @@ -0,0 +1,333 @@ +/* + * QEMU Cryptodev backend for QEMU cipher APIs + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "hw/boards.h" +#include "qapi/error.h" +#include "qapi/qmp/qerror.h" +#include "qemu/error-report.h" +#include "standard-headers/linux/virtio_crypto.h" +#include "sysemu/cryptodev-vhost.h" +#include "chardev/char-fe.h" + + +/** + * @TYPE_CRYPTODEV_BACKEND_VHOST_USER: + * name of backend that uses vhost user server + */ +#define TYPE_CRYPTODEV_BACKEND_VHOST_USER "cryptodev-vhost-user" + +#define CRYPTODEV_BACKEND_VHOST_USER(obj) \ + OBJECT_CHECK(CryptoDevBackendVhostUser, \ + (obj), TYPE_CRYPTODEV_BACKEND_VHOST_USER) + + +typedef struct CryptoDevBackendVhostUser { + CryptoDevBackend parent_obj; + + CharBackend chr; + char *chr_name; + bool opened; + CryptoDevBackendVhost *vhost_crypto[MAX_CRYPTO_QUEUE_NUM]; +} CryptoDevBackendVhostUser; + +static int +cryptodev_vhost_user_running( + CryptoDevBackendVhost *crypto) +{ + return crypto ? 1 : 0; +} + +static void cryptodev_vhost_user_stop(int queues, + CryptoDevBackendVhostUser *s) +{ + size_t i; + + for (i =3D 0; i < queues; i++) { + if (!cryptodev_vhost_user_running(s->vhost_crypto[i])) { + continue; + } + + if (s->vhost_crypto) { + cryptodev_vhost_cleanup(s->vhost_crypto[i]); + s->vhost_crypto[i] =3D NULL; + } + } +} + +static int +cryptodev_vhost_user_start(int queues, + CryptoDevBackendVhostUser *s) +{ + CryptoDevBackendVhostOptions options; + CryptoDevBackend *b =3D CRYPTODEV_BACKEND(s); + int max_queues; + size_t i; + + for (i =3D 0; i < queues; i++) { + if (cryptodev_vhost_user_running(s->vhost_crypto[i])) { + continue; + } + + options.opaque =3D &s->chr; + 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); + if (!s->vhost_crypto[i]) { + error_report("failed to init vhost_crypto for queue %lu", i); + goto err; + } + + if (i =3D=3D 0) { + max_queues =3D + cryptodev_vhost_get_max_queues(s->vhost_crypto[i]); + if (queues > max_queues) { + error_report("you are asking more queues than supported: %= d", + max_queues); + goto err; + } + } + } + + return 0; + +err: + cryptodev_vhost_user_stop(i + 1, s); + return -1; +} + +static Chardev * +cryptodev_vhost_claim_chardev(CryptoDevBackendVhostUser *s, + Error **errp) +{ + Chardev *chr; + + if (s->chr_name =3D=3D NULL) { + error_setg(errp, QERR_INVALID_PARAMETER_VALUE, + "chardev", "a valid character device"); + return NULL; + } + + chr =3D qemu_chr_find(s->chr_name); + if (chr =3D=3D NULL) { + error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, + "Device '%s' not found", s->chr_name); + return NULL; + } + + return chr; +} + +static void cryptodev_vhost_user_event(void *opaque, int event) +{ + CryptoDevBackendVhostUser *s =3D opaque; + CryptoDevBackend *b =3D CRYPTODEV_BACKEND(s); + Error *err =3D NULL; + int queues =3D b->conf.peers.queues; + + assert(queues < MAX_CRYPTO_QUEUE_NUM); + + switch (event) { + case CHR_EVENT_OPENED: + if (cryptodev_vhost_user_start(queues, s) < 0) { + exit(1); + } + b->ready =3D true; + break; + case CHR_EVENT_CLOSED: + b->ready =3D false; + cryptodev_vhost_user_stop(queues, s); + break; + } + + if (err) { + error_report_err(err); + } +} + +static void cryptodev_vhost_user_init( + CryptoDevBackend *backend, Error **errp) +{ + int queues =3D backend->conf.peers.queues; + size_t i; + Error *local_err =3D NULL; + Chardev *chr; + CryptoDevBackendClient *cc; + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(backend); + + chr =3D cryptodev_vhost_claim_chardev(s, &local_err); + if (local_err) { + error_propagate(errp, local_err); + return; + } + + s->opened =3D true; + + for (i =3D 0; i < queues; i++) { + cc =3D cryptodev_backend_new_client( + "cryptodev-vhost-user", NULL); + cc->info_str =3D g_strdup_printf("cryptodev-vhost-user%lu to %s ", + i, chr->label); + cc->queue_index =3D i; + + backend->conf.peers.ccs[i] =3D cc; + + if (i =3D=3D 0) { + if (!qemu_chr_fe_init(&s->chr, chr, &local_err)) { + error_propagate(errp, local_err); + return; + } + } + } + + qemu_chr_fe_set_handlers(&s->chr, NULL, NULL, + cryptodev_vhost_user_event, NULL, s, NULL, true); + + backend->conf.crypto_services =3D + 1u << VIRTIO_CRYPTO_SERVICE_CIPHER | + 1u << VIRTIO_CRYPTO_SERVICE_HASH | + 1u << VIRTIO_CRYPTO_SERVICE_MAC; + backend->conf.cipher_algo_l =3D 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC; + backend->conf.hash_algo =3D 1u << VIRTIO_CRYPTO_HASH_SHA1; +} + +static int64_t cryptodev_vhost_user_sym_create_session( + CryptoDevBackend *backend, + CryptoDevBackendSymSessionInfo *sess_info, + uint32_t queue_index, Error **errp) +{ + return 0; +} + +static int cryptodev_vhost_user_sym_close_session( + CryptoDevBackend *backend, + uint64_t session_id, + uint32_t queue_index, Error **errp) +{ + return 0; +} + +static int cryptodev_vhost_user_sym_operation( + CryptoDevBackend *backend, + CryptoDevBackendSymOpInfo *op_info, + uint32_t queue_index, Error **errp) +{ + return VIRTIO_CRYPTO_OK; +} + +static void cryptodev_vhost_user_cleanup( + CryptoDevBackend *backend, + Error **errp) +{ + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(backend); + size_t i; + int queues =3D backend->conf.peers.queues; + CryptoDevBackendClient *cc; + + cryptodev_vhost_user_stop(queues, s); + + for (i =3D 0; i < queues; i++) { + cc =3D backend->conf.peers.ccs[i]; + if (cc) { + cryptodev_backend_free_client(cc); + backend->conf.peers.ccs[i] =3D NULL; + } + } +} + +static void cryptodev_vhost_user_set_chardev(Object *obj, + const char *value, Error **errp) +{ + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(obj); + + if (s->opened) { + error_setg(errp, QERR_PERMISSION_DENIED); + } else { + g_free(s->chr_name); + s->chr_name =3D g_strdup(value); + } +} + +static char * +cryptodev_vhost_user_get_chardev(Object *obj, Error **errp) +{ + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(obj); + Chardev *chr =3D qemu_chr_fe_get_driver(&s->chr); + + if (chr && chr->label) { + return g_strdup(chr->label); + } + + return NULL; +} + +static void cryptodev_vhost_user_instance_int(Object *obj) +{ + object_property_add_str(obj, "chardev", + cryptodev_vhost_user_get_chardev, + cryptodev_vhost_user_set_chardev, + NULL); +} + +static void cryptodev_vhost_user_finalize(Object *obj) +{ + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(obj); + + qemu_chr_fe_deinit(&s->chr, false); + + g_free(s->chr_name); +} + +static void +cryptodev_vhost_user_class_init(ObjectClass *oc, void *data) +{ + CryptoDevBackendClass *bc =3D CRYPTODEV_BACKEND_CLASS(oc); + + bc->init =3D cryptodev_vhost_user_init; + bc->cleanup =3D cryptodev_vhost_user_cleanup; + bc->create_session =3D cryptodev_vhost_user_sym_create_session; + bc->close_session =3D cryptodev_vhost_user_sym_close_session; + bc->do_sym_op =3D cryptodev_vhost_user_sym_operation; +} + +static const TypeInfo cryptodev_vhost_user_info =3D { + .name =3D TYPE_CRYPTODEV_BACKEND_VHOST_USER, + .parent =3D TYPE_CRYPTODEV_BACKEND, + .class_init =3D cryptodev_vhost_user_class_init, + .instance_init =3D cryptodev_vhost_user_instance_int, + .instance_finalize =3D cryptodev_vhost_user_finalize, + .instance_size =3D sizeof(CryptoDevBackendVhostUser), +}; + +static void +cryptodev_vhost_user_register_types(void) +{ + type_register_static(&cryptodev_vhost_user_info); +} + +type_init(cryptodev_vhost_user_register_types); diff --git a/backends/cryptodev-vhost.c b/backends/cryptodev-vhost.c new file mode 100644 index 0000000..27e1c4a --- /dev/null +++ b/backends/cryptodev-vhost.c @@ -0,0 +1,89 @@ +/* + * QEMU Cryptodev backend for QEMU cipher APIs + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * Jay Zhou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "sysemu/cryptodev-vhost.h" + +#ifdef CONFIG_VHOST_CRYPTO +uint64_t +cryptodev_vhost_get_max_queues( + CryptoDevBackendVhost *crypto) +{ + return crypto->dev.max_queues; +} + +void cryptodev_vhost_cleanup(CryptoDevBackendVhost *crypto) +{ + vhost_dev_cleanup(&crypto->dev); + g_free(crypto); +} + +struct CryptoDevBackendVhost * +cryptodev_vhost_init( + CryptoDevBackendVhostOptions *options) +{ + int r; + CryptoDevBackendVhost *crypto; + + crypto =3D g_new(CryptoDevBackendVhost, 1); + crypto->dev.max_queues =3D 1; + crypto->dev.nvqs =3D 1; + crypto->dev.vqs =3D crypto->vqs; + + crypto->cc =3D options->cc; + + crypto->dev.protocol_features =3D 0; + crypto->backend =3D -1; + + /* vhost-user needs vq_index to initiate a specific queue pair */ + crypto->dev.vq_index =3D crypto->cc->queue_index * crypto->dev.nvqs; + + r =3D vhost_dev_init(&crypto->dev, options->opaque, options->backend_t= ype, 0); + if (r < 0) { + goto fail; + } + + return crypto; +fail: + g_free(crypto); + return NULL; +} + +#else +uint64_t +cryptodev_vhost_get_max_queues(CryptoDevBackendVhost *crypto) +{ + return 0; +} + +void cryptodev_vhost_cleanup(CryptoDevBackendVhost *crypto) +{ +} + +struct CryptoDevBackendVhost * +cryptodev_vhost_init(CryptoDevBackendVhostOptions *options) +{ + return NULL; +} +#endif diff --git a/configure b/configure index 6d8c996..4d91a5b 100755 --- a/configure +++ b/configure @@ -332,6 +332,7 @@ xfs=3D"" tcg=3D"yes" =20 vhost_net=3D"no" +vhost_crypto=3D"no" vhost_scsi=3D"no" vhost_vsock=3D"no" vhost_user=3D"" @@ -801,6 +802,7 @@ Linux) linux_user=3D"yes" kvm=3D"yes" vhost_net=3D"yes" + vhost_crypto=3D"yes" vhost_scsi=3D"yes" vhost_vsock=3D"yes" QEMU_INCLUDES=3D"-I\$(SRC_PATH)/linux-headers -I$(pwd)/linux-headers $QE= MU_INCLUDES" @@ -1163,6 +1165,14 @@ for opt do ;; --enable-vhost-net) vhost_net=3D"yes" ;; + --disable-vhost-crypto) vhost_crypto=3D"no" + ;; + --enable-vhost-crypto) + vhost_crypto=3D"yes" + if test "$mingw32" =3D "yes"; then + error_exit "vhost-crypto isn't available on win32" + fi + ;; --disable-vhost-scsi) vhost_scsi=3D"no" ;; --enable-vhost-scsi) vhost_scsi=3D"yes" @@ -1555,6 +1565,7 @@ disabled with --disable-FEATURE, default is enabled i= f available: cap-ng libcap-ng support attr attr and xattr support vhost-net vhost-net acceleration support + vhost-crypto vhost-crypto acceleration support spice spice rbd rados block device (rbd) libiscsi iscsi support @@ -5591,6 +5602,7 @@ echo "madvise $madvise" echo "posix_madvise $posix_madvise" echo "libcap-ng support $cap_ng" echo "vhost-net support $vhost_net" +echo "vhost-crypto support $vhost_crypto" echo "vhost-scsi support $vhost_scsi" echo "vhost-vsock support $vhost_vsock" echo "vhost-user support $vhost_user" @@ -6652,6 +6664,9 @@ if supported_kvm_target $target; then echo "CONFIG_VHOST_USER_NET_TEST_$target_name=3Dy" >> $config_= host_mak fi fi + if test "$vhost_crypto" =3D "yes" ; then + echo "CONFIG_VHOST_CRYPTO=3Dy" >> $config_target_mak + fi fi if supported_hax_target $target; then echo "CONFIG_HAX=3Dy" >> $config_target_mak diff --git a/include/sysemu/cryptodev-vhost.h b/include/sysemu/cryptodev-vh= ost.h new file mode 100644 index 0000000..fb26b86 --- /dev/null +++ b/include/sysemu/cryptodev-vhost.h @@ -0,0 +1,154 @@ +/* + * QEMU Crypto Device Common Vhost Implement + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * Jay Zhou + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ +#ifndef CRYPTODEV_VHOST_H +#define CRYPTODEV_VHOST_H + +#include "qemu-common.h" +#include "hw/virtio/vhost.h" +#include "hw/virtio/vhost-backend.h" +#include "chardev/char.h" + +#include "sysemu/cryptodev.h" + + +typedef struct CryptoDevBackendVhostOptions { + VhostBackendType backend_type; + void *opaque; + int total_queues; + CryptoDevBackendClient *cc; +} CryptoDevBackendVhostOptions; + +typedef struct CryptoDevBackendVhost { + struct vhost_dev dev; + struct vhost_virtqueue vqs[1]; + int backend; + CryptoDevBackendClient *cc; +} CryptoDevBackendVhost; + +/** + * cryptodev_vhost_get_max_queues: + * @crypto: the cryptodev backend common vhost object + * + * Get the maximum queue number of @crypto. + * + * + * Returns: the maximum queue number + */ +uint64_t +cryptodev_vhost_get_max_queues( + CryptoDevBackendVhost *crypto); + + +/** + * cryptodev_vhost_init: + * @options: the common vhost object's option + * + * Creates a new cryptodev backend common vhost object + * + ** The returned object must be released with + * cryptodev_vhost_cleanup() when no + * longer required + * + * Returns: the cryptodev backend common vhost object + */ +struct CryptoDevBackendVhost * +cryptodev_vhost_init( + CryptoDevBackendVhostOptions *options); + +/** + * cryptodev_vhost_cleanup: + * @crypto: the cryptodev backend common vhost object + * + * Clean the resouce associated with @crypto that realizaed + * by cryptodev_vhost_init() + * + */ +void cryptodev_vhost_cleanup( + CryptoDevBackendVhost *crypto); + +/** + * cryptodev_get_vhost: + * @cc: the client object for each queue + * @b: the cryptodev backend common vhost object + * @queue: the cryptodev backend queue index + * + * Gets a new cryptodev backend common vhost object based on + * @b and @queue + * + * Returns: the cryptodev backend common vhost object + */ +CryptoDevBackendVhost * +cryptodev_get_vhost(CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue); +/** + * cryptodev_vhost_start: + * @dev: the virtio crypto object + * @total_queues: the total count of queue + * + * Starts the vhost crypto logic + * + * Returns: 0 for success, negative for errors + */ +int cryptodev_vhost_start(VirtIODevice *dev, int total_queues); + +/** + * cryptodev_vhost_stop: + * @dev: the virtio crypto object + * @total_queues: the total count of queue + * + * Stops the vhost crypto logic + * + */ +void cryptodev_vhost_stop(VirtIODevice *dev, int total_queues); + +/** + * cryptodev_vhost_virtqueue_mask: + * @dev: the virtio crypto object + * @queue: the cryptodev backend queue index + * @idx: the virtqueue index + * @mask: mask or not (true or false) + * + * Mask/unmask events for @idx virtqueue on @dev device + * + */ +void cryptodev_vhost_virtqueue_mask(VirtIODevice *dev, + int queue, + int idx, bool mask); + +/** + * cryptodev_vhost_virtqueue_pending: + * @dev: the virtio crypto object + * @queue: the cryptodev backend queue index + * @idx: the virtqueue index + * + * Test and clear event pending status for @idx virtqueue on @dev device. + * Should be called after unmask to avoid losing events. + * + * Returns: true for success, false for errors + */ +bool cryptodev_vhost_virtqueue_pending(VirtIODevice *dev, + int queue, int idx); + +#endif /* CRYPTODEV_VHOST_H */ diff --git a/qemu-options.hx b/qemu-options.hx index 5ff741a..436191d 100644 --- a/qemu-options.hx +++ b/qemu-options.hx @@ -4220,6 +4220,27 @@ which specify the queue number of cryptodev backend,= the default of [...] @end example =20 +@item -object cryptodev-vhost-user,id=3D@var{id},chardev=3D@var{chardevid}= [,queues=3D@var{queues}] + +Creates a vhost-user cryptodev backend, backed by a chardev @var{chardevid= }. +The @var{id} parameter is a unique ID that will be used to reference this +cryptodev backend from the @option{virtio-crypto} device. +The chardev should be a unix domain socket backed one. The vhost-user uses +a specifically defined protocol to pass vhost ioctl replacement messages +to an application on the other end of the socket. +The @var{queues} parameter is optional, which specify the queue number +of cryptodev backend for multiqueue vhost-user, the default of @var{queues= } is 1. + +@example + + # qemu-system-x86_64 \ + [...] \ + -chardev socket,id=3Dchardev0,path=3D/path/to/socket \ + -object cryptodev-vhost-user,id=3Dcryptodev0,chardev=3Dchardev0 \ + -device virtio-crypto-pci,id=3Dcrypto0,cryptodev=3Dcryptodev0 \ + [...] +@end example + @item -object secret,id=3D@var{id},data=3D@var{string},format=3D@var{raw|b= ase64}[,keyid=3D@var{secretid},iv=3D@var{string}] @item -object secret,id=3D@var{id},file=3D@var{filename},format=3D@var{raw= |base64}[,keyid=3D@var{secretid},iv=3D@var{string}] =20 diff --git a/vl.c b/vl.c index e725ecb..805c788 100644 --- a/vl.c +++ b/vl.c @@ -2867,6 +2867,12 @@ static bool object_create_initial(const char *type) return false; } =20 +#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) + if (g_str_equal(type, "cryptodev-vhost-user")) { + return false; + } +#endif + /* * return false for concrete netfilters since * they depend on netdevs already existing --=20 1.8.3.1 From nobody Thu May 2 07:43:13 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516539623762142.4353707562093; Sun, 21 Jan 2018 05:00:23 -0800 (PST) Received: from localhost ([::1]:55051 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFES-00007k-V9 for importer@patchew.org; Sun, 21 Jan 2018 08:00:20 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48710) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFAL-0005Rk-Dc for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edFAH-0000ro-Bf for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:05 -0500 Received: from [45.249.212.32] (port=41406 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edFAG-0000qs-Es for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:01 -0500 Received: from DGGEMS412-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 05A76D9534A2B; Sun, 21 Jan 2018 20:55:46 +0800 (CST) Received: from localhost (10.177.19.14) by DGGEMS412-HUB.china.huawei.com (10.3.19.212) with Microsoft SMTP Server id 14.3.361.1; Sun, 21 Jan 2018 20:55:40 +0800 From: Jay Zhou To: Date: Sun, 21 Jan 2018 20:54:48 +0800 Message-ID: <0468514c9952e09a93038a70c16e0cc7f283b1c9.1516538887.git.arei.gonglei@huawei.com> X-Mailer: git-send-email 2.6.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.177.19.14] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.32 Subject: [Qemu-devel] [PATCH v6 2/4] cryptodev: add vhost support 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: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com, mst@redhat.com, wangxinxin.wang@huawei.com, xin.zeng@intel.com, arei.gonglei@huawei.com, roy.fan.zhang@intel.com, stefanha@redhat.com, jianjay.zhou@huawei.com, pbonzini@redhat.com, longpeng2@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gonglei Impliment the vhost-crypto's funtions, such as startup, stop and notification etc. Introduce an enum QCryptoCryptoDevBackendOptionsType in order to identify the cryptodev vhost backend is vhost-user or vhost-kernel-module (If exist). At this point, the cryptdoev-vhost-user works. Signed-off-by: Gonglei Signed-off-by: Longpeng(Mike) Signed-off-by: Jay Zhou --- backends/cryptodev-builtin.c | 1 + backends/cryptodev-vhost-user.c | 16 +++ backends/cryptodev-vhost.c | 258 ++++++++++++++++++++++++++++++= ++++ hw/virtio/Makefile.objs | 2 +- hw/virtio/virtio-crypto.c | 70 +++++++++ include/hw/virtio/virtio-crypto.h | 1 + include/sysemu/cryptodev-vhost-user.h | 44 ++++++ include/sysemu/cryptodev.h | 8 ++ 8 files changed, 399 insertions(+), 1 deletion(-) create mode 100644 include/sysemu/cryptodev-vhost-user.h diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c index 657c0ba..9fb0bd5 100644 --- a/backends/cryptodev-builtin.c +++ b/backends/cryptodev-builtin.c @@ -78,6 +78,7 @@ static void cryptodev_builtin_init( "cryptodev-builtin", NULL); cc->info_str =3D g_strdup_printf("cryptodev-builtin0"); cc->queue_index =3D 0; + cc->type =3D CRYPTODEV_BACKEND_TYPE_BUILTIN; backend->conf.peers.ccs[0] =3D cc; =20 backend->conf.crypto_services =3D diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.c index 4e63ece..0b1f049 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -29,6 +29,7 @@ #include "standard-headers/linux/virtio_crypto.h" #include "sysemu/cryptodev-vhost.h" #include "chardev/char-fe.h" +#include "sysemu/cryptodev-vhost-user.h" =20 =20 /** @@ -58,6 +59,20 @@ cryptodev_vhost_user_running( return crypto ? 1 : 0; } =20 +CryptoDevBackendVhost * +cryptodev_vhost_user_get_vhost( + CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue) +{ + CryptoDevBackendVhostUser *s =3D + CRYPTODEV_BACKEND_VHOST_USER(b); + assert(cc->type =3D=3D CRYPTODEV_BACKEND_TYPE_VHOST_USER); + assert(queue < MAX_CRYPTO_QUEUE_NUM); + + return s->vhost_crypto[queue]; +} + static void cryptodev_vhost_user_stop(int queues, CryptoDevBackendVhostUser *s) { @@ -190,6 +205,7 @@ static void cryptodev_vhost_user_init( cc->info_str =3D g_strdup_printf("cryptodev-vhost-user%lu to %s ", i, chr->label); cc->queue_index =3D i; + cc->type =3D CRYPTODEV_BACKEND_TYPE_VHOST_USER; =20 backend->conf.peers.ccs[i] =3D cc; =20 diff --git a/backends/cryptodev-vhost.c b/backends/cryptodev-vhost.c index 27e1c4a..8337c9a 100644 --- a/backends/cryptodev-vhost.c +++ b/backends/cryptodev-vhost.c @@ -23,9 +23,16 @@ */ =20 #include "qemu/osdep.h" +#include "hw/virtio/virtio-bus.h" #include "sysemu/cryptodev-vhost.h" =20 #ifdef CONFIG_VHOST_CRYPTO +#include "qapi/error.h" +#include "qapi/qmp/qerror.h" +#include "qemu/error-report.h" +#include "hw/virtio/virtio-crypto.h" +#include "sysemu/cryptodev-vhost-user.h" + uint64_t cryptodev_vhost_get_max_queues( CryptoDevBackendVhost *crypto) @@ -70,6 +77,228 @@ fail: return NULL; } =20 +static int +cryptodev_vhost_start_one(CryptoDevBackendVhost *crypto, + VirtIODevice *dev) +{ + int r; + + crypto->dev.nvqs =3D 1; + crypto->dev.vqs =3D crypto->vqs; + + r =3D vhost_dev_enable_notifiers(&crypto->dev, dev); + if (r < 0) { + goto fail_notifiers; + } + + r =3D vhost_dev_start(&crypto->dev, dev); + if (r < 0) { + goto fail_start; + } + + return 0; + +fail_start: + vhost_dev_disable_notifiers(&crypto->dev, dev); +fail_notifiers: + return r; +} + +static void +cryptodev_vhost_stop_one(CryptoDevBackendVhost *crypto, + VirtIODevice *dev) +{ + vhost_dev_stop(&crypto->dev, dev); + vhost_dev_disable_notifiers(&crypto->dev, dev); +} + +CryptoDevBackendVhost * +cryptodev_get_vhost(CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue) +{ + CryptoDevBackendVhost *vhost_crypto =3D NULL; + + if (!cc) { + return NULL; + } + + switch (cc->type) { +#if defined(CONFIG_VHOST_USER) && defined(CONFIG_LINUX) + case CRYPTODEV_BACKEND_TYPE_VHOST_USER: + vhost_crypto =3D cryptodev_vhost_user_get_vhost(cc, b, queue); + break; +#endif + default: + break; + } + + return vhost_crypto; +} + +static void +cryptodev_vhost_set_vq_index(CryptoDevBackendVhost *crypto, + int vq_index) +{ + crypto->dev.vq_index =3D vq_index; +} + +static int +vhost_set_vring_enable(CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue, int enable) +{ + CryptoDevBackendVhost *crypto =3D + cryptodev_get_vhost(cc, b, queue); + const VhostOps *vhost_ops; + + cc->vring_enable =3D enable; + + if (!crypto) { + return 0; + } + + vhost_ops =3D crypto->dev.vhost_ops; + if (vhost_ops->vhost_set_vring_enable) { + return vhost_ops->vhost_set_vring_enable(&crypto->dev, enable); + } + + return 0; +} + +int cryptodev_vhost_start(VirtIODevice *dev, int total_queues) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(dev); + BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(dev))); + VirtioBusState *vbus =3D VIRTIO_BUS(qbus); + VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(vbus); + int r, e; + int i; + CryptoDevBackend *b =3D vcrypto->cryptodev; + CryptoDevBackendVhost *vhost_crypto; + CryptoDevBackendClient *cc; + + if (!k->set_guest_notifiers) { + error_report("binding does not support guest notifiers"); + return -ENOSYS; + } + + for (i =3D 0; i < total_queues; i++) { + cc =3D b->conf.peers.ccs[i]; + + vhost_crypto =3D cryptodev_get_vhost(cc, b, i); + cryptodev_vhost_set_vq_index(vhost_crypto, i); + + /* Suppress the masking guest notifiers on vhost user + * because vhost user doesn't interrupt masking/unmasking + * properly. + */ + if (cc->type =3D=3D CRYPTODEV_BACKEND_TYPE_VHOST_USER) { + dev->use_guest_notifier_mask =3D false; + } + } + + r =3D k->set_guest_notifiers(qbus->parent, total_queues, true); + if (r < 0) { + error_report("error binding guest notifier: %d", -r); + goto err; + } + + for (i =3D 0; i < total_queues; i++) { + cc =3D b->conf.peers.ccs[i]; + + vhost_crypto =3D cryptodev_get_vhost(cc, b, i); + r =3D cryptodev_vhost_start_one(vhost_crypto, dev); + + if (r < 0) { + goto err_start; + } + + if (cc->vring_enable) { + /* restore vring enable state */ + r =3D vhost_set_vring_enable(cc, b, i, cc->vring_enable); + + if (r < 0) { + goto err_start; + } + } + } + + return 0; + +err_start: + while (--i >=3D 0) { + cc =3D b->conf.peers.ccs[i]; + vhost_crypto =3D cryptodev_get_vhost(cc, b, i); + cryptodev_vhost_stop_one(vhost_crypto, dev); + } + e =3D k->set_guest_notifiers(qbus->parent, total_queues, false); + if (e < 0) { + error_report("vhost guest notifier cleanup failed: %d", e); + } +err: + return r; +} + +void cryptodev_vhost_stop(VirtIODevice *dev, int total_queues) +{ + BusState *qbus =3D BUS(qdev_get_parent_bus(DEVICE(dev))); + VirtioBusState *vbus =3D VIRTIO_BUS(qbus); + VirtioBusClass *k =3D VIRTIO_BUS_GET_CLASS(vbus); + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(dev); + CryptoDevBackend *b =3D vcrypto->cryptodev; + CryptoDevBackendVhost *vhost_crypto; + CryptoDevBackendClient *cc; + size_t i; + int r; + + for (i =3D 0; i < total_queues; i++) { + cc =3D b->conf.peers.ccs[i]; + + vhost_crypto =3D cryptodev_get_vhost(cc, b, i); + cryptodev_vhost_stop_one(vhost_crypto, dev); + } + + r =3D k->set_guest_notifiers(qbus->parent, total_queues, false); + if (r < 0) { + error_report("vhost guest notifier cleanup failed: %d", r); + } + assert(r >=3D 0); +} + +void cryptodev_vhost_virtqueue_mask(VirtIODevice *dev, + int queue, + int idx, bool mask) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(dev); + CryptoDevBackend *b =3D vcrypto->cryptodev; + CryptoDevBackendVhost *vhost_crypto; + CryptoDevBackendClient *cc; + + assert(queue < MAX_CRYPTO_QUEUE_NUM); + + cc =3D b->conf.peers.ccs[queue]; + vhost_crypto =3D cryptodev_get_vhost(cc, b, queue); + + vhost_virtqueue_mask(&vhost_crypto->dev, dev, idx, mask); +} + +bool cryptodev_vhost_virtqueue_pending(VirtIODevice *dev, + int queue, int idx) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(dev); + CryptoDevBackend *b =3D vcrypto->cryptodev; + CryptoDevBackendVhost *vhost_crypto; + CryptoDevBackendClient *cc; + + assert(queue < MAX_CRYPTO_QUEUE_NUM); + + cc =3D b->conf.peers.ccs[queue]; + vhost_crypto =3D cryptodev_get_vhost(cc, b, queue); + + return vhost_virtqueue_pending(&vhost_crypto->dev, idx); +} + #else uint64_t cryptodev_vhost_get_max_queues(CryptoDevBackendVhost *crypto) @@ -86,4 +315,33 @@ cryptodev_vhost_init(CryptoDevBackendVhostOptions *opti= ons) { return NULL; } + +CryptoDevBackendVhost * +cryptodev_get_vhost(CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue) +{ + return NULL; +} + +int cryptodev_vhost_start(VirtIODevice *dev, int total_queues) +{ + return -1; +} + +void cryptodev_vhost_stop(VirtIODevice *dev, int total_queues) +{ +} + +void cryptodev_vhost_virtqueue_mask(VirtIODevice *dev, + int queue, + int idx, bool mask) +{ +} + +bool cryptodev_vhost_virtqueue_pending(VirtIODevice *dev, + int queue, int idx) +{ + return false; +} #endif diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs index 765d363..c65dca2 100644 --- a/hw/virtio/Makefile.objs +++ b/hw/virtio/Makefile.objs @@ -7,7 +7,7 @@ common-obj-y +=3D virtio-mmio.o obj-y +=3D virtio.o virtio-balloon.o=20 obj-$(CONFIG_LINUX) +=3D vhost.o vhost-backend.o vhost-user.o obj-$(CONFIG_VHOST_VSOCK) +=3D vhost-vsock.o -obj-y +=3D virtio-crypto.o +obj-$(CONFIG_LINUX) +=3D virtio-crypto.o obj-$(CONFIG_VIRTIO_PCI) +=3D virtio-crypto-pci.o endif =20 diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 19c82e0..9a9fa49 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -20,6 +20,7 @@ #include "hw/virtio/virtio-crypto.h" #include "hw/virtio/virtio-access.h" #include "standard-headers/linux/virtio_ids.h" +#include "sysemu/cryptodev-vhost.h" =20 #define VIRTIO_CRYPTO_VM_VERSION 1 =20 @@ -880,6 +881,72 @@ static void virtio_crypto_get_config(VirtIODevice *vde= v, uint8_t *config) memcpy(config, &crypto_cfg, c->config_size); } =20 +static bool virtio_crypto_started(VirtIOCrypto *c, uint8_t status) +{ + VirtIODevice *vdev =3D VIRTIO_DEVICE(c); + return (status & VIRTIO_CONFIG_S_DRIVER_OK) && + (c->status & VIRTIO_CRYPTO_S_HW_READY) && vdev->vm_running; +} + +static void virtio_crypto_vhost_status(VirtIOCrypto *c, uint8_t status) +{ + VirtIODevice *vdev =3D VIRTIO_DEVICE(c); + int queues =3D c->multiqueue ? c->max_queues : 1; + CryptoDevBackend *b =3D c->cryptodev; + CryptoDevBackendClient *cc =3D b->conf.peers.ccs[0]; + + if (!cryptodev_get_vhost(cc, b, 0)) { + return; + } + + if ((virtio_crypto_started(c, status)) =3D=3D !!c->vhost_started) { + return; + } + + if (!c->vhost_started) { + int r; + + c->vhost_started =3D 1; + r =3D cryptodev_vhost_start(vdev, queues); + if (r < 0) { + error_report("unable to start vhost crypto: %d: " + "falling back on userspace virtio", -r); + c->vhost_started =3D 0; + } + } else { + cryptodev_vhost_stop(vdev, queues); + c->vhost_started =3D 0; + } +} + +static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(vdev); + + virtio_crypto_vhost_status(vcrypto, status); +} + +static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, + bool mask) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(vdev); + int queue =3D virtio_crypto_vq2q(idx); + + assert(vcrypto->vhost_started); + + cryptodev_vhost_virtqueue_mask(vdev, queue, idx, mask); +} + +static bool virtio_crypto_guest_notifier_pending(VirtIODevice *vdev, int i= dx) +{ + VirtIOCrypto *vcrypto =3D VIRTIO_CRYPTO(vdev); + int queue =3D virtio_crypto_vq2q(idx); + + assert(vcrypto->vhost_started); + + return cryptodev_vhost_virtqueue_pending(vdev, queue, idx); +} + static void virtio_crypto_class_init(ObjectClass *klass, void *data) { DeviceClass *dc =3D DEVICE_CLASS(klass); @@ -893,6 +960,9 @@ static void virtio_crypto_class_init(ObjectClass *klass= , void *data) vdc->get_config =3D virtio_crypto_get_config; vdc->get_features =3D virtio_crypto_get_features; vdc->reset =3D virtio_crypto_reset; + vdc->set_status =3D virtio_crypto_set_status; + vdc->guest_notifier_mask =3D virtio_crypto_guest_notifier_mask; + vdc->guest_notifier_pending =3D virtio_crypto_guest_notifier_pending; } =20 static void virtio_crypto_instance_init(Object *obj) diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-c= rypto.h index a00a0bf..ca3a049 100644 --- a/include/hw/virtio/virtio-crypto.h +++ b/include/hw/virtio/virtio-crypto.h @@ -96,6 +96,7 @@ typedef struct VirtIOCrypto { int multiqueue; uint32_t curr_queues; size_t config_size; + uint8_t vhost_started; } VirtIOCrypto; =20 #endif /* _QEMU_VIRTIO_CRYPTO_H */ diff --git a/include/sysemu/cryptodev-vhost-user.h b/include/sysemu/cryptod= ev-vhost-user.h new file mode 100644 index 0000000..937217b --- /dev/null +++ b/include/sysemu/cryptodev-vhost-user.h @@ -0,0 +1,44 @@ +/* + * QEMU Crypto Device Common Vhost User Implement + * + * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD. + * + * Authors: + * Gonglei + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, see . + * + */ +#ifndef CRYPTODEV_VHOST_USER_H +#define CRYPTODEV_VHOST_USER_H + + +/** + * cryptodev_vhost_user_get_vhost: + * @cc: the client object for each queue + * @b: the cryptodev backend common vhost object + * @queue: the queue index + * + * Gets a new cryptodev backend common vhost object based on + * @b and @queue + * + * Returns: the cryptodev backend common vhost object + */ +CryptoDevBackendVhost * +cryptodev_vhost_user_get_vhost( + CryptoDevBackendClient *cc, + CryptoDevBackend *b, + uint16_t queue); + +#endif /* CRYPTODEV_VHOST_USER_H */ diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h index a9d0d1e..faeb6f8 100644 --- a/include/sysemu/cryptodev.h +++ b/include/sysemu/cryptodev.h @@ -163,12 +163,20 @@ typedef struct CryptoDevBackendClass { uint32_t queue_index, Error **errp); } CryptoDevBackendClass; =20 +typedef enum CryptoDevBackendOptionsType { + CRYPTODEV_BACKEND_TYPE_NONE =3D 0, + CRYPTODEV_BACKEND_TYPE_BUILTIN =3D 1, + CRYPTODEV_BACKEND_TYPE_VHOST_USER =3D 2, + CRYPTODEV_BACKEND_TYPE__MAX, +} CryptoDevBackendOptionsType; =20 struct CryptoDevBackendClient { + CryptoDevBackendOptionsType type; char *model; char *name; char *info_str; unsigned int queue_index; + int vring_enable; QTAILQ_ENTRY(CryptoDevBackendClient) next; }; =20 --=20 1.8.3.1 From nobody Thu May 2 07:43:13 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 Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516539559315349.72611105336864; Sun, 21 Jan 2018 04:59:19 -0800 (PST) Received: from localhost ([::1]:54926 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFDN-0007UY-JK for importer@patchew.org; Sun, 21 Jan 2018 07:59:13 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48715) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFAM-0005So-S8 for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:10 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edFAJ-0000sx-FJ for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:06 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2076 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edFAI-0000rV-Lo for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:03 -0500 Received: from DGGEMS407-HUB.china.huawei.com (unknown [172.30.72.60]) by Forcepoint Email with ESMTP id 0873E568EE12F; Sun, 21 Jan 2018 20:55:48 +0800 (CST) Received: from localhost (10.177.19.14) by DGGEMS407-HUB.china.huawei.com (10.3.19.207) with Microsoft SMTP Server id 14.3.361.1; Sun, 21 Jan 2018 20:55:41 +0800 From: Jay Zhou To: Date: Sun, 21 Jan 2018 20:54:49 +0800 Message-ID: X-Mailer: git-send-email 2.6.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.177.19.14] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH v6 3/4] cryptodev-vhost-user: add crypto session handler 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: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com, mst@redhat.com, wangxinxin.wang@huawei.com, xin.zeng@intel.com, arei.gonglei@huawei.com, roy.fan.zhang@intel.com, stefanha@redhat.com, jianjay.zhou@huawei.com, pbonzini@redhat.com, longpeng2@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gonglei Introduce two vhost-user meassges: VHOST_USER_CREATE_CRYPTO_SESSION and VHOST_USER_CLOSE_CRYPTO_SESSION. At this point, the QEMU side support crypto operation in cryptodev host-user backend. Signed-off-by: Gonglei Signed-off-by: Longpeng(Mike) Signed-off-by: Jay Zhou --- backends/cryptodev-vhost-user.c | 48 ++++++++++++++---- docs/interop/vhost-user.txt | 26 ++++++++++ hw/virtio/vhost-user.c | 104 ++++++++++++++++++++++++++++++++++= ++++ include/hw/virtio/vhost-backend.h | 8 +++ 4 files changed, 175 insertions(+), 11 deletions(-) diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.c index 0b1f049..7bd0929 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -233,7 +233,25 @@ static int64_t cryptodev_vhost_user_sym_create_session( CryptoDevBackendSymSessionInfo *sess_info, uint32_t queue_index, Error **errp) { - return 0; + CryptoDevBackendClient *cc =3D + backend->conf.peers.ccs[queue_index]; + CryptoDevBackendVhost *vhost_crypto; + uint64_t session_id =3D 0; + int ret; + + vhost_crypto =3D cryptodev_vhost_user_get_vhost(cc, backend, queue_ind= ex); + if (vhost_crypto) { + struct vhost_dev *dev =3D &(vhost_crypto->dev); + ret =3D dev->vhost_ops->vhost_crypto_create_session(dev, + sess_info, + &session_id); + if (ret < 0) { + return -1; + } else { + return session_id; + } + } + return -1; } =20 static int cryptodev_vhost_user_sym_close_session( @@ -241,15 +259,23 @@ static int cryptodev_vhost_user_sym_close_session( uint64_t session_id, uint32_t queue_index, Error **errp) { - return 0; -} - -static int cryptodev_vhost_user_sym_operation( - CryptoDevBackend *backend, - CryptoDevBackendSymOpInfo *op_info, - uint32_t queue_index, Error **errp) -{ - return VIRTIO_CRYPTO_OK; + CryptoDevBackendClient *cc =3D + backend->conf.peers.ccs[queue_index]; + CryptoDevBackendVhost *vhost_crypto; + int ret; + + vhost_crypto =3D cryptodev_vhost_user_get_vhost(cc, backend, queue_ind= ex); + if (vhost_crypto) { + struct vhost_dev *dev =3D &(vhost_crypto->dev); + ret =3D dev->vhost_ops->vhost_crypto_close_session(dev, + session_id); + if (ret < 0) { + return -1; + } else { + return 0; + } + } + return -1; } =20 static void cryptodev_vhost_user_cleanup( @@ -328,7 +354,7 @@ cryptodev_vhost_user_class_init(ObjectClass *oc, void *= data) bc->cleanup =3D cryptodev_vhost_user_cleanup; bc->create_session =3D cryptodev_vhost_user_sym_create_session; bc->close_session =3D cryptodev_vhost_user_sym_close_session; - bc->do_sym_op =3D cryptodev_vhost_user_sym_operation; + bc->do_sym_op =3D NULL; } =20 static const TypeInfo cryptodev_vhost_user_info =3D { diff --git a/docs/interop/vhost-user.txt b/docs/interop/vhost-user.txt index 9fcf48d..cb3a759 100644 --- a/docs/interop/vhost-user.txt +++ b/docs/interop/vhost-user.txt @@ -368,6 +368,7 @@ Protocol features #define VHOST_USER_PROTOCOL_F_MTU 4 #define VHOST_USER_PROTOCOL_F_SLAVE_REQ 5 #define VHOST_USER_PROTOCOL_F_CROSS_ENDIAN 6 +#define VHOST_USER_PROTOCOL_F_CRYPTO_SESSION 7 =20 Master message types -------------------- @@ -663,6 +664,31 @@ Master message types field, and slaves MUST NOT accept SET_CONFIG for read-only configuration space fields unless the live migration bit is set. =20 +* VHOST_USER_CREATE_CRYPTO_SESSION + + Id: 26 + Equivalent ioctl: N/A + Master payload: crypto session description + Slave payload: crypto session description + + Create a session for crypto operation. The server side must return the + session id, 0 or positive for success, negative for failure. + This request should be sent only when VHOST_USER_PROTOCOL_F_CRYPTO_SE= SSION + feature has been successfully negotiated. + It's a required feature for crypto devices. + +* VHOST_USER_CLOSE_CRYPTO_SESSION + + Id: 27 + Equivalent ioctl: N/A + Master payload: u64 + + Close a session for crypto operation which was previously + created by VHOST_USER_CREATE_CRYPTO_SESSION. + This request should be sent only when VHOST_USER_PROTOCOL_F_CRYPTO_SE= SSION + feature has been successfully negotiated. + It's a required feature for crypto devices. + Slave message types ------------------- =20 diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index 6eb9798..41ff5cf 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -17,6 +17,7 @@ #include "sysemu/kvm.h" #include "qemu/error-report.h" #include "qemu/sockets.h" +#include "sysemu/cryptodev.h" =20 #include #include @@ -39,6 +40,7 @@ enum VhostUserProtocolFeature { VHOST_USER_PROTOCOL_F_NET_MTU =3D 4, VHOST_USER_PROTOCOL_F_SLAVE_REQ =3D 5, VHOST_USER_PROTOCOL_F_CROSS_ENDIAN =3D 6, + VHOST_USER_PROTOCOL_F_CRYPTO_SESSION =3D 7, =20 VHOST_USER_PROTOCOL_F_MAX }; @@ -72,6 +74,8 @@ typedef enum VhostUserRequest { VHOST_USER_SET_VRING_ENDIAN =3D 23, VHOST_USER_GET_CONFIG =3D 24, VHOST_USER_SET_CONFIG =3D 25, + VHOST_USER_CREATE_CRYPTO_SESSION =3D 26, + VHOST_USER_CLOSE_CRYPTO_SESSION =3D 27, VHOST_USER_MAX } VhostUserRequest; =20 @@ -107,6 +111,17 @@ typedef struct VhostUserConfig { uint8_t region[VHOST_USER_MAX_CONFIG_SIZE]; } VhostUserConfig; =20 +#define VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN 512 +#define VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN 64 + +typedef struct VhostUserCryptoSession { + /* session id for success, -1 on errors */ + int64_t session_id; + CryptoDevBackendSymSessionInfo session_setup_data; + uint8_t key[VHOST_CRYPTO_SYM_CIPHER_MAX_KEY_LEN]; + uint8_t auth_key[VHOST_CRYPTO_SYM_HMAC_MAX_KEY_LEN]; +} VhostUserCryptoSession; + static VhostUserConfig c __attribute__ ((unused)); #define VHOST_USER_CONFIG_HDR_SIZE (sizeof(c.offset) \ + sizeof(c.size) \ @@ -132,6 +147,7 @@ typedef union { VhostUserLog log; struct vhost_iotlb_msg iotlb; VhostUserConfig config; + VhostUserCryptoSession session; } VhostUserPayload; =20 typedef struct VhostUserMsg { @@ -1054,6 +1070,92 @@ static int vhost_user_set_config(struct vhost_dev *d= ev, const uint8_t *data, return 0; } =20 +static int vhost_user_crypto_create_session(struct vhost_dev *dev, + void *session_info, + uint64_t *session_id) +{ + bool crypto_session =3D virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CRYPTO_SESSIO= N); + CryptoDevBackendSymSessionInfo *sess_info =3D session_info; + VhostUserMsg msg =3D { + .hdr.request =3D VHOST_USER_CREATE_CRYPTO_SESSION, + .hdr.flags =3D VHOST_USER_VERSION, + .hdr.size =3D sizeof(msg.payload.session), + }; + + assert(dev->vhost_ops->backend_type =3D=3D VHOST_BACKEND_TYPE_USER); + + if (!crypto_session) { + error_report("vhost-user trying to send unhandled ioctl"); + return -1; + } + + memcpy(&msg.payload.session.session_setup_data, sess_info, + sizeof(CryptoDevBackendSymSessionInfo)); + if (sess_info->key_len) { + memcpy(&msg.payload.session.key, sess_info->cipher_key, + sess_info->key_len); + } + if (sess_info->auth_key_len > 0) { + memcpy(&msg.payload.session.auth_key, sess_info->auth_key, + sess_info->auth_key_len); + } + if (vhost_user_write(dev, &msg, NULL, 0) < 0) { + error_report("vhost_user_write() return -1, create session failed"= ); + return -1; + } + + if (vhost_user_read(dev, &msg) < 0) { + error_report("vhost_user_read() return -1, create session failed"); + return -1; + } + + if (msg.hdr.request !=3D VHOST_USER_CREATE_CRYPTO_SESSION) { + error_report("Received unexpected msg type. Expected %d received %= d", + VHOST_USER_CREATE_CRYPTO_SESSION, msg.hdr.request); + return -1; + } + + if (msg.hdr.size !=3D sizeof(msg.payload.session)) { + error_report("Received bad msg size."); + return -1; + } + + if (msg.payload.session.session_id < 0) { + error_report("Bad session id: %" PRId64 "", + msg.payload.session.session_id); + return -1; + } + *session_id =3D msg.payload.session.session_id; + + return 0; +} + +static int +vhost_user_crypto_close_session(struct vhost_dev *dev, uint64_t session_id) +{ + bool crypto_session =3D virtio_has_feature(dev->protocol_features, + VHOST_USER_PROTOCOL_F_CRYPTO_SESSIO= N); + VhostUserMsg msg =3D { + .hdr.request =3D VHOST_USER_CLOSE_CRYPTO_SESSION, + .hdr.flags =3D VHOST_USER_VERSION, + .hdr.size =3D sizeof(msg.payload.u64), + }; + msg.payload.u64 =3D session_id; + + if (!crypto_session) { + error_report("vhost-user trying to send unhandled ioctl"); + return -1; + } + + if (vhost_user_write(dev, &msg, NULL, 0) < 0) { + error_report("vhost_user_write() return -1, close session failed"); + return -1; + } + + return 0; +} + const VhostOps user_ops =3D { .backend_type =3D VHOST_BACKEND_TYPE_USER, .vhost_backend_init =3D vhost_user_init, @@ -1082,4 +1184,6 @@ const VhostOps user_ops =3D { .vhost_send_device_iotlb_msg =3D vhost_user_send_device_iotlb_msg, .vhost_get_config =3D vhost_user_get_config, .vhost_set_config =3D vhost_user_set_config, + .vhost_crypto_create_session =3D vhost_user_crypto_create_session, + .vhost_crypto_close_session =3D vhost_user_crypto_close_session, }; diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-ba= ckend.h index 592254f..5dac61f 100644 --- a/include/hw/virtio/vhost-backend.h +++ b/include/hw/virtio/vhost-backend.h @@ -95,6 +95,12 @@ typedef int (*vhost_set_config_op)(struct vhost_dev *dev= , const uint8_t *data, typedef int (*vhost_get_config_op)(struct vhost_dev *dev, uint8_t *config, uint32_t config_len); =20 +typedef int (*vhost_crypto_create_session_op)(struct vhost_dev *dev, + void *session_info, + uint64_t *session_id); +typedef int (*vhost_crypto_close_session_op)(struct vhost_dev *dev, + uint64_t session_id); + typedef struct VhostOps { VhostBackendType backend_type; vhost_backend_init vhost_backend_init; @@ -130,6 +136,8 @@ typedef struct VhostOps { vhost_send_device_iotlb_msg_op vhost_send_device_iotlb_msg; vhost_get_config_op vhost_get_config; vhost_set_config_op vhost_set_config; + vhost_crypto_create_session_op vhost_crypto_create_session; + vhost_crypto_close_session_op vhost_crypto_close_session; } VhostOps; =20 extern const VhostOps user_ops; --=20 1.8.3.1 From nobody Thu May 2 07:43:13 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 Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1516539494027429.0761306651825; Sun, 21 Jan 2018 04:58:14 -0800 (PST) Received: from localhost ([::1]:54923 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFCM-0006d6-Ax for importer@patchew.org; Sun, 21 Jan 2018 07:58:10 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48714) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1edFAM-0005Sl-Rz for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:07 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1edFAI-0000sc-Vm for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:06 -0500 Received: from szxga05-in.huawei.com ([45.249.212.191]:2077 helo=huawei.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1edFAI-0000rb-KT for qemu-devel@nongnu.org; Sun, 21 Jan 2018 07:56:02 -0500 Received: from DGGEMS404-HUB.china.huawei.com (unknown [172.30.72.58]) by Forcepoint Email with ESMTP id 133BEA18D6B0B; Sun, 21 Jan 2018 20:55:48 +0800 (CST) Received: from localhost (10.177.19.14) by DGGEMS404-HUB.china.huawei.com (10.3.19.204) with Microsoft SMTP Server id 14.3.361.1; Sun, 21 Jan 2018 20:55:42 +0800 From: Jay Zhou To: Date: Sun, 21 Jan 2018 20:54:50 +0800 Message-ID: X-Mailer: git-send-email 2.6.1.windows.1 In-Reply-To: References: MIME-Version: 1.0 X-Originating-IP: [10.177.19.14] X-CFilter-Loop: Reflected X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 45.249.212.191 Subject: [Qemu-devel] [PATCH v6 4/4] cryptodev-vhost-user: set the key length 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: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com, mst@redhat.com, wangxinxin.wang@huawei.com, xin.zeng@intel.com, arei.gonglei@huawei.com, roy.fan.zhang@intel.com, stefanha@redhat.com, jianjay.zhou@huawei.com, pbonzini@redhat.com, longpeng2@huawei.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Gonglei Signed-off-by: Gonglei --- backends/cryptodev-vhost-user.c | 4 ++++ include/sysemu/cryptodev-vhost-user.h | 3 +++ 2 files changed, 7 insertions(+) diff --git a/backends/cryptodev-vhost-user.c b/backends/cryptodev-vhost-use= r.c index 7bd0929..11b834b 100644 --- a/backends/cryptodev-vhost-user.c +++ b/backends/cryptodev-vhost-user.c @@ -226,6 +226,10 @@ static void cryptodev_vhost_user_init( 1u << VIRTIO_CRYPTO_SERVICE_MAC; backend->conf.cipher_algo_l =3D 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC; backend->conf.hash_algo =3D 1u << VIRTIO_CRYPTO_HASH_SHA1; + + backend->conf.max_size =3D UINT64_MAX; + backend->conf.max_cipher_key_len =3D VHOST_USER_MAX_AUTH_KEY_LEN; + backend->conf.max_auth_key_len =3D VHOST_USER_MAX_AUTH_KEY_LEN; } =20 static int64_t cryptodev_vhost_user_sym_create_session( diff --git a/include/sysemu/cryptodev-vhost-user.h b/include/sysemu/cryptod= ev-vhost-user.h index 937217b..6debf53 100644 --- a/include/sysemu/cryptodev-vhost-user.h +++ b/include/sysemu/cryptodev-vhost-user.h @@ -23,6 +23,9 @@ #ifndef CRYPTODEV_VHOST_USER_H #define CRYPTODEV_VHOST_USER_H =20 +#define VHOST_USER_MAX_AUTH_KEY_LEN 512 +#define VHOST_USER_MAX_CIPHER_KEY_LEN 64 + =20 /** * cryptodev_vhost_user_get_vhost: --=20 1.8.3.1