All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
@ 2016-10-20 11:45 Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 01/12] cryptodev: introduce cryptodev backend interface Gonglei
                   ` (14 more replies)
  0 siblings, 15 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Hi,

The virtio crypto is a virtual crypto device as well as a kind
of virtual hardware accelerator for virtual machines. The
encryption and decryption requests are placed in the data
queue and handled by the real crypto accelerators finally.
The second queue is the control queue used to create or
destroy sessions for symmetric algorithms and control
some advanced features in the future. The virtio crypto
device provides the following crypto services: CIPHER,
MAC, HASH, AEAD etc.

TODO:
 - add vhost-user as a high performance cryptodev backend.
 - more crypto services support.
 - mirgration support.

Changes since v8:
 - fix a incorrect check condition in patch 9/12
 - add bh as the asynchronous handler for virtio-crypto's
   data virtqueue in patch 11/12  [Stefan]

Changes since v7:
 - handle endianess problems in input path [Stefan]
 - fix two possiable memory leak  [Stefan]
 - use the iov_*() functions on in_iov/in_num instead of directly accessing the iovecs
 - handle possible integer overflow [Stefan]
 - fix a typo  [Stefan]
 - define struct virtio_crypto_inhdr in virtio_crypto.h [Stefan]
 - use uint8_t instead of uint32_t for status in struct virtio_crypto_inhdr
 - remove unused field in VirtIOCryptoConf. [Stefan]
 - squash the VIRTIO_CRYPTO_OK changes into the patches that introduced the old code. [Stefan]
 - squash the previous patch 12 to patch 3 and patch 9 so that we can import the final version of
   external header file from Linux. [Stefan]

Changes since v6:
 - add copyright and license for virtio_crypto.h [Eric]
 - add/remove (bracket pair for macro definition in virtio_crypto.h  [Eric]
 - add missing dc->vmsd and fix a typo in patch 5
 - fix a checkpatch.pl complaint
 - rebase on the QEMU master branch

Changes since v5:
 - rebase the patch 14 in v5, using the correct at the beginning of whole patch series. [Eric]
 - perfect algorithm chain support in patch 12.
 - more friendly error handler in both controlq and dataq.
 - drop patch "virtio-crypto: emulate virtio crypto as a legacy device by default" because
  we shouldn't support transitional virtio devices any more. [Michael] 
 - drop patch "virtio-crypto-test: add qtest case for virtio-crypto" because
  libqtest doesn't support virtio-1.0 device yet.
 - rebase the patch set based on Michael's pull request:
    [PULL 00/33] virtio, pc: fixes and features

Changes since v4: (Thanks to Stefan)
 - drop scatter-gather I/O identification in virtio crypto spec and corresponding code [Stefan]
 - remove qcrypto perfix for cryptdov stuff [Stefan]
 - use virtio_error() in virtio-crypto device's functions. [Stefan]
 - fix endianness handling. [Stefan]
 - use VMSTATE_VIRTIO_DEVICE() instead of calling register_savevm(). [Stefan]
 - redefine DPRINTF in virtio-crypto.h [Stefan]
 - fix some typos [Stefan]
 - fix other farraginous problems suggested by Stefan.

Changes since v3:
 - rename cryptodev-gcrypt to cryptodev-buitlin. [Daniel]
 - move cryptodev stuff from crypto/ directory to backends/ directory
   in order to keep the crypto subsystem influence by syetem
   emulators. [Daniel]
 - emulate virtio-crypto device as a legacy device by default in patch 11
 - introduce virtio-crypto qtest case in patch 12
 - add myself as cryptdoev backends mainatainer and vitio-crypto
   co-maintainer in patch 13
 - add CRT support for cryptodev-builtin, it based on my previous crypto
   patch serial queued by Daniel.
   https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg06607.html
 - add queue_index for qcrypto_cryptodev_backend_sym_close_session()

Changes since v2:
 According to Daniel's comments:
 - drop cryptodev kernel module as a cryptodev backend
 - rename crypto stuff to cryptodev stuff
 - change some files' license to GPLv2+
 - remove cryptodev command line instead of QOM to define the cryptodev backend
 - rename all functions and structures in crypto sub-directory.
 - add full inline documentation for cryptodev.h
 And:
 - drop crypto-queue.c [Paolo]
 - merge some patches

Great thanks to Daniel and Paolo. Please review again, thanks!

Changes since v1:
 - rmmove mixed endian-ness handler for virtio-crypto device, just
   use little-endian. [mst]
 - add sg list support according virtio-crypto spec v10 (will be posted soon).
 - fix a memory leak in session handler.
 - add a feature page link in qemu.org (http://qemu-project.org/Features/VirtioCrypto)
 - fix some trivial problems, sush as 's/Since 2.7/Since 2.8/g' in qapi-schema.json
 - rebase the latest qemu master tree.


This patch series realize the framework and emulation of a new
virtio crypto device, which is similar with virtio net device.
 
 - I introduce the cryptodev backend as the client of virtio crypto device
   which can be realized by different methods, such as cryptodev-backend-gcrypt in my series,
   vhost-crypto kernel module, vhost-user etc.
 - The patch set abides by the virtio crypto speccification.
 - The virtio crypto support symmetric algorithms (including CIPHER and algorithm chainning)
   at present, except HASH, MAC and AEAD services.
 - unsupport hot plug/unplug cryptodev backend at this moment.

Firstly build QEMU with libgcrypt cryptography support. 

QEMU can then be started using the following parameters:

qemu-system-x86_64 \
    [...] \
        -object cryptodev-backend-builtin,id=cryptodev0 \
        -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
    [...]

The front-end linux kernel driver (Experimental at present) is publicly accessible from:
 
   https://github.com/gongleiarei/virtio-crypto-linux-driver.git

After insmod virtio-crypto.ko, you can use cryptodev-linux test the crypto function
in the guest. For example:

linux-guest:/home/gonglei/cryptodev-linux/tests # ./cipher -
requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver virtio_crypto_aes_cbc
AES Test passed
requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver virtio_crypto_aes_cbc
requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver virtio_crypto_aes_cbc
Test passed

QEMU code also can be accessible from:

 https://github.com/gongleiarei/qemu.git 

 branch virtio-crypto

For more information, please see:
 http://qemu-project.org/Features/VirtioCrypto


Gonglei (12):
  cryptodev: introduce cryptodev backend interface
  cryptodev: add symmetric algorithm operation stuff
  virtio-crypto: introduce virtio_crypto.h
  cryptodev: introduce a new cryptodev backend
  virtio-crypto: add virtio crypto device emulation
  virtio-crypto-pci: add virtio crypto pci support
  virtio-crypto: set capacity of algorithms supported
  virtio-crypto: add control queue handler
  virtio-crypto: add data queue processing handler
  cryptodev: introduce an unified wrapper for crypto operation
  virtio-crypto: using bh to handle dataq's requests
  virtio-crypto: add myself as virtio-crypto and cryptodev backends
    maintainer

 MAINTAINERS                                    |  13 +
 backends/Makefile.objs                         |   3 +
 backends/cryptodev-builtin.c                   | 351 ++++++++++
 backends/cryptodev.c                           | 245 +++++++
 hw/virtio/Makefile.objs                        |   2 +
 hw/virtio/virtio-crypto-pci.c                  |  77 +++
 hw/virtio/virtio-crypto.c                      | 884 +++++++++++++++++++++++++
 hw/virtio/virtio-pci.h                         |  15 +
 include/hw/virtio/virtio-crypto.h              |  94 +++
 include/standard-headers/linux/virtio_crypto.h | 420 ++++++++++++
 include/standard-headers/linux/virtio_ids.h    |   2 +-
 include/sysemu/cryptodev.h                     | 295 +++++++++
 qemu-options.hx                                |  18 +
 13 files changed, 2418 insertions(+), 1 deletion(-)
 create mode 100644 backends/cryptodev-builtin.c
 create mode 100644 backends/cryptodev.c
 create mode 100644 hw/virtio/virtio-crypto-pci.c
 create mode 100644 hw/virtio/virtio-crypto.c
 create mode 100644 include/hw/virtio/virtio-crypto.h
 create mode 100644 include/standard-headers/linux/virtio_crypto.h
 create mode 100644 include/sysemu/cryptodev.h

-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 01/12] cryptodev: introduce cryptodev backend interface
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 02/12] cryptodev: add symmetric algorithm operation stuff Gonglei
                   ` (13 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

cryptodev backend interface is used to realize the active work for
virtual crypto device.

This patch only add the framework, doesn't include specific operations.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 backends/Makefile.objs     |   2 +
 backends/cryptodev.c       | 176 +++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/cryptodev.h | 145 +++++++++++++++++++++++++++++++++++++
 3 files changed, 323 insertions(+)
 create mode 100644 backends/cryptodev.c
 create mode 100644 include/sysemu/cryptodev.h

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 31a3a89..55bd43d 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -9,3 +9,5 @@ common-obj-$(CONFIG_TPM) += tpm.o
 
 common-obj-y += hostmem.o hostmem-ram.o
 common-obj-$(CONFIG_LINUX) += hostmem-file.o
+
+common-obj-y += cryptodev.o
diff --git a/backends/cryptodev.c b/backends/cryptodev.c
new file mode 100644
index 0000000..e8582cd
--- /dev/null
+++ b/backends/cryptodev.c
@@ -0,0 +1,176 @@
+/*
+ * QEMU Crypto Device Implementation
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/cryptodev.h"
+#include "hw/boards.h"
+#include "qapi/error.h"
+#include "qapi/visitor.h"
+#include "qapi-types.h"
+#include "qapi-visit.h"
+#include "qemu/config-file.h"
+#include "qom/object_interfaces.h"
+
+static QTAILQ_HEAD(, CryptoDevBackendClient) crypto_clients;
+
+
+CryptoDevBackendClient *
+cryptodev_backend_new_client(const char *model,
+                                    const char *name)
+{
+    CryptoDevBackendClient *cc;
+
+    cc = g_malloc0(sizeof(CryptoDevBackendClient));
+    cc->model = g_strdup(model);
+    if (name) {
+        cc->name = g_strdup(name);
+    }
+
+    QTAILQ_INSERT_TAIL(&crypto_clients, cc, next);
+
+    return cc;
+}
+
+void cryptodev_backend_free_client(
+                  CryptoDevBackendClient *cc)
+{
+    QTAILQ_REMOVE(&crypto_clients, cc, next);
+    g_free(cc->name);
+    g_free(cc->model);
+    g_free(cc->info_str);
+    g_free(cc);
+}
+
+void cryptodev_backend_cleanup(
+             CryptoDevBackend *backend,
+             Error **errp)
+{
+    CryptoDevBackendClass *bc =
+                  CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->cleanup) {
+        bc->cleanup(backend, errp);
+    }
+
+    backend->ready = false;
+}
+
+static void
+cryptodev_backend_get_queues(Object *obj, Visitor *v, const char *name,
+                             void *opaque, Error **errp)
+{
+    CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
+    uint32_t value = backend->conf.peers.queues;
+
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+cryptodev_backend_set_queues(Object *obj, Visitor *v, const char *name,
+                             void *opaque, Error **errp)
+{
+    CryptoDevBackend *backend = CRYPTODEV_BACKEND(obj);
+    Error *local_err = NULL;
+    uint32_t value;
+
+    visit_type_uint32(v, name, &value, &local_err);
+    if (local_err) {
+        goto out;
+    }
+    if (!value) {
+        error_setg(&local_err, "Property '%s.%s' doesn't take value '%"
+                   PRIu32 "'", object_get_typename(obj), name, value);
+        goto out;
+    }
+    backend->conf.peers.queues = value;
+out:
+    error_propagate(errp, local_err);
+}
+
+static void
+cryptodev_backend_complete(UserCreatable *uc, Error **errp)
+{
+    CryptoDevBackend *backend = CRYPTODEV_BACKEND(uc);
+    CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_GET_CLASS(uc);
+    Error *local_err = NULL;
+
+    if (bc->init) {
+        bc->init(backend, &local_err);
+        if (local_err) {
+            goto out;
+        }
+    }
+    backend->ready = true;
+    return;
+
+out:
+    backend->ready = false;
+    error_propagate(errp, local_err);
+}
+
+static void cryptodev_backend_instance_init(Object *obj)
+{
+    object_property_add(obj, "queues", "int",
+                          cryptodev_backend_get_queues,
+                          cryptodev_backend_set_queues,
+                          NULL, NULL, NULL);
+    /* Initialize devices' queues property to 1 */
+    object_property_set_int(obj, 1, "queues", NULL);
+}
+
+static void cryptodev_backend_finalize(Object *obj)
+{
+
+}
+
+static void
+cryptodev_backend_class_init(ObjectClass *oc, void *data)
+{
+    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+    ucc->complete = cryptodev_backend_complete;
+
+    QTAILQ_INIT(&crypto_clients);
+}
+
+static const TypeInfo cryptodev_backend_info = {
+    .name = TYPE_CRYPTODEV_BACKEND,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(CryptoDevBackend),
+    .instance_init = cryptodev_backend_instance_init,
+    .instance_finalize = cryptodev_backend_finalize,
+    .class_size = sizeof(CryptoDevBackendClass),
+    .class_init = cryptodev_backend_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+cryptodev_backend_register_types(void)
+{
+    type_register_static(&cryptodev_backend_info);
+}
+
+type_init(cryptodev_backend_register_types);
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
new file mode 100644
index 0000000..de9d3e3
--- /dev/null
+++ b/include/sysemu/cryptodev.h
@@ -0,0 +1,145 @@
+/*
+ * QEMU Crypto Device Implementation
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef CRYPTODEV_H
+#define CRYPTODEV_H
+
+#include "qom/object.h"
+#include "qemu-common.h"
+
+/**
+ * CryptoDevBackend:
+ *
+ * The CryptoDevBackend object is an interface
+ * for different cryptodev backends, which provides crypto
+ * operation wrapper.
+ *
+ */
+
+#define TYPE_CRYPTODEV_BACKEND "cryptodev-backend"
+
+#define CRYPTODEV_BACKEND(obj) \
+    OBJECT_CHECK(CryptoDevBackend, \
+                 (obj), TYPE_CRYPTODEV_BACKEND)
+#define CRYPTODEV_BACKEND_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(CryptoDevBackendClass, \
+                 (obj), TYPE_CRYPTODEV_BACKEND)
+#define CRYPTODEV_BACKEND_CLASS(klass) \
+    OBJECT_CLASS_CHECK(CryptoDevBackendClass, \
+                (klass), TYPE_CRYPTODEV_BACKEND)
+
+
+#define MAX_CRYPTO_QUEUE_NUM  64
+
+typedef struct CryptoDevBackendConf CryptoDevBackendConf;
+typedef struct CryptoDevBackendPeers CryptoDevBackendPeers;
+typedef struct CryptoDevBackendClient
+                     CryptoDevBackendClient;
+typedef struct CryptoDevBackend CryptoDevBackend;
+
+
+typedef struct CryptoDevBackendClass {
+    ObjectClass parent_class;
+
+    void (*init)(CryptoDevBackend *backend, Error **errp);
+    void (*cleanup)(CryptoDevBackend *backend, Error **errp);
+} CryptoDevBackendClass;
+
+
+struct CryptoDevBackendClient {
+    char *model;
+    char *name;
+    char *info_str;
+    unsigned int queue_index;
+    QTAILQ_ENTRY(CryptoDevBackendClient) next;
+};
+
+struct CryptoDevBackendPeers {
+    CryptoDevBackendClient *ccs[MAX_CRYPTO_QUEUE_NUM];
+    uint32_t queues;
+};
+
+struct CryptoDevBackendConf {
+    CryptoDevBackendPeers peers;
+
+    /* Supported service mask */
+    uint32_t crypto_services;
+
+    /* Detailed algorithms mask */
+    uint32_t cipher_algo_l;
+    uint32_t cipher_algo_h;
+    uint32_t hash_algo;
+    uint32_t mac_algo_l;
+    uint32_t mac_algo_h;
+    uint32_t asym_algo;
+    uint32_t kdf_algo;
+    uint32_t aead_algo;
+    uint32_t primitive_algo;
+};
+
+struct CryptoDevBackend {
+    Object parent_obj;
+
+    bool ready;
+    CryptoDevBackendConf conf;
+};
+
+/**
+ * cryptodev_backend_new_client:
+ * @model: the cryptodev backend model
+ * @name: the cryptodev backend name, can be NULL
+ *
+ * Creates a new cryptodev backend client object
+ * with the @name in the model @model.
+ *
+ * The returned object must be released with
+ * cryptodev_backend_free_client() when no
+ * longer required
+ *
+ * Returns: a new cryptodev backend client object
+ */
+CryptoDevBackendClient *
+cryptodev_backend_new_client(const char *model,
+                                    const char *name);
+/**
+ * cryptodev_backend_free_client:
+ * @cc: the cryptodev backend client object
+ *
+ * Release the memory associated with @cc that
+ * was previously allocated by cryptodev_backend_new_client()
+ */
+void cryptodev_backend_free_client(
+                  CryptoDevBackendClient *cc);
+
+/**
+ * cryptodev_backend_cleanup:
+ * @backend: the cryptodev backend object
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Clean the resouce associated with @backend that realizaed
+ * by the specific backend's init() callback
+ */
+void cryptodev_backend_cleanup(
+           CryptoDevBackend *backend,
+           Error **errp);
+
+#endif /* CRYPTODEV_H */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 02/12] cryptodev: add symmetric algorithm operation stuff
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 01/12] cryptodev: introduce cryptodev backend interface Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 03/12] virtio-crypto: introduce virtio_crypto.h Gonglei
                   ` (12 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

This patch adds session operation and crypto operation
stuff in the cryptodev backend, including function
pointers and corresponding structures.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 backends/cryptodev.c       |  45 ++++++++++++++
 include/sysemu/cryptodev.h | 149 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 194 insertions(+)

diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index e8582cd..47521cf 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -75,6 +75,51 @@ void cryptodev_backend_cleanup(
     backend->ready = false;
 }
 
+int64_t cryptodev_backend_sym_create_session(
+           CryptoDevBackend *backend,
+           CryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendClass *bc =
+                      CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->create_session) {
+        return bc->create_session(backend, sess_info, queue_index, errp);
+    }
+
+    return -1;
+}
+
+int cryptodev_backend_sym_close_session(
+           CryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendClass *bc =
+                      CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->close_session) {
+        return bc->close_session(backend, session_id, queue_index, errp);
+    }
+
+    return -1;
+}
+
+int cryptodev_backend_sym_operation(
+                 CryptoDevBackend *backend,
+                 CryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendClass *bc =
+                      CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->do_sym_op) {
+        return bc->do_sym_op(backend, op_info, queue_index, errp);
+    }
+
+    return -1;
+}
+
 static void
 cryptodev_backend_get_queues(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
index de9d3e3..e4510da 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -56,12 +56,111 @@ typedef struct CryptoDevBackendClient
                      CryptoDevBackendClient;
 typedef struct CryptoDevBackend CryptoDevBackend;
 
+enum CryptoDevBackendAlgType {
+    CRYPTODEV_BACKEND_ALG_SYM,
+    CRYPTODEV_BACKEND_ALG__MAX,
+};
+
+/**
+ * CryptoDevBackendSymSessionInfo:
+ *
+ * @op_code: operation code (refer to virtio_crypto.h)
+ * @cipher_alg: algorithm type of CIPHER
+ * @key_len: byte length of cipher key
+ * @hash_alg: algorithm type of HASH/MAC
+ * @hash_result_len: byte length of HASH operation result
+ * @auth_key_len: byte length of authenticated key
+ * @add_len: byte length of additional authenticated data
+ * @op_type: operation type (refer to virtio_crypto.h)
+ * @direction: encryption or direction for CIPHER
+ * @hash_mode: HASH mode for HASH operation (refer to virtio_crypto.h)
+ * @alg_chain_order: order of algorithm chaining (CIPHER then HASH,
+ *                   or HASH then CIPHER)
+ * @cipher_key: point to a key of CIPHER
+ * @auth_key: point to an authenticated key of MAC
+ *
+ */
+typedef struct CryptoDevBackendSymSessionInfo {
+    /* corresponding with virtio crypto spec */
+    uint32_t op_code;
+    uint32_t cipher_alg;
+    uint32_t key_len;
+    uint32_t hash_alg;
+    uint32_t hash_result_len;
+    uint32_t auth_key_len;
+    uint32_t add_len;
+    uint8_t op_type;
+    uint8_t direction;
+    uint8_t hash_mode;
+    uint8_t alg_chain_order;
+    uint8_t *cipher_key;
+    uint8_t *auth_key;
+} CryptoDevBackendSymSessionInfo;
+
+/**
+ * CryptoDevBackendSymOpInfo:
+ *
+ * @session_id: session index which was previously
+ *              created by cryptodev_backend_sym_create_session()
+ * @aad_len: byte length of additional authenticated data
+ * @iv_len: byte length of initialization vector or counter
+ * @src_len: byte length of source data
+ * @dst_len: byte length of destination data
+ * @digest_result_len: byte length of hash digest result
+ * @hash_start_src_offset: Starting point for hash processing, specified
+ *  as number of bytes from start of packet in source data, only used for
+ *  algorithm chain
+ * @cipher_start_src_offset: Starting point for cipher processing, specified
+ *  as number of bytes from start of packet in source data, only used for
+ *  algorithm chain
+ * @len_to_hash: byte length of source data on which the hash
+ *  operation will be computed, only used for algorithm chain
+ * @len_to_cipher: byte length of source data on which the cipher
+ *  operation will be computed, only used for algorithm chain
+ * @op_type: operation type (refer to virtio_crypto.h)
+ * @iv: point to the initialization vector or counter
+ * @src: point to the source data
+ * @dst: point to the destination data
+ * @aad_data: point to the additional authenticated data
+ * @digest_result: point to the digest result data
+ * @data[0]: point to the extensional memory by one memory allocation
+ *
+ */
+typedef struct CryptoDevBackendSymOpInfo {
+    uint64_t session_id;
+    uint32_t aad_len;
+    uint32_t iv_len;
+    uint32_t src_len;
+    uint32_t dst_len;
+    uint32_t digest_result_len;
+    uint32_t hash_start_src_offset;
+    uint32_t cipher_start_src_offset;
+    uint32_t len_to_hash;
+    uint32_t len_to_cipher;
+    uint8_t op_type;
+    uint8_t *iv;
+    uint8_t *src;
+    uint8_t *dst;
+    uint8_t *aad_data;
+    uint8_t *digest_result;
+    uint8_t data[0];
+} CryptoDevBackendSymOpInfo;
 
 typedef struct CryptoDevBackendClass {
     ObjectClass parent_class;
 
     void (*init)(CryptoDevBackend *backend, Error **errp);
     void (*cleanup)(CryptoDevBackend *backend, Error **errp);
+
+    int64_t (*create_session)(CryptoDevBackend *backend,
+                       CryptoDevBackendSymSessionInfo *sess_info,
+                       uint32_t queue_index, Error **errp);
+    int (*close_session)(CryptoDevBackend *backend,
+                           uint64_t session_id,
+                           uint32_t queue_index, Error **errp);
+    int (*do_sym_op)(CryptoDevBackend *backend,
+                     CryptoDevBackendSymOpInfo *op_info,
+                     uint32_t queue_index, Error **errp);
 } CryptoDevBackendClass;
 
 
@@ -142,4 +241,54 @@ void cryptodev_backend_cleanup(
            CryptoDevBackend *backend,
            Error **errp);
 
+/**
+ * cryptodev_backend_sym_create_session:
+ * @backend: the cryptodev backend object
+ * @sess_info: parameters needed by session creating
+ * @queue_index: queue index of cryptodev backend client
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Create a session for symmetric algorithms
+ *
+ * Returns: session id on success, or -1 on error
+ */
+int64_t cryptodev_backend_sym_create_session(
+           CryptoDevBackend *backend,
+           CryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp);
+
+/**
+ * cryptodev_backend_sym_close_session:
+ * @backend: the cryptodev backend object
+ * @session_id: the session id
+ * @queue_index: queue index of cryptodev backend client
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Close a session for symmetric algorithms which was previously
+ * created by cryptodev_backend_sym_create_session()
+ *
+ * Returns: 0 on success, or Negative on error
+ */
+int cryptodev_backend_sym_close_session(
+           CryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp);
+
+/**
+ * cryptodev_backend_sym_operation:
+ * @backend: the cryptodev backend object
+ * @op_info: parameters needed by symmetric crypto operation
+ * @queue_index: queue index of cryptodev backend client
+ * @errp: pointer to a NULL-initialized error object
+ *
+ * Do symmetric crypto operation, such as encryption and
+ * decryption
+ *
+ * Returns: 0 on success, or Negative on error
+ */
+int cryptodev_backend_sym_operation(
+                 CryptoDevBackend *backend,
+                 CryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp);
+
 #endif /* CRYPTODEV_H */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 03/12] virtio-crypto: introduce virtio_crypto.h
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 01/12] cryptodev: introduce cryptodev backend interface Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 02/12] cryptodev: add symmetric algorithm operation stuff Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 04/12] cryptodev: introduce a new cryptodev backend Gonglei
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Introduce the virtio_crypto.h which follows
virtio-crypto specification.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 include/standard-headers/linux/virtio_crypto.h | 420 +++++++++++++++++++++++++
 1 file changed, 420 insertions(+)
 create mode 100644 include/standard-headers/linux/virtio_crypto.h

diff --git a/include/standard-headers/linux/virtio_crypto.h b/include/standard-headers/linux/virtio_crypto.h
new file mode 100644
index 0000000..a9ed885
--- /dev/null
+++ b/include/standard-headers/linux/virtio_crypto.h
@@ -0,0 +1,420 @@
+#ifndef _LINUX_VIRTIO_CRYPTO_H
+#define _LINUX_VIRTIO_CRYPTO_H
+/* This header is BSD licensed so anyone can use the definitions to implement
+ * compatible drivers/servers.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of IBM nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL IBM OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE. */
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_types.h"
+
+
+#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
+#define VIRTIO_CRYPTO_SERVICE_HASH 1
+#define VIRTIO_CRYPTO_SERVICE_MAC  2
+#define VIRTIO_CRYPTO_SERVICE_AEAD 3
+
+#define VIRTIO_CRYPTO_OPCODE(service, op)   (((service) << 8) | (op))
+
+struct virtio_crypto_ctrl_header {
+#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
+#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
+#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
+#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
+#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
+#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
+#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
+#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
+       VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
+    __virtio32 opcode;
+    __virtio32 algo;
+    __virtio32 flag;
+    /* data virtqueue id */
+    __virtio32 queue_id;
+};
+
+struct virtio_crypto_cipher_session_para {
+#define VIRTIO_CRYPTO_NO_CIPHER                 0
+#define VIRTIO_CRYPTO_CIPHER_ARC4               1
+#define VIRTIO_CRYPTO_CIPHER_AES_ECB            2
+#define VIRTIO_CRYPTO_CIPHER_AES_CBC            3
+#define VIRTIO_CRYPTO_CIPHER_AES_CTR            4
+#define VIRTIO_CRYPTO_CIPHER_DES_ECB            5
+#define VIRTIO_CRYPTO_CIPHER_DES_CBC            6
+#define VIRTIO_CRYPTO_CIPHER_3DES_ECB           7
+#define VIRTIO_CRYPTO_CIPHER_3DES_CBC           8
+#define VIRTIO_CRYPTO_CIPHER_3DES_CTR           9
+#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8          10
+#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2        11
+#define VIRTIO_CRYPTO_CIPHER_AES_F8             12
+#define VIRTIO_CRYPTO_CIPHER_AES_XTS            13
+#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3           14
+    __virtio32 algo;
+    /* length of key */
+    __virtio32 keylen;
+
+#define VIRTIO_CRYPTO_OP_ENCRYPT  1
+#define VIRTIO_CRYPTO_OP_DECRYPT  2
+    /* encrypt or decrypt */
+    __virtio32 op;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_session_input {
+    /* Device-writable part */
+    __virtio64 session_id;
+    __virtio32 status;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_cipher_session_req {
+    struct virtio_crypto_cipher_session_para para;
+};
+
+struct virtio_crypto_hash_session_para {
+#define VIRTIO_CRYPTO_NO_HASH            0
+#define VIRTIO_CRYPTO_HASH_MD5           1
+#define VIRTIO_CRYPTO_HASH_SHA1          2
+#define VIRTIO_CRYPTO_HASH_SHA_224       3
+#define VIRTIO_CRYPTO_HASH_SHA_256       4
+#define VIRTIO_CRYPTO_HASH_SHA_384       5
+#define VIRTIO_CRYPTO_HASH_SHA_512       6
+#define VIRTIO_CRYPTO_HASH_SHA3_224      7
+#define VIRTIO_CRYPTO_HASH_SHA3_256      8
+#define VIRTIO_CRYPTO_HASH_SHA3_384      9
+#define VIRTIO_CRYPTO_HASH_SHA3_512      10
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128      11
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256      12
+    __virtio32 algo;
+    /* hash result length */
+    __virtio32 hash_result_len;
+};
+
+struct virtio_crypto_hash_create_session_req {
+    struct virtio_crypto_hash_session_para para;
+};
+
+struct virtio_crypto_mac_session_para {
+#define VIRTIO_CRYPTO_NO_MAC                       0
+#define VIRTIO_CRYPTO_MAC_HMAC_MD5                 1
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA1                2
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224             3
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256             4
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384             5
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512             6
+#define VIRTIO_CRYPTO_MAC_CMAC_3DES                25
+#define VIRTIO_CRYPTO_MAC_CMAC_AES                 26
+#define VIRTIO_CRYPTO_MAC_KASUMI_F9                27
+#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2              28
+#define VIRTIO_CRYPTO_MAC_GMAC_AES                 41
+#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH             42
+#define VIRTIO_CRYPTO_MAC_CBCMAC_AES               49
+#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9         50
+#define VIRTIO_CRYPTO_MAC_XCBC_AES                 53
+    __virtio32 algo;
+    /* hash result length */
+    __virtio32 hash_result_len;
+    /* length of authenticated key */
+    __virtio32 auth_key_len;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_mac_create_session_req {
+    struct virtio_crypto_mac_session_para para;
+};
+
+struct virtio_crypto_aead_session_para {
+#define VIRTIO_CRYPTO_NO_AEAD     0
+#define VIRTIO_CRYPTO_AEAD_GCM    1
+#define VIRTIO_CRYPTO_AEAD_CCM    2
+#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305  3
+    __virtio32 algo;
+    /* length of key */
+    __virtio32 key_len;
+    /* digest result length */
+    __virtio32 digest_result_len;
+    /* length of the additional authenticated data (AAD) in bytes */
+    __virtio32 aad_len;
+    /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
+    __virtio32 op;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_aead_create_session_req {
+    struct virtio_crypto_aead_session_para para;
+};
+
+struct virtio_crypto_alg_chain_session_para {
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER  1
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH  2
+    __virtio32 alg_chain_order;
+/* Plain hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN    1
+/* Authenticated hash (mac) */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH     2
+/* Nested hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED   3
+    __virtio32 hash_mode;
+    struct virtio_crypto_cipher_session_para cipher_param;
+    union {
+        struct virtio_crypto_hash_session_para hash_param;
+        struct virtio_crypto_mac_session_para mac_param;
+    } u;
+    /* length of the additional authenticated data (AAD) in bytes */
+    __virtio32 aad_len;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_alg_chain_session_req {
+    struct virtio_crypto_alg_chain_session_para para;
+};
+
+struct virtio_crypto_sym_create_session_req {
+    union {
+        struct virtio_crypto_cipher_session_req cipher;
+        struct virtio_crypto_alg_chain_session_req chain;
+    } u;
+
+    /* Device-readable part */
+
+/* No operation */
+#define VIRTIO_CRYPTO_SYM_OP_NONE  0
+/* Cipher only operation on the data */
+#define VIRTIO_CRYPTO_SYM_OP_CIPHER  1
+/* Chain any cipher with any hash or mac operation. The order
+   depends on the value of alg_chain_order param */
+#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING  2
+    __virtio32 op_type;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_destroy_session_req {
+    /* Device-readable part */
+    __virtio64  session_id;
+};
+
+/* The request of the control viritqueue's packet */
+struct virtio_crypto_op_ctrl_req {
+    struct virtio_crypto_ctrl_header header;
+
+    union {
+        struct virtio_crypto_sym_create_session_req   sym_create_session;
+        struct virtio_crypto_hash_create_session_req  hash_create_session;
+        struct virtio_crypto_mac_create_session_req   mac_create_session;
+        struct virtio_crypto_aead_create_session_req  aead_create_session;
+        struct virtio_crypto_destroy_session_req      destroy_session;
+    } u;
+};
+
+struct virtio_crypto_op_header {
+#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
+#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
+#define VIRTIO_CRYPTO_HASH \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
+#define VIRTIO_CRYPTO_MAC \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
+#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
+#define VIRTIO_CRYPTO_AEAD_DECRYPT \
+    VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
+    __virtio32 opcode;
+    /* algo should be service-specific algorithms */
+    __virtio32 algo;
+    /* session_id should be service-specific algorithms */
+    __virtio64 session_id;
+    /* control flag to control the request */
+    __virtio32 flag;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_cipher_para {
+    /*
+     * Byte Length of valid IV/Counter
+     *
+     * - For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
+     *   SNOW3G in UEA2 mode, this is the length of the IV (which
+     *   must be the same as the block length of the cipher).
+     * - For block ciphers in CTR mode, this is the length of the counter
+     *   (which must be the same as the block length of the cipher).
+     * - For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
+     *
+     * The IV/Counter will be updated after every partial cryptographic
+     * operation.
+     */
+    __virtio32 iv_len;
+    /* length of source data */
+    __virtio32 src_data_len;
+    /* length of dst data */
+    __virtio32 dst_data_len;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_hash_para {
+    /* length of source data */
+    __virtio32 src_data_len;
+    /* hash result length */
+    __virtio32 hash_result_len;
+};
+
+struct virtio_crypto_mac_para {
+    struct virtio_crypto_hash_para hash;
+};
+
+struct virtio_crypto_aead_para {
+    /*
+     * Byte Length of valid IV data pointed to by the below iv_addr
+     * parameter.
+     *
+     * - For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
+     *   case iv_addr points to J0.
+     * - For CCM mode, this is the length of the nonce, which can be in the
+     *   range 7 to 13 inclusive.
+     */
+    __virtio32 iv_len;
+    /* length of additional auth data */
+    __virtio32 aad_len;
+    /* length of source data */
+    __virtio32 src_data_len;
+    /* length of dst data */
+    __virtio32 dst_data_len;
+};
+
+struct virtio_crypto_cipher_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_para para;
+};
+
+struct virtio_crypto_hash_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_hash_para para;
+};
+
+struct virtio_crypto_mac_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_para para;
+};
+
+struct virtio_crypto_alg_chain_data_para {
+    __virtio32 iv_len;
+    /* Length of source data */
+    __virtio32 src_data_len;
+    /* Length of destination data */
+    __virtio32 dst_data_len;
+    /* Starting point for cipher processing in source data */
+    __virtio32 cipher_start_src_offset;
+    /* Length of the source data that the cipher will be computed on */
+    __virtio32 len_to_cipher;
+    /* Starting point for hash processing in source data */
+    __virtio32 hash_start_src_offset;
+    /* Length of the source data that the hash will be computed on */
+    __virtio32 len_to_hash;
+    /* Length of the additional auth data */
+    __virtio32 aad_len;
+    /* Length of the hash result */
+    __virtio32 hash_result_len;
+    __virtio32 reserved;
+};
+
+struct virtio_crypto_alg_chain_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_data_para para;
+};
+
+struct virtio_crypto_sym_data_req {
+    union {
+        struct virtio_crypto_cipher_data_req cipher;
+        struct virtio_crypto_alg_chain_data_req chain;
+    } u;
+
+    /* See above VIRTIO_CRYPTO_SYM_OP_* */
+    __virtio32 op_type;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_aead_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_aead_para para;
+};
+
+/* The request of the data viritqueue's packet */
+struct virtio_crypto_op_data_req {
+    struct virtio_crypto_op_header header;
+
+    union {
+        struct virtio_crypto_sym_data_req  sym_req;
+        struct virtio_crypto_hash_data_req hash_req;
+        struct virtio_crypto_mac_data_req mac_req;
+        struct virtio_crypto_aead_data_req aead_req;
+    } u;
+};
+
+#define VIRTIO_CRYPTO_OK        0
+#define VIRTIO_CRYPTO_ERR       1
+#define VIRTIO_CRYPTO_BADMSG    2
+#define VIRTIO_CRYPTO_NOTSUPP   3
+#define VIRTIO_CRYPTO_INVSESS   4 /* Invaild session id */
+
+/* The accelerator hardware is ready */
+#define VIRTIO_CRYPTO_S_HW_READY  (1 << 0)
+#define VIRTIO_CRYPTO_S_STARTED  (1 << 1)
+
+struct virtio_crypto_config {
+    /* See VIRTIO_CRYPTO_* above */
+    __virtio32  status;
+
+    /*
+     * Maximum number of data queue legal values are between 1 and 0x8000
+     */
+    __virtio32  max_dataqueues;
+
+    /* Specifies the services mask which the devcie support,
+       see VIRTIO_CRYPTO_SERVICE_* above */
+    __virtio32 crypto_services;
+
+    /* Detailed algorithms mask */
+    __virtio32 cipher_algo_l;
+    __virtio32 cipher_algo_h;
+    __virtio32 hash_algo;
+    __virtio32 mac_algo_l;
+    __virtio32 mac_algo_h;
+    __virtio32 aead_algo;
+    __virtio32 reserve;
+};
+
+struct virtio_crypto_inhdr {
+    /* See VIRTIO_CRYPTO_* above */
+    uint8_t status;
+};
+
+#endif /* _LINUX_VIRTIO_CRYPTO_H */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 04/12] cryptodev: introduce a new cryptodev backend
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (2 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 03/12] virtio-crypto: introduce virtio_crypto.h Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 05/12] virtio-crypto: add virtio crypto device emulation Gonglei
                   ` (10 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

The new cryptodev backend named cryptodev-builtin,
which realized by QEMU cipher APIs. These APIs can
be backed by either nettle or gcrypt.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 backends/Makefile.objs       |   1 +
 backends/cryptodev-builtin.c | 351 +++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx              |  18 +++
 3 files changed, 370 insertions(+)
 create mode 100644 backends/cryptodev-builtin.c

diff --git a/backends/Makefile.objs b/backends/Makefile.objs
index 55bd43d..1846998 100644
--- a/backends/Makefile.objs
+++ b/backends/Makefile.objs
@@ -11,3 +11,4 @@ common-obj-y += hostmem.o hostmem-ram.o
 common-obj-$(CONFIG_LINUX) += hostmem-file.o
 
 common-obj-y += cryptodev.o
+common-obj-y += cryptodev-builtin.o
diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
new file mode 100644
index 0000000..9ad79ad
--- /dev/null
+++ b/backends/cryptodev-builtin.c
@@ -0,0 +1,351 @@
+/*
+ * QEMU Cryptodev backend for QEMU cipher APIs
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/cryptodev.h"
+#include "hw/boards.h"
+#include "qapi/error.h"
+#include "standard-headers/linux/virtio_crypto.h"
+#include "crypto/cipher.h"
+
+
+/**
+ * @TYPE_CRYPTODEV_BACKEND_BUILTIN:
+ * name of backend that uses QEMU cipher API
+ */
+#define TYPE_CRYPTODEV_BACKEND_BUILTIN "cryptodev-backend-builtin"
+
+#define CRYPTODEV_BACKEND_BUILTIN(obj) \
+    OBJECT_CHECK(CryptoDevBackendBuiltin, \
+                 (obj), TYPE_CRYPTODEV_BACKEND_BUILTIN)
+
+typedef struct CryptoDevBackendBuiltin
+                         CryptoDevBackendBuiltin;
+
+typedef struct CryptoDevBackendBuiltinSession {
+    QCryptoCipher *cipher;
+    uint8_t direction; /* encryption or decryption */
+    uint8_t type; /* cipher? hash? aead? */
+    QTAILQ_ENTRY(CryptoDevBackendBuiltinSession) next;
+} CryptoDevBackendBuiltinSession;
+
+/* Max number of symmetric sessions */
+#define MAX_NUM_SESSIONS 256
+
+
+struct CryptoDevBackendBuiltin {
+    CryptoDevBackend parent_obj;
+
+    CryptoDevBackendBuiltinSession *sessions[MAX_NUM_SESSIONS];
+};
+
+static void cryptodev_builtin_init(
+             CryptoDevBackend *backend, Error **errp)
+{
+    /* Only support one queue */
+    int queues = backend->conf.peers.queues;
+    CryptoDevBackendClient *cc;
+
+    if (queues != 1) {
+        error_setg(errp,
+                  "Only support one queue in cryptdov-builtin backend");
+        return;
+    }
+
+    cc = cryptodev_backend_new_client(
+              "cryptodev-builtin", NULL);
+    cc->info_str = g_strdup_printf("cryptodev-builtin0");
+    cc->queue_index = 0;
+    backend->conf.peers.ccs[0] = cc;
+
+    backend->conf.crypto_services =
+                         1u << VIRTIO_CRYPTO_SERVICE_CIPHER |
+                         1u << VIRTIO_CRYPTO_SERVICE_HASH |
+                         1u << VIRTIO_CRYPTO_SERVICE_MAC;
+    backend->conf.cipher_algo_l = 1u << VIRTIO_CRYPTO_CIPHER_AES_CBC;
+    backend->conf.hash_algo = 1u << VIRTIO_CRYPTO_HASH_SHA1;
+}
+
+static int
+cryptodev_builtin_get_unused_session_index(
+                 CryptoDevBackendBuiltin *builtin)
+{
+    size_t i;
+
+    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
+        if (builtin->sessions[i] == NULL) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static int
+cryptodev_builtin_get_aes_algo(uint32_t key_len, Error **errp)
+{
+    int algo;
+
+    if (key_len == 128 / 8) {
+        algo = QCRYPTO_CIPHER_ALG_AES_128;
+    } else if (key_len == 192 / 8) {
+        algo = QCRYPTO_CIPHER_ALG_AES_192;
+    } else if (key_len == 256 / 8) {
+        algo = QCRYPTO_CIPHER_ALG_AES_256;
+    } else {
+        error_setg(errp, "Unsupported key length :%u", key_len);
+        return -1;
+    }
+
+    return algo;
+}
+
+static int cryptodev_builtin_create_cipher_session(
+                    CryptoDevBackendBuiltin *builtin,
+                    CryptoDevBackendSymSessionInfo *sess_info,
+                    Error **errp)
+{
+    int algo;
+    int mode;
+    QCryptoCipher *cipher;
+    int index;
+    CryptoDevBackendBuiltinSession *sess;
+
+    if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        error_setg(errp, "Unsupported optype :%u", sess_info->op_type);
+        return -1;
+    }
+
+    index = cryptodev_builtin_get_unused_session_index(builtin);
+    if (index < 0) {
+        error_setg(errp, "Total number of sessions created exceeds %u",
+                  MAX_NUM_SESSIONS);
+        return -1;
+    }
+
+    switch (sess_info->cipher_alg) {
+    case VIRTIO_CRYPTO_CIPHER_AES_ECB:
+        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_ECB;
+        break;
+    case VIRTIO_CRYPTO_CIPHER_AES_CBC:
+        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_CBC;
+        break;
+    case VIRTIO_CRYPTO_CIPHER_AES_CTR:
+        algo = cryptodev_builtin_get_aes_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_CTR;
+        break;
+    case VIRTIO_CRYPTO_CIPHER_DES_ECB:
+        algo = QCRYPTO_CIPHER_ALG_DES_RFB;
+        mode = QCRYPTO_CIPHER_MODE_ECB;
+        break;
+    default:
+        error_setg(errp, "Unsupported cipher alg :%u",
+                   sess_info->cipher_alg);
+        return -1;
+    }
+
+    cipher = qcrypto_cipher_new(algo, mode,
+                               sess_info->cipher_key,
+                               sess_info->key_len,
+                               errp);
+    if (!cipher) {
+        return -1;
+    }
+
+    sess = g_new0(CryptoDevBackendBuiltinSession, 1);
+    sess->cipher = cipher;
+    sess->direction = sess_info->direction;
+    sess->type = sess_info->op_type;
+
+    builtin->sessions[index] = sess;
+
+    return index;
+}
+
+static int64_t cryptodev_builtin_sym_create_session(
+           CryptoDevBackend *backend,
+           CryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendBuiltin *builtin =
+                      CRYPTODEV_BACKEND_BUILTIN(backend);
+    int64_t session_id = -1;
+    int ret;
+
+    switch (sess_info->op_code) {
+    case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+        ret = cryptodev_builtin_create_cipher_session(
+                           builtin, sess_info, errp);
+        if (ret < 0) {
+            return ret;
+        } else {
+            session_id = ret;
+        }
+        break;
+    case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
+    case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
+    default:
+        error_setg(errp, "Unsupported opcode :%" PRIu32 "",
+                   sess_info->op_code);
+        return -1;
+    }
+
+    return session_id;
+}
+
+static int cryptodev_builtin_sym_close_session(
+           CryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendBuiltin *builtin =
+                      CRYPTODEV_BACKEND_BUILTIN(backend);
+
+    if (session_id >= MAX_NUM_SESSIONS ||
+              builtin->sessions[session_id] == NULL) {
+        error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
+                      session_id);
+        return -1;
+    }
+
+    qcrypto_cipher_free(builtin->sessions[session_id]->cipher);
+    g_free(builtin->sessions[session_id]);
+    builtin->sessions[session_id] = NULL;
+    return 0;
+}
+
+static int cryptodev_builtin_sym_operation(
+                 CryptoDevBackend *backend,
+                 CryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp)
+{
+    CryptoDevBackendBuiltin *builtin =
+                      CRYPTODEV_BACKEND_BUILTIN(backend);
+    CryptoDevBackendBuiltinSession *sess;
+    int ret;
+
+    if (op_info->session_id >= MAX_NUM_SESSIONS ||
+              builtin->sessions[op_info->session_id] == NULL) {
+        error_setg(errp, "Cannot find a valid session id: %" PRIu64 "",
+                   op_info->session_id);
+        return -VIRTIO_CRYPTO_INVSESS;
+    }
+
+    if (op_info->op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        error_setg(errp,
+               "Algorithm chain is unsupported for cryptdoev-builtin");
+        return -VIRTIO_CRYPTO_NOTSUPP;
+    }
+
+    sess = builtin->sessions[op_info->session_id];
+
+    ret = qcrypto_cipher_setiv(sess->cipher, op_info->iv,
+                               op_info->iv_len, errp);
+    if (ret < 0) {
+        return -VIRTIO_CRYPTO_ERR;
+    }
+
+    if (sess->direction == VIRTIO_CRYPTO_OP_ENCRYPT) {
+        ret = qcrypto_cipher_encrypt(sess->cipher, op_info->src,
+                                     op_info->dst, op_info->src_len, errp);
+        if (ret < 0) {
+            return -VIRTIO_CRYPTO_ERR;
+        }
+    } else {
+        ret = qcrypto_cipher_decrypt(sess->cipher, op_info->src,
+                                     op_info->dst, op_info->src_len, errp);
+        if (ret < 0) {
+            return -VIRTIO_CRYPTO_ERR;
+        }
+    }
+    return VIRTIO_CRYPTO_OK;
+}
+
+static void cryptodev_builtin_cleanup(
+             CryptoDevBackend *backend,
+             Error **errp)
+{
+    CryptoDevBackendBuiltin *builtin =
+                      CRYPTODEV_BACKEND_BUILTIN(backend);
+    size_t i;
+    int queues = backend->conf.peers.queues;
+    CryptoDevBackendClient *cc;
+
+    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
+        if (builtin->sessions[i] != NULL) {
+            cryptodev_builtin_sym_close_session(
+                    backend, i, 0, errp);
+        }
+    }
+
+    assert(queues == 1);
+
+    for (i = 0; i < queues; i++) {
+        cc = backend->conf.peers.ccs[i];
+        if (cc) {
+            cryptodev_backend_free_client(cc);
+            backend->conf.peers.ccs[i] = NULL;
+        }
+    }
+}
+
+static void
+cryptodev_builtin_class_init(ObjectClass *oc, void *data)
+{
+    CryptoDevBackendClass *bc = CRYPTODEV_BACKEND_CLASS(oc);
+
+    bc->init = cryptodev_builtin_init;
+    bc->cleanup = cryptodev_builtin_cleanup;
+    bc->create_session = cryptodev_builtin_sym_create_session;
+    bc->close_session = cryptodev_builtin_sym_close_session;
+    bc->do_sym_op = cryptodev_builtin_sym_operation;
+}
+
+static const TypeInfo cryptodev_builtin_info = {
+    .name = TYPE_CRYPTODEV_BACKEND_BUILTIN,
+    .parent = TYPE_CRYPTODEV_BACKEND,
+    .class_init = cryptodev_builtin_class_init,
+    .instance_size = sizeof(CryptoDevBackendBuiltin),
+};
+
+static void
+cryptodev_builtin_register_types(void)
+{
+    type_register_static(&cryptodev_builtin_info);
+}
+
+type_init(cryptodev_builtin_register_types);
diff --git a/qemu-options.hx b/qemu-options.hx
index b1fbdb0..66f1d28 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -3948,6 +3948,24 @@ secondary:
 If you want to know the detail of above command line, you can read
 the colo-compare git log.
 
+@item -object cryptodev-backend-builtin,id=@var{id}[,queues=@var{queues}]
+
+Creates a cryptodev backend which executes crypto opreation from
+the QEMU cipher APIS. The @var{id} parameter is
+a unique ID that will be used to reference this cryptodev backend from
+the @option{virtio-crypto} device. The @var{queues} parameter is optional,
+which specify the queue number of cryptodev backend, the default of
+@var{queues} is 1.
+
+@example
+
+ # qemu-system-x86_64 \
+   [...] \
+       -object cryptodev-backend-builtin,id=cryptodev0 \
+       -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
+   [...]
+@end example
+
 @item -object secret,id=@var{id},data=@var{string},format=@var{raw|base64}[,keyid=@var{secretid},iv=@var{string}]
 @item -object secret,id=@var{id},file=@var{filename},format=@var{raw|base64}[,keyid=@var{secretid},iv=@var{string}]
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 05/12] virtio-crypto: add virtio crypto device emulation
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (3 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 04/12] cryptodev: introduce a new cryptodev backend Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 06/12] virtio-crypto-pci: add virtio crypto pci support Gonglei
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Introduce the virtio crypto realization, I'll
finish the core code in the following patches. The
thoughts came from virtio net realization.

For more information see:
http://qemu-project.org/Features/VirtioCrypto

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/Makefile.objs                     |   1 +
 hw/virtio/virtio-crypto.c                   | 151 ++++++++++++++++++++++++++++
 include/hw/virtio/virtio-crypto.h           |  73 ++++++++++++++
 include/standard-headers/linux/virtio_ids.h |   2 +-
 4 files changed, 226 insertions(+), 1 deletion(-)
 create mode 100644 hw/virtio/virtio-crypto.c
 create mode 100644 include/hw/virtio/virtio-crypto.h

diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index e716308..968f392 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -7,3 +7,4 @@ obj-y += virtio.o virtio-balloon.o
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
 
 obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
+obj-y += virtio-crypto.o
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
new file mode 100644
index 0000000..109a504
--- /dev/null
+++ b/hw/virtio/virtio-crypto.c
@@ -0,0 +1,151 @@
+/*
+ * Virtio crypto Support
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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 "qemu/iov.h"
+#include "hw/qdev.h"
+#include "qapi/error.h"
+#include "qemu/error-report.h"
+
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-crypto.h"
+#include "hw/virtio/virtio-access.h"
+#include "standard-headers/linux/virtio_ids.h"
+
+#define VIRTIO_CRYPTO_VM_VERSION 1
+
+static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
+                                           uint64_t features,
+                                           Error **errp)
+{
+    return features;
+}
+
+static void virtio_crypto_reset(VirtIODevice *vdev)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+    /* multiqueue is disabled by default */
+    vcrypto->curr_queues = 1;
+    if (!vcrypto->cryptodev->ready) {
+        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
+    } else {
+        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
+    }
+}
+
+static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
+    int i;
+
+    vcrypto->cryptodev = vcrypto->conf.cryptodev;
+    if (vcrypto->cryptodev == NULL) {
+        error_setg(errp, "'cryptodev' parameter expects a valid object");
+        return;
+    }
+
+    vcrypto->max_queues = MAX(vcrypto->cryptodev->conf.peers.queues, 1);
+    if (vcrypto->max_queues + 1 > VIRTIO_QUEUE_MAX) {
+        error_setg(errp, "Invalid number of queues (= %" PRIu16 "), "
+                   "must be a postive integer less than %d.",
+                   vcrypto->max_queues, VIRTIO_QUEUE_MAX);
+        return;
+    }
+
+    virtio_init(vdev, "virtio-crypto", VIRTIO_ID_CRYPTO, vcrypto->config_size);
+    vcrypto->curr_queues = 1;
+
+    for (i = 0; i < vcrypto->max_queues; i++) {
+        virtio_add_queue(vdev, 1024, NULL);
+    }
+
+    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, NULL);
+    if (!vcrypto->cryptodev->ready) {
+        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
+    } else {
+        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
+    }
+}
+
+static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+
+    virtio_cleanup(vdev);
+}
+
+static const VMStateDescription vmstate_virtio_crypto = {
+    .name = "virtio-crypto",
+    .minimum_version_id = VIRTIO_CRYPTO_VM_VERSION,
+    .version_id = VIRTIO_CRYPTO_VM_VERSION,
+    .fields = (VMStateField[]) {
+        VMSTATE_VIRTIO_DEVICE,
+        VMSTATE_END_OF_LIST()
+    },
+};
+
+static Property virtio_crypto_properties[] = {
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
+{
+
+}
+
+static void virtio_crypto_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);
+
+    dc->props = virtio_crypto_properties;
+    dc->vmsd = &vmstate_virtio_crypto;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    vdc->realize = virtio_crypto_device_realize;
+    vdc->unrealize = virtio_crypto_device_unrealize;
+    vdc->get_config = virtio_crypto_get_config;
+    vdc->get_features = virtio_crypto_get_features;
+    vdc->reset = virtio_crypto_reset;
+}
+
+static void virtio_crypto_instance_init(Object *obj)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(obj);
+
+    /*
+     * The default config_size is sizeof(struct virtio_crypto_config).
+     * Can be overriden with virtio_crypto_set_config_size.
+     */
+    vcrypto->config_size = sizeof(struct virtio_crypto_config);
+
+    object_property_add_link(obj, "cryptodev",
+                             TYPE_CRYPTODEV_BACKEND,
+                             (Object **)&vcrypto->conf.cryptodev,
+                             qdev_prop_allow_set_link_before_realize,
+                             OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);
+}
+
+static const TypeInfo virtio_crypto_info = {
+    .name = TYPE_VIRTIO_CRYPTO,
+    .parent = TYPE_VIRTIO_DEVICE,
+    .instance_size = sizeof(VirtIOCrypto),
+    .instance_init = virtio_crypto_instance_init,
+    .class_init = virtio_crypto_class_init,
+};
+
+static void virtio_register_types(void)
+{
+    type_register_static(&virtio_crypto_info);
+}
+
+type_init(virtio_register_types)
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
new file mode 100644
index 0000000..4652c21
--- /dev/null
+++ b/include/hw/virtio/virtio-crypto.h
@@ -0,0 +1,73 @@
+/*
+ * Virtio crypto Support
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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.
+ */
+
+#ifndef _QEMU_VIRTIO_CRYPTO_H
+#define _QEMU_VIRTIO_CRYPTO_H
+
+#include "standard-headers/linux/virtio_crypto.h"
+#include "hw/virtio/virtio.h"
+#include "sysemu/iothread.h"
+#include "sysemu/cryptodev.h"
+
+
+#define DEBUG_VIRTIO_CRYPTO 0
+
+#define DPRINTF(fmt, ...) \
+do { \
+    if (DEBUG_VIRTIO_CRYPTO) { \
+        fprintf(stderr, "virtio_crypto: " fmt, ##__VA_ARGS__); \
+    } \
+} while (0)
+
+
+#define TYPE_VIRTIO_CRYPTO "virtio-crypto-device"
+#define VIRTIO_CRYPTO(obj) \
+        OBJECT_CHECK(VirtIOCrypto, (obj), TYPE_VIRTIO_CRYPTO)
+#define VIRTIO_CRYPTO_GET_PARENT_CLASS(obj) \
+        OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_CRYPTO)
+
+
+typedef struct VirtIOCryptoConf {
+    CryptoDevBackend *cryptodev;
+} VirtIOCryptoConf;
+
+struct VirtIOCrypto;
+
+typedef struct VirtIOCryptoReq {
+    VirtQueueElement elem;
+    /* flags of operation, such as type of algorithm */
+    uint32_t flags;
+    VirtQueue *vq;
+    struct VirtIOCrypto *vcrypto;
+    union {
+        CryptoDevBackendSymOpInfo *sym_op_info;
+    } u;
+} VirtIOCryptoReq;
+
+typedef struct VirtIOCrypto {
+    VirtIODevice parent_obj;
+
+    VirtQueue *ctrl_vq;
+
+    VirtIOCryptoConf conf;
+    CryptoDevBackend *cryptodev;
+
+    uint32_t max_queues;
+    uint32_t status;
+
+    int multiqueue;
+    uint32_t curr_queues;
+    size_t config_size;
+} VirtIOCrypto;
+
+#endif /* _QEMU_VIRTIO_CRYPTO_H */
diff --git a/include/standard-headers/linux/virtio_ids.h b/include/standard-headers/linux/virtio_ids.h
index 3228d58..fe74e42 100644
--- a/include/standard-headers/linux/virtio_ids.h
+++ b/include/standard-headers/linux/virtio_ids.h
@@ -42,5 +42,5 @@
 #define VIRTIO_ID_GPU          16 /* virtio GPU */
 #define VIRTIO_ID_INPUT        18 /* virtio input */
 #define VIRTIO_ID_VSOCK        19 /* virtio vsock transport */
-
+#define VIRTIO_ID_CRYPTO       20 /* virtio crypto */
 #endif /* _LINUX_VIRTIO_IDS_H */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 06/12] virtio-crypto-pci: add virtio crypto pci support
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (4 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 05/12] virtio-crypto: add virtio crypto device emulation Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 07/12] virtio-crypto: set capacity of algorithms supported Gonglei
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

This patch adds virtio-crypto-pci, which is the pci proxy for the virtio
crypto device.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/Makefile.objs       |  1 +
 hw/virtio/virtio-crypto-pci.c | 77 +++++++++++++++++++++++++++++++++++++++++++
 hw/virtio/virtio-pci.h        | 15 +++++++++
 3 files changed, 93 insertions(+)
 create mode 100644 hw/virtio/virtio-crypto-pci.c

diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index 968f392..95c4c30 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -8,3 +8,4 @@ obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
 
 obj-$(CONFIG_VHOST_VSOCK) += vhost-vsock.o
 obj-y += virtio-crypto.o
+obj-$(CONFIG_VIRTIO_PCI) += virtio-crypto-pci.o
diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c
new file mode 100644
index 0000000..21d9984
--- /dev/null
+++ b/hw/virtio/virtio-crypto-pci.c
@@ -0,0 +1,77 @@
+/*
+ * Virtio crypto device
+ *
+ * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
+ *
+ * Authors:
+ *    Gonglei <arei.gonglei@huawei.com>
+ *
+ * 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 "hw/pci/pci.h"
+#include "hw/virtio/virtio.h"
+#include "hw/virtio/virtio-bus.h"
+#include "hw/virtio/virtio-pci.h"
+#include "hw/virtio/virtio-crypto.h"
+#include "qapi/error.h"
+
+static Property virtio_crypto_pci_properties[] = {
+    DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags,
+                    VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
+    DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void virtio_crypto_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
+{
+    VirtIOCryptoPCI *vcrypto = VIRTIO_CRYPTO_PCI(vpci_dev);
+    DeviceState *vdev = DEVICE(&vcrypto->vdev);
+
+    qdev_set_parent_bus(vdev, BUS(&vpci_dev->bus));
+    virtio_pci_force_virtio_1(vpci_dev);
+    object_property_set_bool(OBJECT(vdev), true, "realized", errp);
+    object_property_set_link(OBJECT(vcrypto),
+                 OBJECT(vcrypto->vdev.conf.cryptodev), "cryptodev",
+                 NULL);
+}
+
+static void virtio_crypto_pci_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
+    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);
+
+    k->realize = virtio_crypto_pci_realize;
+    set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+    dc->props = virtio_crypto_pci_properties;
+
+    pcidev_k->class_id = PCI_CLASS_OTHERS;
+}
+
+static void virtio_crypto_initfn(Object *obj)
+{
+    VirtIOCryptoPCI *dev = VIRTIO_CRYPTO_PCI(obj);
+
+    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
+                                TYPE_VIRTIO_CRYPTO);
+    object_property_add_alias(obj, "cryptodev", OBJECT(&dev->vdev),
+                              "cryptodev", &error_abort);
+}
+
+static const TypeInfo virtio_crypto_pci_info = {
+    .name          = TYPE_VIRTIO_CRYPTO_PCI,
+    .parent        = TYPE_VIRTIO_PCI,
+    .instance_size = sizeof(VirtIOCryptoPCI),
+    .instance_init = virtio_crypto_initfn,
+    .class_init    = virtio_crypto_pci_class_init,
+};
+
+static void virtio_crypto_pci_register_types(void)
+{
+    type_register_static(&virtio_crypto_pci_info);
+}
+type_init(virtio_crypto_pci_register_types)
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index b4edea6..27801f0 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -25,6 +25,8 @@
 #include "hw/virtio/virtio-bus.h"
 #include "hw/virtio/virtio-input.h"
 #include "hw/virtio/virtio-gpu.h"
+#include "hw/virtio/virtio-crypto.h"
+
 #ifdef CONFIG_VIRTFS
 #include "hw/9pfs/virtio-9p.h"
 #endif
@@ -48,6 +50,7 @@ typedef struct VirtIOInputHIDPCI VirtIOInputHIDPCI;
 typedef struct VirtIOInputHostPCI VirtIOInputHostPCI;
 typedef struct VirtIOGPUPCI VirtIOGPUPCI;
 typedef struct VHostVSockPCI VHostVSockPCI;
+typedef struct VirtIOCryptoPCI VirtIOCryptoPCI;
 
 /* virtio-pci-bus */
 
@@ -352,6 +355,18 @@ struct VHostVSockPCI {
 };
 #endif
 
+/*
+ * virtio-crypto-pci: This extends VirtioPCIProxy.
+ */
+#define TYPE_VIRTIO_CRYPTO_PCI "virtio-crypto-pci"
+#define VIRTIO_CRYPTO_PCI(obj) \
+        OBJECT_CHECK(VirtIOCryptoPCI, (obj), TYPE_VIRTIO_CRYPTO_PCI)
+
+struct VirtIOCryptoPCI {
+    VirtIOPCIProxy parent_obj;
+    VirtIOCrypto vdev;
+};
+
 /* Virtio ABI version, if we increment this, we break the guest driver. */
 #define VIRTIO_PCI_ABI_VERSION          0
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 07/12] virtio-crypto: set capacity of algorithms supported
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (5 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 06/12] virtio-crypto-pci: add virtio crypto pci support Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 08/12] virtio-crypto: add control queue handler Gonglei
                   ` (7 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Expose the capacity of algorithms supported by
virtio crypto device to the frontend driver using
pci configuration space.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/virtio-crypto.c         | 40 ++++++++++++++++++++++++++++++++++++++-
 include/hw/virtio/virtio-crypto.h | 11 +++++++++++
 2 files changed, 50 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 109a504..2032d31 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -42,6 +42,22 @@ static void virtio_crypto_reset(VirtIODevice *vdev)
     }
 }
 
+static void virtio_crypto_init_config(VirtIODevice *vdev)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+
+    vcrypto->conf.crypto_services =
+                     vcrypto->conf.cryptodev->conf.crypto_services;
+    vcrypto->conf.cipher_algo_l =
+                     vcrypto->conf.cryptodev->conf.cipher_algo_l;
+    vcrypto->conf.cipher_algo_h =
+                     vcrypto->conf.cryptodev->conf.cipher_algo_h;
+    vcrypto->conf.hash_algo = vcrypto->conf.cryptodev->conf.hash_algo;
+    vcrypto->conf.mac_algo_l = vcrypto->conf.cryptodev->conf.mac_algo_l;
+    vcrypto->conf.mac_algo_h = vcrypto->conf.cryptodev->conf.mac_algo_h;
+    vcrypto->conf.aead_algo = vcrypto->conf.cryptodev->conf.aead_algo;
+}
+
 static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
@@ -75,6 +91,8 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
     } else {
         vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
     }
+
+    virtio_crypto_init_config(vdev);
 }
 
 static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp)
@@ -100,7 +118,27 @@ static Property virtio_crypto_properties[] = {
 
 static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
 {
-
+    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);
+    struct virtio_crypto_config crypto_cfg;
+
+    virtio_stl_p(vdev, &crypto_cfg.status, c->status);
+    virtio_stl_p(vdev, &crypto_cfg.max_dataqueues, c->max_queues);
+    virtio_stl_p(vdev, &crypto_cfg.crypto_services,
+                       c->conf.crypto_services);
+    virtio_stl_p(vdev, &crypto_cfg.cipher_algo_l,
+                       c->conf.cipher_algo_l);
+    virtio_stl_p(vdev, &crypto_cfg.cipher_algo_h,
+                       c->conf.cipher_algo_h);
+    virtio_stl_p(vdev, &crypto_cfg.hash_algo,
+                       c->conf.hash_algo);
+    virtio_stl_p(vdev, &crypto_cfg.mac_algo_l,
+                       c->conf.mac_algo_l);
+    virtio_stl_p(vdev, &crypto_cfg.mac_algo_h,
+                       c->conf.mac_algo_h);
+    virtio_stl_p(vdev, &crypto_cfg.aead_algo,
+                       c->conf.aead_algo);
+
+    memcpy(config, &crypto_cfg, c->config_size);
 }
 
 static void virtio_crypto_class_init(ObjectClass *klass, void *data)
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
index 4652c21..4a4b3da 100644
--- a/include/hw/virtio/virtio-crypto.h
+++ b/include/hw/virtio/virtio-crypto.h
@@ -39,6 +39,17 @@ do { \
 
 typedef struct VirtIOCryptoConf {
     CryptoDevBackend *cryptodev;
+
+    /* Supported service mask */
+    uint32_t crypto_services;
+
+    /* Detailed algorithms mask */
+    uint32_t cipher_algo_l;
+    uint32_t cipher_algo_h;
+    uint32_t hash_algo;
+    uint32_t mac_algo_l;
+    uint32_t mac_algo_h;
+    uint32_t aead_algo;
 } VirtIOCryptoConf;
 
 struct VirtIOCrypto;
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 08/12] virtio-crypto: add control queue handler
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (6 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 07/12] virtio-crypto: set capacity of algorithms supported Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler Gonglei
                   ` (6 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Realize the symmetric algorithm control queue handler,
including plain cipher and chainning algorithms.

Currently the control queue is used to create and
close session for symmetric algorithm.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/virtio-crypto.c | 290 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 289 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 2032d31..4be65e0 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -23,6 +23,294 @@
 
 #define VIRTIO_CRYPTO_VM_VERSION 1
 
+/*
+ * Transfer virtqueue index to crypto queue index.
+ * The control virtqueue is after the data virtqueues
+ * so the input value doesn't need to be adjusted
+ */
+static inline int virtio_crypto_vq2q(int queue_index)
+{
+    return queue_index;
+}
+
+static int
+virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
+           CryptoDevBackendSymSessionInfo *info,
+           struct virtio_crypto_cipher_session_para *cipher_para,
+           struct iovec **iov, unsigned int *out_num)
+{
+    unsigned int num = *out_num;
+
+    info->cipher_alg = virtio_ldl_p(vdev, &cipher_para->algo);
+    info->key_len = virtio_ldl_p(vdev, &cipher_para->keylen);
+    info->direction = virtio_ldl_p(vdev, &cipher_para->op);
+    DPRINTF("cipher_alg=%" PRIu32 ", info->direction=%" PRIu32 "\n",
+             info->cipher_alg, info->direction);
+    /* Get cipher key */
+    if (info->key_len > 0) {
+        size_t s;
+        DPRINTF("keylen=%" PRIu32 "\n", info->key_len);
+
+        info->cipher_key = g_malloc(info->key_len);
+        s = iov_to_buf(*iov, num, 0, info->cipher_key, info->key_len);
+        if (unlikely(s != info->key_len)) {
+            virtio_error(vdev, "virtio-crypto cipher key incorrect");
+            return -EFAULT;
+        }
+        iov_discard_front(iov, &num, info->key_len);
+        *out_num = num;
+    }
+
+    return 0;
+}
+
+static int64_t
+virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
+               struct virtio_crypto_sym_create_session_req *sess_req,
+               uint32_t queue_id,
+               uint32_t opcode,
+               struct iovec *iov, unsigned int out_num)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    CryptoDevBackendSymSessionInfo info;
+    int64_t session_id;
+    int queue_index;
+    uint32_t op_type;
+    Error *local_err = NULL;
+    int ret;
+
+    memset(&info, 0, sizeof(info));
+    op_type = virtio_ldl_p(vdev, &sess_req->op_type);
+    info.op_type = op_type;
+    info.op_code = opcode;
+
+    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        ret = virtio_crypto_cipher_session_helper(vdev, &info,
+                           &sess_req->u.cipher.para,
+                           &iov, &out_num);
+        if (ret < 0) {
+            ret = -EFAULT;
+            goto err;
+        }
+    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        size_t s;
+        /* cipher part */
+        ret = virtio_crypto_cipher_session_helper(vdev, &info,
+                           &sess_req->u.chain.para.cipher_param,
+                           &iov, &out_num);
+        if (ret < 0) {
+            ret = -EFAULT;
+            goto err;
+        }
+        /* hash part */
+        info.alg_chain_order = virtio_ldl_p(vdev,
+                                       &sess_req->u.chain.para.alg_chain_order);
+        info.add_len = virtio_ldl_p(vdev, &sess_req->u.chain.para.aad_len);
+        info.hash_mode = virtio_ldl_p(vdev, &sess_req->u.chain.para.hash_mode);
+        if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) {
+            info.hash_alg = virtio_ldl_p(vdev,
+                               &sess_req->u.chain.para.u.mac_param.algo);
+            info.auth_key_len = virtio_ldl_p(vdev,
+                             &sess_req->u.chain.para.u.mac_param.auth_key_len);
+            info.hash_result_len = virtio_ldl_p(vdev,
+                           &sess_req->u.chain.para.u.mac_param.hash_result_len);
+            /* get auth key */
+            if (info.auth_key_len > 0) {
+                DPRINTF("auth_keylen=%" PRIu32 "\n", info.auth_key_len);
+                info.auth_key = g_malloc(info.auth_key_len);
+                s = iov_to_buf(iov, out_num, 0, info.auth_key,
+                               info.auth_key_len);
+                if (unlikely(s != info.auth_key_len)) {
+                    virtio_error(vdev,
+                          "virtio-crypto authenticated key incorrect");
+                    ret = -EFAULT;
+                    goto err;
+                }
+                iov_discard_front(&iov, &out_num, info.auth_key_len);
+            }
+        } else if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) {
+            info.hash_alg = virtio_ldl_p(vdev,
+                             &sess_req->u.chain.para.u.hash_param.algo);
+            info.hash_result_len = virtio_ldl_p(vdev,
+                        &sess_req->u.chain.para.u.hash_param.hash_result_len);
+        } else {
+            /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */
+            error_report("unsupported hash mode");
+            ret = -VIRTIO_CRYPTO_NOTSUPP;
+            goto err;
+        }
+    } else {
+        /* VIRTIO_CRYPTO_SYM_OP_NONE */
+        error_report("unsupported cipher op_type: VIRTIO_CRYPTO_SYM_OP_NONE");
+        ret = -VIRTIO_CRYPTO_NOTSUPP;
+        goto err;
+    }
+
+    queue_index = virtio_crypto_vq2q(queue_id);
+    session_id = cryptodev_backend_sym_create_session(
+                                     vcrypto->cryptodev,
+                                     &info, queue_index, &local_err);
+    if (session_id >= 0) {
+        DPRINTF("create session_id=%" PRIu64 " successfully\n",
+                session_id);
+
+        ret = session_id;
+    } else {
+        if (local_err) {
+            error_report_err(local_err);
+        }
+        ret = -VIRTIO_CRYPTO_ERR;
+    }
+
+err:
+    g_free(info.cipher_key);
+    g_free(info.auth_key);
+    return ret;
+}
+
+static uint8_t
+virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
+         struct virtio_crypto_destroy_session_req *close_sess_req,
+         uint32_t queue_id)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    int ret;
+    uint64_t session_id;
+    uint32_t status;
+    Error *local_err = NULL;
+
+    session_id = virtio_ldq_p(vdev, &close_sess_req->session_id);
+    DPRINTF("close session, id=%" PRIu64 "\n", session_id);
+
+    ret = cryptodev_backend_sym_close_session(
+              vcrypto->cryptodev, session_id, queue_id, &local_err);
+    if (ret == 0) {
+        status = VIRTIO_CRYPTO_OK;
+    } else {
+        if (local_err) {
+            error_report_err(local_err);
+        } else {
+            error_report("destroy session failed");
+        }
+        status = VIRTIO_CRYPTO_ERR;
+    }
+
+    return status;
+}
+
+static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+    struct virtio_crypto_op_ctrl_req ctrl;
+    VirtQueueElement *elem;
+    struct iovec *in_iov;
+    struct iovec *out_iov;
+    unsigned in_num;
+    unsigned out_num;
+    uint32_t queue_id;
+    uint32_t opcode;
+    struct virtio_crypto_session_input input;
+    int64_t session_id;
+    uint8_t status;
+    size_t s;
+
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+        if (elem->out_num < 1 || elem->in_num < 1) {
+            virtio_error(vdev, "virtio-crypto ctrl missing headers");
+            virtqueue_detach_element(vq, elem, 0);
+            g_free(elem);
+            break;
+        }
+
+        out_num = elem->out_num;
+        out_iov = elem->out_sg;
+        in_num = elem->in_num;
+        in_iov = elem->in_sg;
+        if (unlikely(iov_to_buf(out_iov, out_num, 0, &ctrl, sizeof(ctrl))
+                    != sizeof(ctrl))) {
+            virtio_error(vdev, "virtio-crypto request ctrl_hdr too short");
+            virtqueue_detach_element(vq, elem, 0);
+            g_free(elem);
+            break;
+        }
+        iov_discard_front(&out_iov, &out_num, sizeof(ctrl));
+
+        opcode = virtio_ldl_p(vdev, &ctrl.header.opcode);
+        queue_id = virtio_ldl_p(vdev, &ctrl.header.queue_id);
+
+        switch (opcode) {
+        case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+            memset(&input, 0, sizeof(input));
+            session_id = virtio_crypto_create_sym_session(vcrypto,
+                             &ctrl.u.sym_create_session,
+                             queue_id, opcode,
+                             out_iov, out_num);
+            /* Serious errors, need to reset virtio crypto device */
+            if (session_id == -EFAULT) {
+                virtqueue_detach_element(vq, elem, 0);
+                break;
+            } else if (session_id == -VIRTIO_CRYPTO_NOTSUPP) {
+                virtio_stl_p(vdev, &input.status, VIRTIO_CRYPTO_NOTSUPP);
+            } else if (session_id == -VIRTIO_CRYPTO_ERR) {
+                virtio_stl_p(vdev, &input.status, VIRTIO_CRYPTO_ERR);
+            } else {
+                /* Set the session id */
+                virtio_stq_p(vdev, &input.session_id, session_id);
+                virtio_stl_p(vdev, &input.status, VIRTIO_CRYPTO_OK);
+            }
+
+            s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input));
+            if (unlikely(s != sizeof(input))) {
+                virtio_error(vdev, "virtio-crypto input incorrect");
+                virtqueue_detach_element(vq, elem, 0);
+                break;
+            }
+            virtqueue_push(vq, elem, sizeof(input));
+            virtio_notify(vdev, vq);
+            break;
+        case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION:
+        case VIRTIO_CRYPTO_HASH_DESTROY_SESSION:
+        case VIRTIO_CRYPTO_MAC_DESTROY_SESSION:
+        case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION:
+            status = virtio_crypto_handle_close_session(vcrypto,
+                   &ctrl.u.destroy_session, queue_id);
+            /* The status only occupy one byte, we can directly use it */
+            s = iov_from_buf(in_iov, in_num, 0, &status, sizeof(status));
+            if (unlikely(s != sizeof(status))) {
+                virtio_error(vdev, "virtio-crypto status incorrect");
+                virtqueue_detach_element(vq, elem, 0);
+                break;
+            }
+            virtqueue_push(vq, elem, sizeof(status));
+            virtio_notify(vdev, vq);
+            break;
+        case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
+        case VIRTIO_CRYPTO_MAC_CREATE_SESSION:
+        case VIRTIO_CRYPTO_AEAD_CREATE_SESSION:
+        default:
+            error_report("virtio-crypto unsupported ctrl opcode: %d", opcode);
+            memset(&input, 0, sizeof(input));
+            virtio_stl_p(vdev, &input.status, VIRTIO_CRYPTO_NOTSUPP);
+            s = iov_from_buf(in_iov, in_num, 0, &input, sizeof(input));
+            if (unlikely(s != sizeof(input))) {
+                virtio_error(vdev, "virtio-crypto input incorrect");
+                virtqueue_detach_element(vq, elem, 0);
+                break;
+            }
+            virtqueue_push(vq, elem, sizeof(input));
+            virtio_notify(vdev, vq);
+
+            break;
+        } /* end switch case */
+
+        g_free(elem);
+    } /* end for loop */
+}
+
 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
                                            uint64_t features,
                                            Error **errp)
@@ -85,7 +373,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
         virtio_add_queue(vdev, 1024, NULL);
     }
 
-    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, NULL);
+    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
     if (!vcrypto->cryptodev->ready) {
         vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
     } else {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (7 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 08/12] virtio-crypto: add control queue handler Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-27 16:59   ` Michael S. Tsirkin
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 10/12] cryptodev: introduce an unified wrapper for crypto operation Gonglei
                   ` (5 subsequent siblings)
  14 siblings, 1 reply; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Introduces VirtIOCryptoReq structure to store
crypto request so that we can easily support
asynchronous crypto operation in the future.

At present, we only support cipher and algorithm
chaining.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/virtio-crypto.c         | 358 +++++++++++++++++++++++++++++++++++++-
 include/hw/virtio/virtio-crypto.h |   4 +
 2 files changed, 361 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 4be65e0..eabc61f 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -311,6 +311,362 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
     } /* end for loop */
 }
 
+static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq,
+                                VirtIOCryptoReq *req)
+{
+    req->vcrypto = vcrypto;
+    req->vq = vq;
+    req->in = NULL;
+    req->in_iov = NULL;
+    req->in_num = 0;
+    req->in_len = 0;
+    req->flags = CRYPTODEV_BACKEND_ALG__MAX;
+    req->u.sym_op_info = NULL;
+}
+
+static void virtio_crypto_free_request(VirtIOCryptoReq *req)
+{
+    if (req) {
+        if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
+            g_free(req->u.sym_op_info);
+        }
+        g_free(req);
+    }
+}
+
+static void
+virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
+                VirtIOCryptoReq *req,
+                uint32_t status,
+                CryptoDevBackendSymOpInfo *sym_op_info)
+{
+    size_t s, len;
+
+    if (status != VIRTIO_CRYPTO_OK) {
+        return;
+    }
+
+    len = sym_op_info->dst_len;
+    /* Save the cipher result */
+    s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len);
+    if (s != len) {
+        virtio_error(vdev, "virtio-crypto dest data incorrect");
+        return;
+    }
+
+    iov_discard_front(&req->in_iov, &req->in_num, len);
+
+    if (sym_op_info->op_type ==
+                      VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        /* Save the digest result */
+        s = iov_from_buf(req->in_iov, req->in_num, 0,
+                         sym_op_info->digest_result,
+                         sym_op_info->digest_result_len);
+        if (s != sym_op_info->digest_result_len) {
+            virtio_error(vdev, "virtio-crypto digest result incorrect");
+        }
+    }
+}
+
+static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t status)
+{
+    VirtIOCrypto *vcrypto = req->vcrypto;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+
+    if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
+        virtio_crypto_sym_input_data_helper(vdev, req, status,
+                                            req->u.sym_op_info);
+    }
+    stb_p(&req->in->status, status);
+    virtqueue_push(req->vq, &req->elem, req->in_len);
+    virtio_notify(vdev, req->vq);
+}
+
+static VirtIOCryptoReq *
+virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
+{
+    VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq));
+
+    if (req) {
+        virtio_crypto_init_request(s, vq, req);
+    }
+    return req;
+}
+
+static CryptoDevBackendSymOpInfo *
+virtio_crypto_sym_op_helper(VirtIODevice *vdev,
+           struct virtio_crypto_cipher_para *cipher_para,
+           struct virtio_crypto_alg_chain_data_para *alg_chain_para,
+           struct iovec *iov, unsigned int out_num)
+{
+    CryptoDevBackendSymOpInfo *op_info;
+    uint32_t src_len = 0, dst_len = 0;
+    uint32_t iv_len = 0;
+    uint32_t aad_len = 0, hash_result_len = 0;
+    uint32_t hash_start_src_offset = 0, len_to_hash = 0;
+    uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
+
+    size_t max_len, curr_size = 0;
+    size_t s;
+
+    /* Plain cipher */
+    if (cipher_para) {
+        iv_len = virtio_ldl_p(vdev, &cipher_para->iv_len);
+        src_len = virtio_ldl_p(vdev, &cipher_para->src_data_len);
+        dst_len = virtio_ldl_p(vdev, &cipher_para->dst_data_len);
+    } else if (alg_chain_para) { /* Algorithm chain */
+        iv_len = virtio_ldl_p(vdev, &alg_chain_para->iv_len);
+        src_len = virtio_ldl_p(vdev, &alg_chain_para->src_data_len);
+        dst_len = virtio_ldl_p(vdev, &alg_chain_para->dst_data_len);
+
+        aad_len = virtio_ldl_p(vdev, &alg_chain_para->aad_len);
+        hash_result_len = virtio_ldl_p(vdev,
+                              &alg_chain_para->hash_result_len);
+        hash_start_src_offset = virtio_ldl_p(vdev,
+                         &alg_chain_para->hash_start_src_offset);
+        cipher_start_src_offset = virtio_ldl_p(vdev,
+                         &alg_chain_para->cipher_start_src_offset);
+        len_to_cipher = virtio_ldl_p(vdev, &alg_chain_para->len_to_cipher);
+        len_to_hash = virtio_ldl_p(vdev, &alg_chain_para->len_to_hash);
+    } else {
+        return NULL;
+    }
+
+    max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
+    if (unlikely(max_len > LONG_MAX - sizeof(CryptoDevBackendSymOpInfo))) {
+        virtio_error(vdev, "virtio-crypto too big length");
+        return NULL;
+    }
+
+    op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);
+    op_info->iv_len = iv_len;
+    op_info->src_len = src_len;
+    op_info->dst_len = dst_len;
+    op_info->aad_len = aad_len;
+    op_info->digest_result_len = hash_result_len;
+    op_info->hash_start_src_offset = hash_start_src_offset;
+    op_info->len_to_hash = len_to_hash;
+    op_info->cipher_start_src_offset = cipher_start_src_offset;
+    op_info->len_to_cipher = len_to_cipher;
+    /* Handle the initilization vector */
+    if (op_info->iv_len > 0) {
+        DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
+        op_info->iv = op_info->data + curr_size;
+
+        s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len);
+        if (unlikely(s != op_info->iv_len)) {
+            virtio_error(vdev, "virtio-crypto iv incorrect");
+            goto err;
+        }
+        iov_discard_front(&iov, &out_num, op_info->iv_len);
+        curr_size += op_info->iv_len;
+    }
+
+    /* Handle additional authentication data if exist */
+    if (op_info->aad_len > 0) {
+        DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len);
+        op_info->aad_data = op_info->data + curr_size;
+
+        s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len);
+        if (unlikely(s != op_info->aad_len)) {
+            virtio_error(vdev, "virtio-crypto additional auth data incorrect");
+            goto err;
+        }
+        iov_discard_front(&iov, &out_num, op_info->aad_len);
+
+        curr_size += op_info->aad_len;
+    }
+
+    /* Handle the source data */
+    if (op_info->src_len > 0) {
+        DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len);
+        op_info->src = op_info->data + curr_size;
+
+        s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len);
+        if (unlikely(s != op_info->src_len)) {
+            virtio_error(vdev, "virtio-crypto source data incorrect");
+            goto err;
+        }
+        iov_discard_front(&iov, &out_num, op_info->src_len);
+
+        curr_size += op_info->src_len;
+    }
+
+    /* Handle the destination data */
+    op_info->dst = op_info->data + curr_size;
+    curr_size += op_info->dst_len;
+
+    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);
+
+    /* Handle the hash digest result */
+    if (hash_result_len > 0) {
+        DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len);
+        op_info->digest_result = op_info->data + curr_size;
+    }
+
+    return op_info;
+
+err:
+    g_free(op_info);
+    return NULL;
+}
+
+static int
+virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
+               struct virtio_crypto_sym_data_req *req,
+               CryptoDevBackendSymOpInfo **sym_op_info,
+               struct iovec *iov, unsigned int out_num)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    uint32_t op_type;
+    CryptoDevBackendSymOpInfo *op_info;
+
+    op_type = virtio_ldl_p(vdev, &req->op_type);
+
+    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
+                                              NULL, iov, out_num);
+        if (!op_info) {
+            return -EFAULT;
+        }
+        op_info->op_type = op_type;
+    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        op_info = virtio_crypto_sym_op_helper(vdev, NULL,
+                                              &req->u.chain.para,
+                                              iov, out_num);
+        if (!op_info) {
+            return -EFAULT;
+        }
+        op_info->op_type = op_type;
+    } else {
+        /* VIRTIO_CRYPTO_SYM_OP_NONE */
+        error_report("virtio-crypto unsupported cipher type");
+        return -VIRTIO_CRYPTO_NOTSUPP;
+    }
+
+    *sym_op_info = op_info;
+
+    return 0;
+}
+
+static int
+virtio_crypto_handle_request(VirtIOCryptoReq *request)
+{
+    VirtIOCrypto *vcrypto = request->vcrypto;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    VirtQueueElement *elem = &request->elem;
+    int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq));
+    struct virtio_crypto_op_data_req req;
+    int ret;
+    struct iovec *in_iov;
+    struct iovec *out_iov;
+    unsigned in_num;
+    unsigned out_num;
+    uint32_t opcode;
+    uint8_t status = VIRTIO_CRYPTO_ERR;
+    uint64_t session_id;
+    CryptoDevBackendSymOpInfo *sym_op_info = NULL;
+    Error *local_err = NULL;
+
+    if (elem->out_num < 1 || elem->in_num < 1) {
+        virtio_error(vdev, "virtio-crypto dataq missing headers");
+        return -1;
+    }
+
+    out_num = elem->out_num;
+    out_iov = elem->out_sg;
+    in_num = elem->in_num;
+    in_iov = elem->in_sg;
+    if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req))
+                != sizeof(req))) {
+        virtio_error(vdev, "virtio-crypto request outhdr too short");
+        return -1;
+    }
+    iov_discard_front(&out_iov, &out_num, sizeof(req));
+
+    if (in_iov[in_num - 1].iov_len <
+            sizeof(struct virtio_crypto_inhdr)) {
+        virtio_error(vdev, "virtio-crypto request inhdr too short");
+        return -1;
+    }
+    /* We always touch the last byte, so just see how big in_iov is. */
+    request->in_len = iov_size(in_iov, in_num);
+    request->in = (void *)in_iov[in_num - 1].iov_base
+              + in_iov[in_num - 1].iov_len
+              - sizeof(struct virtio_crypto_inhdr);
+    iov_discard_back(in_iov, &in_num, sizeof(struct virtio_crypto_inhdr));
+
+    /*
+     * The length of operation result, including dest_data
+     * and digest_result if exist.
+     */
+    request->in_num = in_num;
+    request->in_iov = in_iov;
+
+    opcode = virtio_ldl_p(vdev, &req.header.opcode);
+    session_id = virtio_ldq_p(vdev, &req.header.session_id);
+
+    switch (opcode) {
+    case VIRTIO_CRYPTO_CIPHER_ENCRYPT:
+    case VIRTIO_CRYPTO_CIPHER_DECRYPT:
+        ret = virtio_crypto_handle_sym_req(vcrypto,
+                         &req.u.sym_req,
+                         &sym_op_info,
+                         out_iov, out_num);
+        /* Serious errors, need to reset virtio crypto device */
+        if (ret == -EFAULT) {
+            return -1;
+        } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) {
+            virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP);
+            virtio_crypto_free_request(request);
+        } else {
+            sym_op_info->session_id = session_id;
+
+            /* Set request's parameter */
+            request->flags = CRYPTODEV_BACKEND_ALG_SYM;
+            request->u.sym_op_info = sym_op_info;
+            ret = cryptodev_backend_sym_operation(vcrypto->cryptodev,
+                                    sym_op_info, queue_index, &local_err);
+            if (ret < 0) {
+                status = VIRTIO_CRYPTO_ERR;
+                if (local_err) {
+                    error_report_err(local_err);
+                }
+            } else { /* ret >= 0 */
+                status = VIRTIO_CRYPTO_OK;
+            }
+            virtio_crypto_req_complete(request, status);
+            virtio_crypto_free_request(request);
+        }
+        break;
+    case VIRTIO_CRYPTO_HASH:
+    case VIRTIO_CRYPTO_MAC:
+    case VIRTIO_CRYPTO_AEAD_ENCRYPT:
+    case VIRTIO_CRYPTO_AEAD_DECRYPT:
+    default:
+        error_report("virtio-crypto unsupported dataq opcode: %u",
+                     opcode);
+        virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP);
+        virtio_crypto_free_request(request);
+    }
+
+    return 0;
+}
+
+static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+    VirtIOCryptoReq *req;
+
+    while ((req = virtio_crypto_get_request(vcrypto, vq))) {
+        if (virtio_crypto_handle_request(req) < 0) {
+            virtqueue_detach_element(req->vq, &req->elem, 0);
+            virtio_crypto_free_request(req);
+            break;
+        }
+    }
+}
+
 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
                                            uint64_t features,
                                            Error **errp)
@@ -370,7 +726,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
     vcrypto->curr_queues = 1;
 
     for (i = 0; i < vcrypto->max_queues; i++) {
-        virtio_add_queue(vdev, 1024, NULL);
+        virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq);
     }
 
     vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
index 4a4b3da..2628056 100644
--- a/include/hw/virtio/virtio-crypto.h
+++ b/include/hw/virtio/virtio-crypto.h
@@ -58,6 +58,10 @@ typedef struct VirtIOCryptoReq {
     VirtQueueElement elem;
     /* flags of operation, such as type of algorithm */
     uint32_t flags;
+    struct virtio_crypto_inhdr *in;
+    struct iovec *in_iov; /* Head address of dest iovec */
+    unsigned int in_num; /* Number of dest iovec */
+    size_t in_len;
     VirtQueue *vq;
     struct VirtIOCrypto *vcrypto;
     union {
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 10/12] cryptodev: introduce an unified wrapper for crypto operation
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (8 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 11/12] virtio-crypto: using bh to handle dataq's requests Gonglei
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

We use an opaque point to the VirtIOCryptoReq which
can support different packets based on different
algorithms.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 backends/cryptodev.c       | 28 ++++++++++++++++++++++++++--
 hw/virtio/virtio-crypto.c  | 10 +++++-----
 include/sysemu/cryptodev.h | 13 +++++++------
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index 47521cf..4a49f97 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -30,6 +30,8 @@
 #include "qapi-visit.h"
 #include "qemu/config-file.h"
 #include "qom/object_interfaces.h"
+#include "hw/virtio/virtio-crypto.h"
+
 
 static QTAILQ_HEAD(, CryptoDevBackendClient) crypto_clients;
 
@@ -105,7 +107,7 @@ int cryptodev_backend_sym_close_session(
     return -1;
 }
 
-int cryptodev_backend_sym_operation(
+static int cryptodev_backend_sym_operation(
                  CryptoDevBackend *backend,
                  CryptoDevBackendSymOpInfo *op_info,
                  uint32_t queue_index, Error **errp)
@@ -117,7 +119,29 @@ int cryptodev_backend_sym_operation(
         return bc->do_sym_op(backend, op_info, queue_index, errp);
     }
 
-    return -1;
+    return -VIRTIO_CRYPTO_ERR;
+}
+
+int cryptodev_backend_crypto_operation(
+                 CryptoDevBackend *backend,
+                 void *opaque,
+                 uint32_t queue_index, Error **errp)
+{
+    VirtIOCryptoReq *req = opaque;
+
+    if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
+        CryptoDevBackendSymOpInfo *op_info;
+        op_info = req->u.sym_op_info;
+
+        return cryptodev_backend_sym_operation(backend,
+                         op_info, queue_index, errp);
+    } else {
+        error_setg(errp, "Unsupported cryptodev alg type: %" PRIu32 "",
+                   req->flags);
+       return -VIRTIO_CRYPTO_NOTSUPP;
+    }
+
+    return -VIRTIO_CRYPTO_ERR;
 }
 
 static void
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index eabc61f..7fe1128 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -625,15 +625,15 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request)
             /* Set request's parameter */
             request->flags = CRYPTODEV_BACKEND_ALG_SYM;
             request->u.sym_op_info = sym_op_info;
-            ret = cryptodev_backend_sym_operation(vcrypto->cryptodev,
-                                    sym_op_info, queue_index, &local_err);
+            ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev,
+                                    request, queue_index, &local_err);
             if (ret < 0) {
-                status = VIRTIO_CRYPTO_ERR;
+                status = -ret;
                 if (local_err) {
                     error_report_err(local_err);
                 }
-            } else { /* ret >= 0 */
-                status = VIRTIO_CRYPTO_OK;
+            } else { /* ret == VIRTIO_CRYPTO_OK */
+                status = ret;
             }
             virtio_crypto_req_complete(request, status);
             virtio_crypto_free_request(request);
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
index e4510da..f9a4b36 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -275,20 +275,21 @@ int cryptodev_backend_sym_close_session(
            uint32_t queue_index, Error **errp);
 
 /**
- * cryptodev_backend_sym_operation:
+ * cryptodev_backend_crypto_operation:
  * @backend: the cryptodev backend object
- * @op_info: parameters needed by symmetric crypto operation
+ * @opaque: pointer to a VirtIOCryptoReq object
  * @queue_index: queue index of cryptodev backend client
  * @errp: pointer to a NULL-initialized error object
  *
- * Do symmetric crypto operation, such as encryption and
+ * Do crypto operation, such as encryption and
  * decryption
  *
- * Returns: 0 on success, or Negative on error
+ * Returns: VIRTIO_CRYPTO_OK on success,
+ *         or -VIRTIO_CRYPTO_* on error
  */
-int cryptodev_backend_sym_operation(
+int cryptodev_backend_crypto_operation(
                  CryptoDevBackend *backend,
-                 CryptoDevBackendSymOpInfo *op_info,
+                 void *opaque,
                  uint32_t queue_index, Error **errp);
 
 #endif /* CRYPTODEV_H */
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 11/12] virtio-crypto: using bh to handle dataq's requests
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (9 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 10/12] cryptodev: introduce an unified wrapper for crypto operation Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 12/12] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

Make crypto operations are executed asynchronously,
so that other QEMU threads and monitor couldn't
be blocked at the virtqueue handling context.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/virtio-crypto.c         | 55 +++++++++++++++++++++++++++++++++++++--
 include/hw/virtio/virtio-crypto.h |  8 +++++-
 2 files changed, 60 insertions(+), 3 deletions(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 7fe1128..47a25cd 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -667,6 +667,41 @@ static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
     }
 }
 
+static void virtio_crypto_dataq_bh(void *opaque)
+{
+    VirtIOCryptoQueue *q = opaque;
+    VirtIOCrypto *vcrypto = q->vcrypto;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+
+    /* This happens when device was stopped but BH wasn't. */
+    if (!vdev->vm_running) {
+        return;
+    }
+
+    /* Just in case the driver is not ready on more */
+    if (unlikely(!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK))) {
+        return;
+    }
+
+    virtio_crypto_handle_dataq(vdev, q->dataq);
+    virtio_queue_set_notification(q->dataq, 1);
+}
+
+static void
+virtio_crypto_handle_dataq_bh(VirtIODevice *vdev, VirtQueue *vq)
+{
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
+    VirtIOCryptoQueue *q =
+         &vcrypto->vqs[virtio_crypto_vq2q(virtio_get_queue_index(vq))];
+
+    /* This happens when device was stopped but VCPU wasn't. */
+    if (!vdev->vm_running) {
+        return;
+    }
+    virtio_queue_set_notification(vq, 0);
+    qemu_bh_schedule(q->dataq_bh);
+}
+
 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
                                            uint64_t features,
                                            Error **errp)
@@ -724,9 +759,13 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
 
     virtio_init(vdev, "virtio-crypto", VIRTIO_ID_CRYPTO, vcrypto->config_size);
     vcrypto->curr_queues = 1;
-
+    vcrypto->vqs = g_malloc0(sizeof(VirtIOCryptoQueue) * vcrypto->max_queues);
     for (i = 0; i < vcrypto->max_queues; i++) {
-        virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq);
+        vcrypto->vqs[i].dataq =
+                 virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq_bh);
+        vcrypto->vqs[i].dataq_bh =
+                 qemu_bh_new(virtio_crypto_dataq_bh, &vcrypto->vqs[i]);
+        vcrypto->vqs[i].vcrypto = vcrypto;
     }
 
     vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
@@ -742,6 +781,18 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
 static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
+    VirtIOCryptoQueue *q;
+    int i, max_queues;
+
+    max_queues = vcrypto->multiqueue ? vcrypto->max_queues : 1;
+    for (i = 0; i < max_queues; i++) {
+        virtio_del_queue(vdev, i);
+        q = &vcrypto->vqs[i];
+        qemu_bh_delete(q->dataq_bh);
+    }
+
+    g_free(vcrypto->vqs);
 
     virtio_cleanup(vdev);
 }
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
index 2628056..e15d694 100644
--- a/include/hw/virtio/virtio-crypto.h
+++ b/include/hw/virtio/virtio-crypto.h
@@ -69,11 +69,17 @@ typedef struct VirtIOCryptoReq {
     } u;
 } VirtIOCryptoReq;
 
+typedef struct VirtIOCryptoQueue {
+    VirtQueue *dataq;
+    QEMUBH *dataq_bh;
+    struct VirtIOCrypto *vcrypto;
+} VirtIOCryptoQueue;
+
 typedef struct VirtIOCrypto {
     VirtIODevice parent_obj;
 
     VirtQueue *ctrl_vq;
-
+    VirtIOCryptoQueue *vqs;
     VirtIOCryptoConf conf;
     CryptoDevBackend *cryptodev;
 
-- 
1.8.3.1

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

* [Qemu-devel] [PATCH v9 12/12] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (10 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 11/12] virtio-crypto: using bh to handle dataq's requests Gonglei
@ 2016-10-20 11:45 ` Gonglei
  2016-10-20 12:25 ` [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation no-reply
                   ` (2 subsequent siblings)
  14 siblings, 0 replies; 26+ messages in thread
From: Gonglei @ 2016-10-20 11:45 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: luonengjun, mst, stefanha, pbonzini, berrange, weidong.huang,
	wu.wubin, mike.caraman, agraf, xin.zeng, claudio.fontana, nmorey,
	vincent.jardin, jianjay.zhou, hanweidong, peter.huangpeng,
	arei.gonglei, eblake, Gonglei

This patch includes two parts: Cryptodev Backends
and virtio-crypto stuff. I can maintain cryptodev backends
which introduced by myself. For virtio-crypto stuff, I can
share the work with Michael (The whole virtio supporter).

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 MAINTAINERS | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index b01fec0..96fd24f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1003,6 +1003,13 @@ F: include/sysemu/rng*.h
 F: backends/rng*.c
 F: tests/virtio-rng-test.c
 
+virtio-crypto
+M: Gonglei <arei.gonglei@huawei.com>
+S: Supported
+F: hw/virtio/virtio-crypto.c
+F: hw/virtio/virtio-crypto-pci.c
+F: include/hw/virtio/virtio-crypto.h
+
 nvme
 M: Keith Busch <keith.busch@intel.com>
 L: qemu-block@nongnu.org
@@ -1248,6 +1255,12 @@ S: Maintained
 F: backends/hostmem*.c
 F: include/sysemu/hostmem.h
 
+Cryptodev Backends
+M: Gonglei <arei.gonglei@huawei.com>
+S: Maintained
+F: include/sysemu/cryptodev*.h
+F: backends/cryptodev*.c
+
 QAPI
 M: Markus Armbruster <armbru@redhat.com>
 M: Michael Roth <mdroth@linux.vnet.ibm.com>
-- 
1.8.3.1

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (11 preceding siblings ...)
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 12/12] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
@ 2016-10-20 12:25 ` no-reply
  2016-10-27  8:03   ` Gonglei (Arei)
  2016-10-25 11:20 ` Gonglei (Arei)
  2016-10-30 20:00 ` [Qemu-devel] " Halil Pasic
  14 siblings, 1 reply; 26+ messages in thread
From: no-reply @ 2016-10-20 12:25 UTC (permalink / raw)
  To: arei.gonglei
  Cc: famz, qemu-devel, virtio-dev, weidong.huang, claudio.fontana,
	mst, xin.zeng, hanweidong, luonengjun, agraf, nmorey,
	mike.caraman, stefanha, jianjay.zhou, pbonzini, peter.huangpeng,
	vincent.jardin, wu.wubin, arei.gonglei

Hi,

Your series failed automatic build test. Please find the testing commands and
their output below. If you have docker installed, you can probably reproduce it
locally.

Type: series
Message-id: 1476963957-176296-1-git-send-email-arei.gonglei@huawei.com
Subject: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation

=== TEST SCRIPT BEGIN ===
#!/bin/bash
set -e
git submodule update --init dtc
# Let docker tests dump environment info
export SHOW_ENV=1
export J=16
make docker-test-quick@centos6
make docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
From https://github.com/patchew-project/qemu
 * [new tag]         patchew/1476963957-176296-1-git-send-email-arei.gonglei@huawei.com -> patchew/1476963957-176296-1-git-send-email-arei.gonglei@huawei.com
Switched to a new branch 'test'
d4ba160 virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer
370fc1f virtio-crypto: using bh to handle dataq's requests
87cb29d cryptodev: introduce an unified wrapper for crypto operation
64138c2 virtio-crypto: add data queue processing handler
bd145c0 virtio-crypto: add control queue handler
0841a9f virtio-crypto: set capacity of algorithms supported
0ad7799 virtio-crypto-pci: add virtio crypto pci support
e1fb177 virtio-crypto: add virtio crypto device emulation
9ab5672 cryptodev: introduce a new cryptodev backend
6d04b16 virtio-crypto: introduce virtio_crypto.h
e97a1ef cryptodev: add symmetric algorithm operation stuff
7ba4b58 cryptodev: introduce cryptodev backend interface

=== OUTPUT BEGIN ===
Submodule 'dtc' (git://git.qemu-project.org/dtc.git) registered for path 'dtc'
Cloning into 'dtc'...
Submodule path 'dtc': checked out '65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf'
  BUILD   centos6
make[1]: Entering directory '/var/tmp/patchew-tester-tmp-wj4_xrg5/src'
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY    RUNNER
    RUN test-quick in qemu:centos6 
Packages installed:
SDL-devel-1.2.14-7.el6_7.1.x86_64
ccache-3.1.6-2.el6.x86_64
epel-release-6-8.noarch
gcc-4.4.7-17.el6.x86_64
git-1.7.1-4.el6_7.1.x86_64
glib2-devel-2.28.8-5.el6.x86_64
libfdt-devel-1.4.0-1.el6.x86_64
make-3.81-23.el6.x86_64
package g++ is not installed
pixman-devel-0.32.8-1.el6.x86_64
tar-1.23-15.el6_8.x86_64
zlib-devel-1.2.3-29.el6.x86_64

Environment variables:
PACKAGES=libfdt-devel ccache     tar git make gcc g++     zlib-devel glib2-devel SDL-devel pixman-devel     epel-release
HOSTNAME=4ebbea40c825
TERM=xterm
MAKEFLAGS= -j16
HISTSIZE=1000
J=16
USER=root
CCACHE_DIR=/var/tmp/ccache
EXTRA_CONFIGURE_OPTS=
V=
SHOW_ENV=1
MAIL=/var/spool/mail/root
PATH=/usr/lib/ccache:/usr/lib64/ccache:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
LANG=en_US.UTF-8
TARGET_LIST=
HISTCONTROL=ignoredups
SHLVL=1
HOME=/root
TEST_DIR=/tmp/qemu-test
LOGNAME=root
LESSOPEN=||/usr/bin/lesspipe.sh %s
FEATURES= dtc
DEBUG=
G_BROKEN_FILENAMES=1
CCACHE_HASHDIR=
_=/usr/bin/env

Configure options:
--enable-werror --target-list=x86_64-softmmu,aarch64-softmmu --prefix=/var/tmp/qemu-build/install
No C++ compiler available; disabling C++ specific optional code
Install prefix    /var/tmp/qemu-build/install
BIOS directory    /var/tmp/qemu-build/install/share/qemu
binary directory  /var/tmp/qemu-build/install/bin
library directory /var/tmp/qemu-build/install/lib
module directory  /var/tmp/qemu-build/install/lib/qemu
libexec directory /var/tmp/qemu-build/install/libexec
include directory /var/tmp/qemu-build/install/include
config directory  /var/tmp/qemu-build/install/etc
local state directory   /var/tmp/qemu-build/install/var
Manual directory  /var/tmp/qemu-build/install/share/man
ELF interp prefix /usr/gnemul/qemu-%M
Source path       /tmp/qemu-test/src
C compiler        cc
Host C compiler   cc
C++ compiler      
Objective-C compiler cc
ARFLAGS           rv
CFLAGS            -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2 -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -fPIE -DPIE -m64 -D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -Wstrict-prototypes -Wredundant-decls -Wall -Wundef -Wwrite-strings -Wmissing-prototypes -fno-strict-aliasing -fno-common -fwrapv  -Wendif-labels -Wmissing-include-dirs -Wempty-body -Wnested-externs -Wformat-security -Wformat-y2k -Winit-self -Wignored-qualifiers -Wold-style-declaration -Wold-style-definition -Wtype-limits -fstack-protector-all
LDFLAGS           -Wl,--warn-common -Wl,-z,relro -Wl,-z,now -pie -m64 -g 
make              make
install           install
python            python -B
smbd              /usr/sbin/smbd
module support    no
host CPU          x86_64
host big endian   no
target list       x86_64-softmmu aarch64-softmmu
tcg debug enabled no
gprof enabled     no
sparse enabled    no
strip binaries    yes
profiler          no
static build      no
pixman            system
SDL support       yes (1.2.14)
GTK support       no 
GTK GL support    no
VTE support       no 
TLS priority      NORMAL
GNUTLS support    no
GNUTLS rnd        no
libgcrypt         no
libgcrypt kdf     no
nettle            no 
nettle kdf        no
libtasn1          no
curses support    no
virgl support     no
curl support      no
mingw32 support   no
Audio drivers     oss
Block whitelist (rw) 
Block whitelist (ro) 
VirtFS support    no
VNC support       yes
VNC SASL support  no
VNC JPEG support  no
VNC PNG support   no
xen support       no
brlapi support    no
bluez  support    no
Documentation     no
PIE               yes
vde support       no
netmap support    no
Linux AIO support no
ATTR/XATTR support yes
Install blobs     yes
KVM support       yes
RDMA support      no
TCG interpreter   no
fdt support       yes
preadv support    yes
fdatasync         yes
madvise           yes
posix_madvise     yes
libcap-ng support no
vhost-net support yes
vhost-scsi support yes
vhost-vsock support yes
Trace backends    log
spice support     no 
rbd support       no
xfsctl support    no
smartcard support no
libusb            no
usb net redir     no
OpenGL support    no
OpenGL dmabufs    no
libiscsi support  no
libnfs support    no
build guest agent yes
QGA VSS support   no
QGA w32 disk info no
QGA MSI support   no
seccomp support   no
coroutine backend ucontext
coroutine pool    yes
debug stack usage no
GlusterFS support no
Archipelago support no
gcov              gcov
gcov enabled      no
TPM support       yes
libssh2 support   no
TPM passthrough   yes
QOM debugging     yes
lzo support       no
snappy support    no
bzip2 support     no
NUMA host support no
tcmalloc support  no
jemalloc support  no
avx2 optimization no
replication support yes
  GEN     x86_64-softmmu/config-devices.mak.tmp
  GEN     aarch64-softmmu/config-devices.mak.tmp
  GEN     config-host.h
  GEN     qemu-options.def
  GEN     qmp-commands.h
  GEN     qapi-types.h
  GEN     qapi-visit.h
  GEN     qapi-event.h
  GEN     qmp-introspect.h
  GEN     x86_64-softmmu/config-devices.mak
  GEN     aarch64-softmmu/config-devices.mak
  GEN     module_block.h
  GEN     tests/test-qapi-types.h
  GEN     tests/test-qapi-visit.h
  GEN     tests/test-qmp-commands.h
  GEN     tests/test-qapi-event.h
  GEN     tests/test-qmp-introspect.h
  GEN     trace/generated-tracers.h
  GEN     trace/generated-tcg-tracers.h
  GEN     trace/generated-helpers-wrappers.h
  GEN     trace/generated-helpers.h
  GEN     config-all-devices.mak
  CC      tests/qemu-iotests/socket_scm_helper.o
  GEN     qga/qapi-generated/qga-qapi-types.h
  GEN     qga/qapi-generated/qga-qapi-visit.h
  GEN     qga/qapi-generated/qga-qmp-commands.h
  GEN     qga/qapi-generated/qga-qapi-types.c
  GEN     qga/qapi-generated/qga-qapi-visit.c
  GEN     qga/qapi-generated/qga-qmp-marshal.c
  GEN     qmp-introspect.c
  GEN     qapi-types.c
  GEN     qapi-visit.c
  GEN     qapi-event.c
  CC      qapi/qapi-visit-core.o
  CC      qapi/qapi-dealloc-visitor.o
  CC      qapi/qmp-output-visitor.o
  CC      qapi/qmp-input-visitor.o
  CC      qapi/qmp-registry.o
  CC      qapi/qmp-dispatch.o
  CC      qapi/string-input-visitor.o
  CC      qapi/string-output-visitor.o
  CC      qapi/opts-visitor.o
  CC      qapi/qapi-clone-visitor.o
  CC      qapi/qmp-event.o
  CC      qapi/qapi-util.o
  CC      qobject/qnull.o
  CC      qobject/qint.o
  CC      qobject/qstring.o
  CC      qobject/qdict.o
  CC      qobject/qlist.o
  CC      qobject/qfloat.o
  CC      qobject/qbool.o
  CC      qobject/qjson.o
  CC      qobject/qobject.o
  CC      qobject/json-lexer.o
  CC      qobject/json-streamer.o
  CC      qobject/json-parser.o
  GEN     trace/generated-tracers.c
  CC      trace/control.o
  CC      trace/qmp.o
  CC      util/osdep.o
  CC      util/cutils.o
  CC      util/unicode.o
  CC      util/qemu-timer-common.o
  CC      util/bufferiszero.o
  CC      util/compatfd.o
  CC      util/event_notifier-posix.o
  CC      util/mmap-alloc.o
  CC      util/oslib-posix.o
  CC      util/qemu-openpty.o
  CC      util/memfd.o
  CC      util/qemu-thread-posix.o
  CC      util/envlist.o
  CC      util/path.o
  CC      util/module.o
  CC      util/bitmap.o
  CC      util/bitops.o
  CC      util/hbitmap.o
  CC      util/fifo8.o
  CC      util/acl.o
  CC      util/error.o
  CC      util/qemu-error.o
  CC      util/id.o
  CC      util/iov.o
  CC      util/qemu-config.o
  CC      util/qemu-sockets.o
  CC      util/uri.o
  CC      util/notify.o
  CC      util/qemu-option.o
  CC      util/qemu-progress.o
  CC      util/hexdump.o
  CC      util/crc32c.o
  CC      util/uuid.o
  CC      util/throttle.o
  CC      util/getauxval.o
  CC      util/readline.o
  CC      util/rfifolock.o
  CC      util/rcu.o
  CC      util/qemu-coroutine.o
  CC      util/qemu-coroutine-lock.o
  CC      util/qemu-coroutine-io.o
  CC      util/qemu-coroutine-sleep.o
  CC      util/coroutine-ucontext.o
  CC      util/buffer.o
  CC      util/timed-average.o
  CC      util/base64.o
  CC      util/qdist.o
  CC      util/log.o
  CC      util/qht.o
  CC      util/range.o
  CC      crypto/pbkdf-stub.o
  CC      stubs/arch-query-cpu-def.o
  CC      stubs/arch-query-cpu-model-expansion.o
  CC      stubs/arch-query-cpu-model-comparison.o
  CC      stubs/bdrv-next-monitor-owned.o
  CC      stubs/blk-commit-all.o
  CC      stubs/arch-query-cpu-model-baseline.o
  CC      stubs/blockdev-close-all-bdrv-states.o
  CC      stubs/clock-warp.o
  CC      stubs/cpu-get-clock.o
  CC      stubs/cpu-get-icount.o
  CC      stubs/dump.o
  CC      stubs/fdset-find-fd.o
  CC      stubs/fdset-add-fd.o
  CC      stubs/fdset-get-fd.o
  CC      stubs/gdbstub.o
  CC      stubs/fdset-remove-fd.o
  CC      stubs/get-fd.o
  CC      stubs/get-next-serial.o
  CC      stubs/get-vm-name.o
  CC      stubs/iothread-lock.o
  CC      stubs/is-daemonized.o
  CC      stubs/machine-init-done.o
  CC      stubs/migr-blocker.o
  CC      stubs/mon-is-qmp.o
  CC      stubs/mon-printf.o
  CC      stubs/monitor-init.o
  CC      stubs/notify-event.o
  CC      stubs/qtest.o
  CC      stubs/replay.o
  CC      stubs/replay-user.o
  CC      stubs/reset.o
  CC      stubs/runstate-check.o
  CC      stubs/set-fd-handler.o
  CC      stubs/slirp.o
  CC      stubs/sysbus.o
  CC      stubs/trace-control.o
  CC      stubs/uuid.o
  CC      stubs/vm-stop.o
  CC      stubs/vmstate.o
  CC      stubs/cpus.o
  CC      stubs/kvm.o
  CC      stubs/qmp_pc_dimm_device_list.o
  CC      stubs/target-monitor-defs.o
  CC      stubs/target-get-monitor-def.o
  CC      stubs/vhost.o
  CC      stubs/iohandler.o
  CC      stubs/smbios_type_38.o
  CC      stubs/ipmi.o
  CC      stubs/pc_madt_cpu_entry.o
  CC      contrib/ivshmem-client/ivshmem-client.o
  CC      contrib/ivshmem-client/main.o
  CC      contrib/ivshmem-server/ivshmem-server.o
  CC      contrib/ivshmem-server/main.o
  CC      qemu-nbd.o
  CC      async.o
  CC      thread-pool.o
  CC      block.o
  CC      blockjob.o
  CC      main-loop.o
  CC      iohandler.o
  CC      qemu-timer.o
  CC      aio-posix.o
  CC      qemu-io-cmds.o
  CC      replication.o
  CC      block/raw_bsd.o
  CC      block/qcow.o
  CC      block/vdi.o
  CC      block/vmdk.o
  CC      block/cloop.o
  CC      block/bochs.o
  CC      block/vpc.o
  CC      block/vvfat.o
  CC      block/dmg.o
  CC      block/qcow2.o
  CC      block/qcow2-refcount.o
  CC      block/qcow2-cluster.o
  CC      block/qcow2-snapshot.o
  CC      block/qcow2-cache.o
  CC      block/qed.o
  CC      block/qed-gencb.o
  CC      block/qed-l2-cache.o
  CC      block/qed-table.o
  CC      block/qed-cluster.o
  CC      block/qed-check.o
  CC      block/vhdx.o
  CC      block/vhdx-endian.o
  CC      block/vhdx-log.o
  CC      block/quorum.o
  CC      block/parallels.o
  CC      block/blkdebug.o
  CC      block/blkverify.o
  CC      block/blkreplay.o
  CC      block/block-backend.o
  CC      block/snapshot.o
  CC      block/qapi.o
  CC      block/raw-posix.o
  CC      block/null.o
  CC      block/mirror.o
  CC      block/commit.o
  CC      block/io.o
  CC      block/throttle-groups.o
  CC      block/nbd.o
  CC      block/nbd-client.o
  CC      block/sheepdog.o
  CC      block/accounting.o
  CC      block/dirty-bitmap.o
  CC      block/write-threshold.o
  CC      block/backup.o
  CC      block/replication.o
  CC      block/crypto.o
  CC      nbd/server.o
  CC      nbd/client.o
  CC      nbd/common.o
  CC      crypto/init.o
  CC      crypto/hash.o
  CC      crypto/hash-glib.o
  CC      crypto/aes.o
  CC      crypto/desrfb.o
  CC      crypto/cipher.o
  CC      crypto/tlscreds.o
  CC      crypto/tlscredsanon.o
  CC      crypto/tlscredsx509.o
  CC      crypto/tlssession.o
  CC      crypto/secret.o
  CC      crypto/random-platform.o
  CC      crypto/pbkdf.o
  CC      crypto/ivgen.o
  CC      crypto/ivgen-essiv.o
  CC      crypto/ivgen-plain.o
  CC      crypto/ivgen-plain64.o
  CC      crypto/afsplit.o
  CC      crypto/xts.o
  CC      crypto/block.o
  CC      crypto/block-qcow.o
  CC      crypto/block-luks.o
  CC      io/channel.o
  CC      io/channel-buffer.o
  CC      io/channel-command.o
  CC      io/channel-file.o
  CC      io/channel-socket.o
  CC      io/channel-tls.o
  CC      io/channel-watch.o
  CC      io/channel-websock.o
  CC      io/channel-util.o
  CC      io/task.o
  CC      qom/object.o
  CC      qom/container.o
  CC      qom/qom-qobject.o
  CC      qom/object_interfaces.o
  GEN     qemu-img-cmds.h
  CC      qemu-io.o
  CC      qemu-bridge-helper.o
  CC      blockdev.o
  CC      blockdev-nbd.o
  CC      iothread.o
  CC      qdev-monitor.o
  CC      device-hotplug.o
  CC      qemu-char.o
  CC      os-posix.o
  CC      page_cache.o
  CC      accel.o
  CC      bt-host.o
  CC      bt-vhci.o
  CC      dma-helpers.o
  CC      vl.o
  CC      tpm.o
  CC      device_tree.o
  GEN     qmp-marshal.c
  CC      qmp.o
  CC      hmp.o
  CC      tcg-runtime.o
  CC      cpus-common.o
  CC      audio/audio.o
  CC      audio/noaudio.o
  CC      audio/wavaudio.o
  CC      audio/sdlaudio.o
  CC      audio/mixeng.o
  CC      audio/ossaudio.o
  CC      audio/wavcapture.o
  CC      backends/rng.o
  CC      backends/rng-egd.o
  CC      backends/rng-random.o
  CC      backends/msmouse.o
  CC      backends/testdev.o
  CC      backends/tpm.o
  CC      backends/hostmem.o
  CC      backends/hostmem-ram.o
  CC      backends/hostmem-file.o
  CC      backends/cryptodev.o
  CC      backends/cryptodev-builtin.o
  CC      block/stream.o
  CC      disas/arm.o
  CC      disas/i386.o
  CC      fsdev/qemu-fsdev-dummy.o
  CC      fsdev/qemu-fsdev-opts.o
  CC      hw/acpi/core.o
  CC      hw/acpi/piix4.o
  CC      hw/acpi/pcihp.o
  CC      hw/acpi/ich9.o
  CC      hw/acpi/tco.o
  CC      hw/acpi/cpu_hotplug.o
/tmp/qemu-test/src/backends/cryptodev-builtin.c: In function ‘cryptodev_builtin_create_cipher_session’:
/tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error: ‘QCRYPTO_CIPHER_MODE_CTR’ undeclared (first use in this function)
/tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error: (Each undeclared identifier is reported only once
/tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error: for each function it appears in.)
make: *** [backends/cryptodev-builtin.o] Error 1
make: *** Waiting for unfinished jobs....
tests/docker/Makefile.include:112: recipe for target 'docker-run' failed
make[1]: *** [docker-run] Error 2
make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-wj4_xrg5/src'
tests/docker/Makefile.include:143: recipe for target 'docker-run-test-quick@centos6' failed
make: *** [docker-run-test-quick@centos6] Error 2
=== OUTPUT END ===

Test command exited with code: 2


---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (12 preceding siblings ...)
  2016-10-20 12:25 ` [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation no-reply
@ 2016-10-25 11:20 ` Gonglei (Arei)
  2016-10-25 16:50   ` Michael S. Tsirkin
  2016-10-30 20:00 ` [Qemu-devel] " Halil Pasic
  14 siblings, 1 reply; 26+ messages in thread
From: Gonglei (Arei) @ 2016-10-25 11:20 UTC (permalink / raw)
  To: Gonglei (Arei), qemu-devel, virtio-dev
  Cc: Luonengjun, mst, stefanha, pbonzini, berrange, Huangweidong (C),
	Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter),
	arei.gonglei, eblake

Hi Michael and Stefan,

Ping...

Would you please review and/or merge this feature for Qemu 2.8
because the soft-freeze period draw near.

Thanks,
-Gonglei


> -----Original Message-----
> From: Gonglei (Arei)
> Sent: Thursday, October 20, 2016 7:46 PM
> Subject: [PATCH v9 00/12] virtio-crypto: introduce framework and device
> emulation
> 
> Hi,
> 
> The virtio crypto is a virtual crypto device as well as a kind
> of virtual hardware accelerator for virtual machines. The
> encryption and decryption requests are placed in the data
> queue and handled by the real crypto accelerators finally.
> The second queue is the control queue used to create or
> destroy sessions for symmetric algorithms and control
> some advanced features in the future. The virtio crypto
> device provides the following crypto services: CIPHER,
> MAC, HASH, AEAD etc.
> 
> TODO:
>  - add vhost-user as a high performance cryptodev backend.
>  - more crypto services support.
>  - mirgration support.
> 
> Changes since v8:
>  - fix a incorrect check condition in patch 9/12
>  - add bh as the asynchronous handler for virtio-crypto's
>    data virtqueue in patch 11/12  [Stefan]
> 
> Changes since v7:
>  - handle endianess problems in input path [Stefan]
>  - fix two possiable memory leak  [Stefan]
>  - use the iov_*() functions on in_iov/in_num instead of directly accessing the
> iovecs
>  - handle possible integer overflow [Stefan]
>  - fix a typo  [Stefan]
>  - define struct virtio_crypto_inhdr in virtio_crypto.h [Stefan]
>  - use uint8_t instead of uint32_t for status in struct virtio_crypto_inhdr
>  - remove unused field in VirtIOCryptoConf. [Stefan]
>  - squash the VIRTIO_CRYPTO_OK changes into the patches that introduced
> the old code. [Stefan]
>  - squash the previous patch 12 to patch 3 and patch 9 so that we can import
> the final version of
>    external header file from Linux. [Stefan]
> 
> Changes since v6:
>  - add copyright and license for virtio_crypto.h [Eric]
>  - add/remove (bracket pair for macro definition in virtio_crypto.h  [Eric]
>  - add missing dc->vmsd and fix a typo in patch 5
>  - fix a checkpatch.pl complaint
>  - rebase on the QEMU master branch
> 
> Changes since v5:
>  - rebase the patch 14 in v5, using the correct at the beginning of whole patch
> series. [Eric]
>  - perfect algorithm chain support in patch 12.
>  - more friendly error handler in both controlq and dataq.
>  - drop patch "virtio-crypto: emulate virtio crypto as a legacy device by default"
> because
>   we shouldn't support transitional virtio devices any more. [Michael]
>  - drop patch "virtio-crypto-test: add qtest case for virtio-crypto" because
>   libqtest doesn't support virtio-1.0 device yet.
>  - rebase the patch set based on Michael's pull request:
>     [PULL 00/33] virtio, pc: fixes and features
> 
> Changes since v4: (Thanks to Stefan)
>  - drop scatter-gather I/O identification in virtio crypto spec and corresponding
> code [Stefan]
>  - remove qcrypto perfix for cryptdov stuff [Stefan]
>  - use virtio_error() in virtio-crypto device's functions. [Stefan]
>  - fix endianness handling. [Stefan]
>  - use VMSTATE_VIRTIO_DEVICE() instead of calling register_savevm().
> [Stefan]
>  - redefine DPRINTF in virtio-crypto.h [Stefan]
>  - fix some typos [Stefan]
>  - fix other farraginous problems suggested by Stefan.
> 
> Changes since v3:
>  - rename cryptodev-gcrypt to cryptodev-buitlin. [Daniel]
>  - move cryptodev stuff from crypto/ directory to backends/ directory
>    in order to keep the crypto subsystem influence by syetem
>    emulators. [Daniel]
>  - emulate virtio-crypto device as a legacy device by default in patch 11
>  - introduce virtio-crypto qtest case in patch 12
>  - add myself as cryptdoev backends mainatainer and vitio-crypto
>    co-maintainer in patch 13
>  - add CRT support for cryptodev-builtin, it based on my previous crypto
>    patch serial queued by Daniel.
>    https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg06607.html
>  - add queue_index for qcrypto_cryptodev_backend_sym_close_session()
> 
> Changes since v2:
>  According to Daniel's comments:
>  - drop cryptodev kernel module as a cryptodev backend
>  - rename crypto stuff to cryptodev stuff
>  - change some files' license to GPLv2+
>  - remove cryptodev command line instead of QOM to define the cryptodev
> backend
>  - rename all functions and structures in crypto sub-directory.
>  - add full inline documentation for cryptodev.h
>  And:
>  - drop crypto-queue.c [Paolo]
>  - merge some patches
> 
> Great thanks to Daniel and Paolo. Please review again, thanks!
> 
> Changes since v1:
>  - rmmove mixed endian-ness handler for virtio-crypto device, just
>    use little-endian. [mst]
>  - add sg list support according virtio-crypto spec v10 (will be posted soon).
>  - fix a memory leak in session handler.
>  - add a feature page link in qemu.org
> (http://qemu-project.org/Features/VirtioCrypto)
>  - fix some trivial problems, sush as 's/Since 2.7/Since 2.8/g' in
> qapi-schema.json
>  - rebase the latest qemu master tree.
> 
> 
> This patch series realize the framework and emulation of a new
> virtio crypto device, which is similar with virtio net device.
> 
>  - I introduce the cryptodev backend as the client of virtio crypto device
>    which can be realized by different methods, such as
> cryptodev-backend-gcrypt in my series,
>    vhost-crypto kernel module, vhost-user etc.
>  - The patch set abides by the virtio crypto speccification.
>  - The virtio crypto support symmetric algorithms (including CIPHER and
> algorithm chainning)
>    at present, except HASH, MAC and AEAD services.
>  - unsupport hot plug/unplug cryptodev backend at this moment.
> 
> Firstly build QEMU with libgcrypt cryptography support.
> 
> QEMU can then be started using the following parameters:
> 
> qemu-system-x86_64 \
>     [...] \
>         -object cryptodev-backend-builtin,id=cryptodev0 \
>         -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
>     [...]
> 
> The front-end linux kernel driver (Experimental at present) is publicly accessible
> from:
> 
>    https://github.com/gongleiarei/virtio-crypto-linux-driver.git
> 
> After insmod virtio-crypto.ko, you can use cryptodev-linux test the crypto
> function
> in the guest. For example:
> 
> linux-guest:/home/gonglei/cryptodev-linux/tests # ./cipher -
> requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> virtio_crypto_aes_cbc
> AES Test passed
> requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> virtio_crypto_aes_cbc
> requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> virtio_crypto_aes_cbc
> Test passed
> 
> QEMU code also can be accessible from:
> 
>  https://github.com/gongleiarei/qemu.git
> 
>  branch virtio-crypto
> 
> For more information, please see:
>  http://qemu-project.org/Features/VirtioCrypto
> 
> 
> Gonglei (12):
>   cryptodev: introduce cryptodev backend interface
>   cryptodev: add symmetric algorithm operation stuff
>   virtio-crypto: introduce virtio_crypto.h
>   cryptodev: introduce a new cryptodev backend
>   virtio-crypto: add virtio crypto device emulation
>   virtio-crypto-pci: add virtio crypto pci support
>   virtio-crypto: set capacity of algorithms supported
>   virtio-crypto: add control queue handler
>   virtio-crypto: add data queue processing handler
>   cryptodev: introduce an unified wrapper for crypto operation
>   virtio-crypto: using bh to handle dataq's requests
>   virtio-crypto: add myself as virtio-crypto and cryptodev backends
>     maintainer
> 
>  MAINTAINERS                                    |  13 +
>  backends/Makefile.objs                         |   3 +
>  backends/cryptodev-builtin.c                   | 351 ++++++++++
>  backends/cryptodev.c                           | 245 +++++++
>  hw/virtio/Makefile.objs                        |   2 +
>  hw/virtio/virtio-crypto-pci.c                  |  77 +++
>  hw/virtio/virtio-crypto.c                      | 884
> +++++++++++++++++++++++++
>  hw/virtio/virtio-pci.h                         |  15 +
>  include/hw/virtio/virtio-crypto.h              |  94 +++
>  include/standard-headers/linux/virtio_crypto.h | 420 ++++++++++++
>  include/standard-headers/linux/virtio_ids.h    |   2 +-
>  include/sysemu/cryptodev.h                     | 295 +++++++++
>  qemu-options.hx                                |  18 +
>  13 files changed, 2418 insertions(+), 1 deletion(-)
>  create mode 100644 backends/cryptodev-builtin.c
>  create mode 100644 backends/cryptodev.c
>  create mode 100644 hw/virtio/virtio-crypto-pci.c
>  create mode 100644 hw/virtio/virtio-crypto.c
>  create mode 100644 include/hw/virtio/virtio-crypto.h
>  create mode 100644 include/standard-headers/linux/virtio_crypto.h
>  create mode 100644 include/sysemu/cryptodev.h
> 
> --
> 1.8.3.1
> 

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-25 11:20 ` Gonglei (Arei)
@ 2016-10-25 16:50   ` Michael S. Tsirkin
  2016-10-26  0:54     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
  0 siblings, 1 reply; 26+ messages in thread
From: Michael S. Tsirkin @ 2016-10-25 16:50 UTC (permalink / raw)
  To: Gonglei (Arei)
  Cc: qemu-devel, virtio-dev, Luonengjun, stefanha, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter),
	arei.gonglei, eblake

Will do.
Meanwhile, could you please create and open the oasis tracker
in jira, so we can vote on it?


On Tue, Oct 25, 2016 at 11:20:35AM +0000, Gonglei (Arei) wrote:
> Hi Michael and Stefan,
> 
> Ping...
> 
> Would you please review and/or merge this feature for Qemu 2.8
> because the soft-freeze period draw near.
> 
> Thanks,
> -Gonglei
> 
> 
> > -----Original Message-----
> > From: Gonglei (Arei)
> > Sent: Thursday, October 20, 2016 7:46 PM
> > Subject: [PATCH v9 00/12] virtio-crypto: introduce framework and device
> > emulation
> > 
> > Hi,
> > 
> > The virtio crypto is a virtual crypto device as well as a kind
> > of virtual hardware accelerator for virtual machines. The
> > encryption and decryption requests are placed in the data
> > queue and handled by the real crypto accelerators finally.
> > The second queue is the control queue used to create or
> > destroy sessions for symmetric algorithms and control
> > some advanced features in the future. The virtio crypto
> > device provides the following crypto services: CIPHER,
> > MAC, HASH, AEAD etc.
> > 
> > TODO:
> >  - add vhost-user as a high performance cryptodev backend.
> >  - more crypto services support.
> >  - mirgration support.
> > 
> > Changes since v8:
> >  - fix a incorrect check condition in patch 9/12
> >  - add bh as the asynchronous handler for virtio-crypto's
> >    data virtqueue in patch 11/12  [Stefan]
> > 
> > Changes since v7:
> >  - handle endianess problems in input path [Stefan]
> >  - fix two possiable memory leak  [Stefan]
> >  - use the iov_*() functions on in_iov/in_num instead of directly accessing the
> > iovecs
> >  - handle possible integer overflow [Stefan]
> >  - fix a typo  [Stefan]
> >  - define struct virtio_crypto_inhdr in virtio_crypto.h [Stefan]
> >  - use uint8_t instead of uint32_t for status in struct virtio_crypto_inhdr
> >  - remove unused field in VirtIOCryptoConf. [Stefan]
> >  - squash the VIRTIO_CRYPTO_OK changes into the patches that introduced
> > the old code. [Stefan]
> >  - squash the previous patch 12 to patch 3 and patch 9 so that we can import
> > the final version of
> >    external header file from Linux. [Stefan]
> > 
> > Changes since v6:
> >  - add copyright and license for virtio_crypto.h [Eric]
> >  - add/remove (bracket pair for macro definition in virtio_crypto.h  [Eric]
> >  - add missing dc->vmsd and fix a typo in patch 5
> >  - fix a checkpatch.pl complaint
> >  - rebase on the QEMU master branch
> > 
> > Changes since v5:
> >  - rebase the patch 14 in v5, using the correct at the beginning of whole patch
> > series. [Eric]
> >  - perfect algorithm chain support in patch 12.
> >  - more friendly error handler in both controlq and dataq.
> >  - drop patch "virtio-crypto: emulate virtio crypto as a legacy device by default"
> > because
> >   we shouldn't support transitional virtio devices any more. [Michael]
> >  - drop patch "virtio-crypto-test: add qtest case for virtio-crypto" because
> >   libqtest doesn't support virtio-1.0 device yet.
> >  - rebase the patch set based on Michael's pull request:
> >     [PULL 00/33] virtio, pc: fixes and features
> > 
> > Changes since v4: (Thanks to Stefan)
> >  - drop scatter-gather I/O identification in virtio crypto spec and corresponding
> > code [Stefan]
> >  - remove qcrypto perfix for cryptdov stuff [Stefan]
> >  - use virtio_error() in virtio-crypto device's functions. [Stefan]
> >  - fix endianness handling. [Stefan]
> >  - use VMSTATE_VIRTIO_DEVICE() instead of calling register_savevm().
> > [Stefan]
> >  - redefine DPRINTF in virtio-crypto.h [Stefan]
> >  - fix some typos [Stefan]
> >  - fix other farraginous problems suggested by Stefan.
> > 
> > Changes since v3:
> >  - rename cryptodev-gcrypt to cryptodev-buitlin. [Daniel]
> >  - move cryptodev stuff from crypto/ directory to backends/ directory
> >    in order to keep the crypto subsystem influence by syetem
> >    emulators. [Daniel]
> >  - emulate virtio-crypto device as a legacy device by default in patch 11
> >  - introduce virtio-crypto qtest case in patch 12
> >  - add myself as cryptdoev backends mainatainer and vitio-crypto
> >    co-maintainer in patch 13
> >  - add CRT support for cryptodev-builtin, it based on my previous crypto
> >    patch serial queued by Daniel.
> >    https://lists.gnu.org/archive/html/qemu-devel/2016-09/msg06607.html
> >  - add queue_index for qcrypto_cryptodev_backend_sym_close_session()
> > 
> > Changes since v2:
> >  According to Daniel's comments:
> >  - drop cryptodev kernel module as a cryptodev backend
> >  - rename crypto stuff to cryptodev stuff
> >  - change some files' license to GPLv2+
> >  - remove cryptodev command line instead of QOM to define the cryptodev
> > backend
> >  - rename all functions and structures in crypto sub-directory.
> >  - add full inline documentation for cryptodev.h
> >  And:
> >  - drop crypto-queue.c [Paolo]
> >  - merge some patches
> > 
> > Great thanks to Daniel and Paolo. Please review again, thanks!
> > 
> > Changes since v1:
> >  - rmmove mixed endian-ness handler for virtio-crypto device, just
> >    use little-endian. [mst]
> >  - add sg list support according virtio-crypto spec v10 (will be posted soon).
> >  - fix a memory leak in session handler.
> >  - add a feature page link in qemu.org
> > (http://qemu-project.org/Features/VirtioCrypto)
> >  - fix some trivial problems, sush as 's/Since 2.7/Since 2.8/g' in
> > qapi-schema.json
> >  - rebase the latest qemu master tree.
> > 
> > 
> > This patch series realize the framework and emulation of a new
> > virtio crypto device, which is similar with virtio net device.
> > 
> >  - I introduce the cryptodev backend as the client of virtio crypto device
> >    which can be realized by different methods, such as
> > cryptodev-backend-gcrypt in my series,
> >    vhost-crypto kernel module, vhost-user etc.
> >  - The patch set abides by the virtio crypto speccification.
> >  - The virtio crypto support symmetric algorithms (including CIPHER and
> > algorithm chainning)
> >    at present, except HASH, MAC and AEAD services.
> >  - unsupport hot plug/unplug cryptodev backend at this moment.
> > 
> > Firstly build QEMU with libgcrypt cryptography support.
> > 
> > QEMU can then be started using the following parameters:
> > 
> > qemu-system-x86_64 \
> >     [...] \
> >         -object cryptodev-backend-builtin,id=cryptodev0 \
> >         -device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
> >     [...]
> > 
> > The front-end linux kernel driver (Experimental at present) is publicly accessible
> > from:
> > 
> >    https://github.com/gongleiarei/virtio-crypto-linux-driver.git
> > 
> > After insmod virtio-crypto.ko, you can use cryptodev-linux test the crypto
> > function
> > in the guest. For example:
> > 
> > linux-guest:/home/gonglei/cryptodev-linux/tests # ./cipher -
> > requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> > virtio_crypto_aes_cbc
> > AES Test passed
> > requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> > virtio_crypto_aes_cbc
> > requested cipher CRYPTO_AES_CBC, got cbc(aes) with driver
> > virtio_crypto_aes_cbc
> > Test passed
> > 
> > QEMU code also can be accessible from:
> > 
> >  https://github.com/gongleiarei/qemu.git
> > 
> >  branch virtio-crypto
> > 
> > For more information, please see:
> >  http://qemu-project.org/Features/VirtioCrypto
> > 
> > 
> > Gonglei (12):
> >   cryptodev: introduce cryptodev backend interface
> >   cryptodev: add symmetric algorithm operation stuff
> >   virtio-crypto: introduce virtio_crypto.h
> >   cryptodev: introduce a new cryptodev backend
> >   virtio-crypto: add virtio crypto device emulation
> >   virtio-crypto-pci: add virtio crypto pci support
> >   virtio-crypto: set capacity of algorithms supported
> >   virtio-crypto: add control queue handler
> >   virtio-crypto: add data queue processing handler
> >   cryptodev: introduce an unified wrapper for crypto operation
> >   virtio-crypto: using bh to handle dataq's requests
> >   virtio-crypto: add myself as virtio-crypto and cryptodev backends
> >     maintainer
> > 
> >  MAINTAINERS                                    |  13 +
> >  backends/Makefile.objs                         |   3 +
> >  backends/cryptodev-builtin.c                   | 351 ++++++++++
> >  backends/cryptodev.c                           | 245 +++++++
> >  hw/virtio/Makefile.objs                        |   2 +
> >  hw/virtio/virtio-crypto-pci.c                  |  77 +++
> >  hw/virtio/virtio-crypto.c                      | 884
> > +++++++++++++++++++++++++
> >  hw/virtio/virtio-pci.h                         |  15 +
> >  include/hw/virtio/virtio-crypto.h              |  94 +++
> >  include/standard-headers/linux/virtio_crypto.h | 420 ++++++++++++
> >  include/standard-headers/linux/virtio_ids.h    |   2 +-
> >  include/sysemu/cryptodev.h                     | 295 +++++++++
> >  qemu-options.hx                                |  18 +
> >  13 files changed, 2418 insertions(+), 1 deletion(-)
> >  create mode 100644 backends/cryptodev-builtin.c
> >  create mode 100644 backends/cryptodev.c
> >  create mode 100644 hw/virtio/virtio-crypto-pci.c
> >  create mode 100644 hw/virtio/virtio-crypto.c
> >  create mode 100644 include/hw/virtio/virtio-crypto.h
> >  create mode 100644 include/standard-headers/linux/virtio_crypto.h
> >  create mode 100644 include/sysemu/cryptodev.h
> > 
> > --
> > 1.8.3.1
> > 

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-25 16:50   ` Michael S. Tsirkin
@ 2016-10-26  0:54     ` Gonglei (Arei)
  2016-10-27 16:12       ` Michael S. Tsirkin
  0 siblings, 1 reply; 26+ messages in thread
From: Gonglei (Arei) @ 2016-10-26  0:54 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, virtio-dev, Luonengjun, stefanha, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter),
	arei.gonglei, eblake

Hi Michael,


> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Michael S. Tsirkin
> Sent: Wednesday, October 26, 2016 12:51 AM
> Subject: [virtio-dev] Re: [PATCH v9 00/12] virtio-crypto: introduce framework
> and device emulation
> 
> Will do.
> Meanwhile, could you please create and open the oasis tracker
> in jira, so we can vote on it?
> 
I created an oasis issue one month ago:

https://issues.oasis-open.org/i#browse/VIRTIO-153

I'll update the status based on the newest version about virtio-crypto spec.


Regards,
-Gonglei

> 
> On Tue, Oct 25, 2016 at 11:20:35AM +0000, Gonglei (Arei) wrote:
> > Hi Michael and Stefan,
> >
> > Ping...
> >
> > Would you please review and/or merge this feature for Qemu 2.8
> > because the soft-freeze period draw near.
> >
> > Thanks,
> > -Gonglei
> >
> >

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-20 12:25 ` [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation no-reply
@ 2016-10-27  8:03   ` Gonglei (Arei)
  0 siblings, 0 replies; 26+ messages in thread
From: Gonglei (Arei) @ 2016-10-27  8:03 UTC (permalink / raw)
  To: qemu-devel
  Cc: famz, virtio-dev, Huangweidong (C),
	Claudio Fontana, mst, xin.zeng, Hanweidong (Randy),
	Luonengjun, agraf, nmorey, mike.caraman, stefanha, Zhoujian (jay,
	Euler), pbonzini, Huangpeng (Peter), vincent.jardin, Wubin (H),
	arei.gonglei

Hi Michael,

Warm reminder: 

The dependency (crypto stuff) of virito-crypto patch series had been merged,
so the building failure was gone.

Regards,
-Gonglei


> -----Original Message-----
> From: no-reply@patchew.org [mailto:no-reply@patchew.org]
> Sent: Thursday, October 20, 2016 8:26 PM
> To: Gonglei (Arei)
> Cc: famz@redhat.com; qemu-devel@nongnu.org;
> virtio-dev@lists.oasis-open.org; Huangweidong (C); Claudio Fontana;
> mst@redhat.com; xin.zeng@intel.com; Hanweidong (Randy); Luonengjun;
> agraf@suse.de; nmorey@kalray.eu; mike.caraman@nxp.com; Gonglei (Arei);
> stefanha@redhat.com; Zhoujian (jay, Euler); pbonzini@redhat.com;
> Huangpeng (Peter); vincent.jardin@6wind.com; Wubin (H);
> arei.gonglei@hotmail.com
> Subject: Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework
> and device emulation
> 
> Hi,
> 
> Your series failed automatic build test. Please find the testing commands and
> their output below. If you have docker installed, you can probably reproduce it
> locally.
> 
> Type: series
> Message-id: 1476963957-176296-1-git-send-email-arei.gonglei@huawei.com
> Subject: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and
> device emulation
> 
[snip]

>   CC      hw/acpi/cpu_hotplug.o
> /tmp/qemu-test/src/backends/cryptodev-builtin.c: In function
> ‘cryptodev_builtin_create_cipher_session’:
> /tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error:
> ‘QCRYPTO_CIPHER_MODE_CTR’ undeclared (first use in this function)
> /tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error: (Each undeclared
> identifier is reported only once
> /tmp/qemu-test/src/backends/cryptodev-builtin.c:169: error: for each function
> it appears in.)
> make: *** [backends/cryptodev-builtin.o] Error 1
> make: *** Waiting for unfinished jobs....
> tests/docker/Makefile.include:112: recipe for target 'docker-run' failed
> make[1]: *** [docker-run] Error 2
> make[1]: Leaving directory '/var/tmp/patchew-tester-tmp-wj4_xrg5/src'
> tests/docker/Makefile.include:143: recipe for target
> 'docker-run-test-quick@centos6' failed
> make: *** [docker-run-test-quick@centos6] Error 2
> === OUTPUT END ===
> 
> Test command exited with code: 2
> 
> 
> ---
> Email generated automatically by Patchew [http://patchew.org/].
> Please send your feedback to patchew-devel@freelists.org

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-26  0:54     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
@ 2016-10-27 16:12       ` Michael S. Tsirkin
  0 siblings, 0 replies; 26+ messages in thread
From: Michael S. Tsirkin @ 2016-10-27 16:12 UTC (permalink / raw)
  To: Gonglei (Arei)
  Cc: qemu-devel, virtio-dev, Luonengjun, stefanha, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter),
	arei.gonglei, eblake

On Wed, Oct 26, 2016 at 12:54:45AM +0000, Gonglei (Arei) wrote:
> Hi Michael,
> 
> 
> > -----Original Message-----
> > From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> > On Behalf Of Michael S. Tsirkin
> > Sent: Wednesday, October 26, 2016 12:51 AM
> > Subject: [virtio-dev] Re: [PATCH v9 00/12] virtio-crypto: introduce framework
> > and device emulation
> > 
> > Will do.
> > Meanwhile, could you please create and open the oasis tracker
> > in jira, so we can vote on it?
> > 
> I created an oasis issue one month ago:
> 
> https://issues.oasis-open.org/i#browse/VIRTIO-153
> 
> I'll update the status based on the newest version about virtio-crypto spec.
> 
> 
> Regards,
> -Gonglei

Good. Once you feel it's time to vote on it, pls open
it according to "Jira usage guidelines" email.

> > 
> > On Tue, Oct 25, 2016 at 11:20:35AM +0000, Gonglei (Arei) wrote:
> > > Hi Michael and Stefan,
> > >
> > > Ping...
> > >
> > > Would you please review and/or merge this feature for Qemu 2.8
> > > because the soft-freeze period draw near.
> > >
> > > Thanks,
> > > -Gonglei
> > >
> > >

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

* Re: [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler
  2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler Gonglei
@ 2016-10-27 16:59   ` Michael S. Tsirkin
  2016-10-28  0:50     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
  0 siblings, 1 reply; 26+ messages in thread
From: Michael S. Tsirkin @ 2016-10-27 16:59 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, stefanha, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng, arei.gonglei, eblake

On Thu, Oct 20, 2016 at 07:45:54PM +0800, Gonglei wrote:
> Introduces VirtIOCryptoReq structure to store
> crypto request so that we can easily support
> asynchronous crypto operation in the future.
> 
> At present, we only support cipher and algorithm
> chaining.
> 
> Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> ---
>  hw/virtio/virtio-crypto.c         | 358 +++++++++++++++++++++++++++++++++++++-
>  include/hw/virtio/virtio-crypto.h |   4 +
>  2 files changed, 361 insertions(+), 1 deletion(-)
> 
> diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> index 4be65e0..eabc61f 100644
> --- a/hw/virtio/virtio-crypto.c
> +++ b/hw/virtio/virtio-crypto.c
> @@ -311,6 +311,362 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
>      } /* end for loop */
>  }
>  
> +static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq,
> +                                VirtIOCryptoReq *req)
> +{
> +    req->vcrypto = vcrypto;
> +    req->vq = vq;
> +    req->in = NULL;
> +    req->in_iov = NULL;
> +    req->in_num = 0;
> +    req->in_len = 0;
> +    req->flags = CRYPTODEV_BACKEND_ALG__MAX;
> +    req->u.sym_op_info = NULL;
> +}
> +
> +static void virtio_crypto_free_request(VirtIOCryptoReq *req)
> +{
> +    if (req) {
> +        if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> +            g_free(req->u.sym_op_info);
> +        }
> +        g_free(req);
> +    }
> +}
> +
> +static void
> +virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
> +                VirtIOCryptoReq *req,
> +                uint32_t status,
> +                CryptoDevBackendSymOpInfo *sym_op_info)
> +{
> +    size_t s, len;
> +
> +    if (status != VIRTIO_CRYPTO_OK) {
> +        return;
> +    }
> +
> +    len = sym_op_info->dst_len;
> +    /* Save the cipher result */
> +    s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len);
> +    if (s != len) {
> +        virtio_error(vdev, "virtio-crypto dest data incorrect");
> +        return;
> +    }
> +
> +    iov_discard_front(&req->in_iov, &req->in_num, len);
> +
> +    if (sym_op_info->op_type ==
> +                      VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
> +        /* Save the digest result */
> +        s = iov_from_buf(req->in_iov, req->in_num, 0,
> +                         sym_op_info->digest_result,
> +                         sym_op_info->digest_result_len);
> +        if (s != sym_op_info->digest_result_len) {
> +            virtio_error(vdev, "virtio-crypto digest result incorrect");
> +        }
> +    }
> +}
> +
> +static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t status)
> +{
> +    VirtIOCrypto *vcrypto = req->vcrypto;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> +
> +    if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> +        virtio_crypto_sym_input_data_helper(vdev, req, status,
> +                                            req->u.sym_op_info);
> +    }
> +    stb_p(&req->in->status, status);
> +    virtqueue_push(req->vq, &req->elem, req->in_len);
> +    virtio_notify(vdev, req->vq);
> +}
> +
> +static VirtIOCryptoReq *
> +virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
> +{
> +    VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq));
> +
> +    if (req) {
> +        virtio_crypto_init_request(s, vq, req);
> +    }
> +    return req;
> +}
> +
> +static CryptoDevBackendSymOpInfo *
> +virtio_crypto_sym_op_helper(VirtIODevice *vdev,
> +           struct virtio_crypto_cipher_para *cipher_para,
> +           struct virtio_crypto_alg_chain_data_para *alg_chain_para,
> +           struct iovec *iov, unsigned int out_num)
> +{
> +    CryptoDevBackendSymOpInfo *op_info;
> +    uint32_t src_len = 0, dst_len = 0;
> +    uint32_t iv_len = 0;
> +    uint32_t aad_len = 0, hash_result_len = 0;
> +    uint32_t hash_start_src_offset = 0, len_to_hash = 0;
> +    uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
> +
> +    size_t max_len, curr_size = 0;
> +    size_t s;
> +
> +    /* Plain cipher */
> +    if (cipher_para) {
> +        iv_len = virtio_ldl_p(vdev, &cipher_para->iv_len);
> +        src_len = virtio_ldl_p(vdev, &cipher_para->src_data_len);
> +        dst_len = virtio_ldl_p(vdev, &cipher_para->dst_data_len);
> +    } else if (alg_chain_para) { /* Algorithm chain */
> +        iv_len = virtio_ldl_p(vdev, &alg_chain_para->iv_len);
> +        src_len = virtio_ldl_p(vdev, &alg_chain_para->src_data_len);
> +        dst_len = virtio_ldl_p(vdev, &alg_chain_para->dst_data_len);
> +
> +        aad_len = virtio_ldl_p(vdev, &alg_chain_para->aad_len);
> +        hash_result_len = virtio_ldl_p(vdev,
> +                              &alg_chain_para->hash_result_len);
> +        hash_start_src_offset = virtio_ldl_p(vdev,
> +                         &alg_chain_para->hash_start_src_offset);
> +        cipher_start_src_offset = virtio_ldl_p(vdev,
> +                         &alg_chain_para->cipher_start_src_offset);
> +        len_to_cipher = virtio_ldl_p(vdev, &alg_chain_para->len_to_cipher);
> +        len_to_hash = virtio_ldl_p(vdev, &alg_chain_para->len_to_hash);
> +    } else {
> +        return NULL;
> +    }
> +


You don't need virtio_ wrappers for modern devices I think. Just use LE
accessors.

> +    max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
> +    if (unlikely(max_len > LONG_MAX - sizeof(CryptoDevBackendSymOpInfo))) {
> +        virtio_error(vdev, "virtio-crypto too big length");
> +        return NULL;
> +    }
> +
> +    op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);

Wow this can allocate up to 2^64 bytes, triggerable by guest. Not nice.
Also, max size depends on long size and guest has no way
to know it. Not nice either.

Add max size in device config?

> +    op_info->iv_len = iv_len;
> +    op_info->src_len = src_len;
> +    op_info->dst_len = dst_len;
> +    op_info->aad_len = aad_len;
> +    op_info->digest_result_len = hash_result_len;
> +    op_info->hash_start_src_offset = hash_start_src_offset;
> +    op_info->len_to_hash = len_to_hash;
> +    op_info->cipher_start_src_offset = cipher_start_src_offset;
> +    op_info->len_to_cipher = len_to_cipher;
> +    /* Handle the initilization vector */
> +    if (op_info->iv_len > 0) {
> +        DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
> +        op_info->iv = op_info->data + curr_size;

This shows that splitting a single file like this
is not helpful. I wanted to know how is data initialized
and what makes this math safe, and couldn't figure it out
from this patch alone.


> +
> +        s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len);
> +        if (unlikely(s != op_info->iv_len)) {
> +            virtio_error(vdev, "virtio-crypto iv incorrect");
> +            goto err;
> +        }
> +        iov_discard_front(&iov, &out_num, op_info->iv_len);
> +        curr_size += op_info->iv_len;
> +    }
> +
> +    /* Handle additional authentication data if exist */

-> if it exists

> +    if (op_info->aad_len > 0) {
> +        DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len);
> +        op_info->aad_data = op_info->data + curr_size;
> +
> +        s = iov_to_buf(iov, out_num, 0, op_info->aad_data, op_info->aad_len);
> +        if (unlikely(s != op_info->aad_len)) {
> +            virtio_error(vdev, "virtio-crypto additional auth data incorrect");
> +            goto err;
> +        }
> +        iov_discard_front(&iov, &out_num, op_info->aad_len);
> +
> +        curr_size += op_info->aad_len;
> +    }
> +
> +    /* Handle the source data */
> +    if (op_info->src_len > 0) {
> +        DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len);
> +        op_info->src = op_info->data + curr_size;
> +
> +        s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len);
> +        if (unlikely(s != op_info->src_len)) {
> +            virtio_error(vdev, "virtio-crypto source data incorrect");
> +            goto err;
> +        }
> +        iov_discard_front(&iov, &out_num, op_info->src_len);
> +
> +        curr_size += op_info->src_len;
> +    }
> +
> +    /* Handle the destination data */
> +    op_info->dst = op_info->data + curr_size;
> +    curr_size += op_info->dst_len;
> +
> +    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);
> +
> +    /* Handle the hash digest result */
> +    if (hash_result_len > 0) {
> +        DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len);
> +        op_info->digest_result = op_info->data + curr_size;
> +    }
> +
> +    return op_info;
> +
> +err:
> +    g_free(op_info);
> +    return NULL;
> +}
> +
> +static int
> +virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
> +               struct virtio_crypto_sym_data_req *req,
> +               CryptoDevBackendSymOpInfo **sym_op_info,
> +               struct iovec *iov, unsigned int out_num)
> +{
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> +    uint32_t op_type;
> +    CryptoDevBackendSymOpInfo *op_info;
> +
> +    op_type = virtio_ldl_p(vdev, &req->op_type);
> +
> +    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
> +        op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
> +                                              NULL, iov, out_num);
> +        if (!op_info) {
> +            return -EFAULT;
> +        }
> +        op_info->op_type = op_type;
> +    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
> +        op_info = virtio_crypto_sym_op_helper(vdev, NULL,
> +                                              &req->u.chain.para,
> +                                              iov, out_num);
> +        if (!op_info) {
> +            return -EFAULT;
> +        }
> +        op_info->op_type = op_type;
> +    } else {
> +        /* VIRTIO_CRYPTO_SYM_OP_NONE */
> +        error_report("virtio-crypto unsupported cipher type");
> +        return -VIRTIO_CRYPTO_NOTSUPP;

virtio_error?

> +    }
> +
> +    *sym_op_info = op_info;
> +
> +    return 0;
> +}
> +
> +static int
> +virtio_crypto_handle_request(VirtIOCryptoReq *request)
> +{
> +    VirtIOCrypto *vcrypto = request->vcrypto;
> +    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> +    VirtQueueElement *elem = &request->elem;
> +    int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq));
> +    struct virtio_crypto_op_data_req req;
> +    int ret;
> +    struct iovec *in_iov;
> +    struct iovec *out_iov;
> +    unsigned in_num;
> +    unsigned out_num;
> +    uint32_t opcode;
> +    uint8_t status = VIRTIO_CRYPTO_ERR;
> +    uint64_t session_id;
> +    CryptoDevBackendSymOpInfo *sym_op_info = NULL;
> +    Error *local_err = NULL;
> +
> +    if (elem->out_num < 1 || elem->in_num < 1) {
> +        virtio_error(vdev, "virtio-crypto dataq missing headers");
> +        return -1;
> +    }
> +
> +    out_num = elem->out_num;
> +    out_iov = elem->out_sg;
> +    in_num = elem->in_num;
> +    in_iov = elem->in_sg;
> +    if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req))
> +                != sizeof(req))) {
> +        virtio_error(vdev, "virtio-crypto request outhdr too short");
> +        return -1;
> +    }
> +    iov_discard_front(&out_iov, &out_num, sizeof(req));
> +
> +    if (in_iov[in_num - 1].iov_len <
> +            sizeof(struct virtio_crypto_inhdr)) {
> +        virtio_error(vdev, "virtio-crypto request inhdr too short");
> +        return -1;
> +    }
> +    /* We always touch the last byte, so just see how big in_iov is. */
> +    request->in_len = iov_size(in_iov, in_num);
> +    request->in = (void *)in_iov[in_num - 1].iov_base
> +              + in_iov[in_num - 1].iov_len
> +              - sizeof(struct virtio_crypto_inhdr);
> +    iov_discard_back(in_iov, &in_num, sizeof(struct virtio_crypto_inhdr));
> +
> +    /*
> +     * The length of operation result, including dest_data
> +     * and digest_result if exist.
> +     */
> +    request->in_num = in_num;
> +    request->in_iov = in_iov;
> +
> +    opcode = virtio_ldl_p(vdev, &req.header.opcode);
> +    session_id = virtio_ldq_p(vdev, &req.header.session_id);
> +
> +    switch (opcode) {
> +    case VIRTIO_CRYPTO_CIPHER_ENCRYPT:
> +    case VIRTIO_CRYPTO_CIPHER_DECRYPT:
> +        ret = virtio_crypto_handle_sym_req(vcrypto,
> +                         &req.u.sym_req,
> +                         &sym_op_info,
> +                         out_iov, out_num);
> +        /* Serious errors, need to reset virtio crypto device */
> +        if (ret == -EFAULT) {
> +            return -1;
> +        } else if (ret == -VIRTIO_CRYPTO_NOTSUPP) {
> +            virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP);
> +            virtio_crypto_free_request(request);
> +        } else {
> +            sym_op_info->session_id = session_id;
> +
> +            /* Set request's parameter */
> +            request->flags = CRYPTODEV_BACKEND_ALG_SYM;
> +            request->u.sym_op_info = sym_op_info;
> +            ret = cryptodev_backend_sym_operation(vcrypto->cryptodev,
> +                                    sym_op_info, queue_index, &local_err);
> +            if (ret < 0) {
> +                status = VIRTIO_CRYPTO_ERR;
> +                if (local_err) {
> +                    error_report_err(local_err);
> +                }
> +            } else { /* ret >= 0 */
> +                status = VIRTIO_CRYPTO_OK;
> +            }
> +            virtio_crypto_req_complete(request, status);
> +            virtio_crypto_free_request(request);
> +        }
> +        break;
> +    case VIRTIO_CRYPTO_HASH:
> +    case VIRTIO_CRYPTO_MAC:
> +    case VIRTIO_CRYPTO_AEAD_ENCRYPT:
> +    case VIRTIO_CRYPTO_AEAD_DECRYPT:
> +    default:
> +        error_report("virtio-crypto unsupported dataq opcode: %u",
> +                     opcode);
> +        virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP);
> +        virtio_crypto_free_request(request);
> +    }
> +
> +    return 0;
> +}
> +
> +static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
> +{
> +    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
> +    VirtIOCryptoReq *req;
> +
> +    while ((req = virtio_crypto_get_request(vcrypto, vq))) {
> +        if (virtio_crypto_handle_request(req) < 0) {
> +            virtqueue_detach_element(req->vq, &req->elem, 0);
> +            virtio_crypto_free_request(req);
> +            break;
> +        }
> +    }
> +}
> +
>  static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
>                                             uint64_t features,
>                                             Error **errp)
> @@ -370,7 +726,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
>      vcrypto->curr_queues = 1;
>  
>      for (i = 0; i < vcrypto->max_queues; i++) {
> -        virtio_add_queue(vdev, 1024, NULL);
> +        virtio_add_queue(vdev, 1024, virtio_crypto_handle_dataq);
>      }
>  
>      vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
> diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
> index 4a4b3da..2628056 100644
> --- a/include/hw/virtio/virtio-crypto.h
> +++ b/include/hw/virtio/virtio-crypto.h
> @@ -58,6 +58,10 @@ typedef struct VirtIOCryptoReq {
>      VirtQueueElement elem;
>      /* flags of operation, such as type of algorithm */
>      uint32_t flags;
> +    struct virtio_crypto_inhdr *in;
> +    struct iovec *in_iov; /* Head address of dest iovec */
> +    unsigned int in_num; /* Number of dest iovec */
> +    size_t in_len;
>      VirtQueue *vq;
>      struct VirtIOCrypto *vcrypto;
>      union {
> -- 
> 1.8.3.1
> 

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v9 09/12] virtio-crypto: add data queue processing handler
  2016-10-27 16:59   ` Michael S. Tsirkin
@ 2016-10-28  0:50     ` Gonglei (Arei)
  0 siblings, 0 replies; 26+ messages in thread
From: Gonglei (Arei) @ 2016-10-28  0:50 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: qemu-devel, virtio-dev, Luonengjun, stefanha, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter),
	arei.gonglei, eblake

Hi Michael,

Thanks for your comments.

> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Michael S. Tsirkin
> Sent: Friday, October 28, 2016 12:59 AM
> Subject: [virtio-dev] Re: [PATCH v9 09/12] virtio-crypto: add data queue
> processing handler
> 
> On Thu, Oct 20, 2016 at 07:45:54PM +0800, Gonglei wrote:
> > Introduces VirtIOCryptoReq structure to store
> > crypto request so that we can easily support
> > asynchronous crypto operation in the future.
> >
> > At present, we only support cipher and algorithm
> > chaining.
> >
> > Signed-off-by: Gonglei <arei.gonglei@huawei.com>
> > ---
> >  hw/virtio/virtio-crypto.c         | 358
> +++++++++++++++++++++++++++++++++++++-
> >  include/hw/virtio/virtio-crypto.h |   4 +
> >  2 files changed, 361 insertions(+), 1 deletion(-)
> >
> > diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
> > index 4be65e0..eabc61f 100644
> > --- a/hw/virtio/virtio-crypto.c
> > +++ b/hw/virtio/virtio-crypto.c
> > @@ -311,6 +311,362 @@ static void virtio_crypto_handle_ctrl(VirtIODevice
> *vdev, VirtQueue *vq)
> >      } /* end for loop */
> >  }
> >
> > +static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq,
> > +                                VirtIOCryptoReq *req)
> > +{
> > +    req->vcrypto = vcrypto;
> > +    req->vq = vq;
> > +    req->in = NULL;
> > +    req->in_iov = NULL;
> > +    req->in_num = 0;
> > +    req->in_len = 0;
> > +    req->flags = CRYPTODEV_BACKEND_ALG__MAX;
> > +    req->u.sym_op_info = NULL;
> > +}
> > +
> > +static void virtio_crypto_free_request(VirtIOCryptoReq *req)
> > +{
> > +    if (req) {
> > +        if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> > +            g_free(req->u.sym_op_info);
> > +        }
> > +        g_free(req);
> > +    }
> > +}
> > +
> > +static void
> > +virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
> > +                VirtIOCryptoReq *req,
> > +                uint32_t status,
> > +                CryptoDevBackendSymOpInfo *sym_op_info)
> > +{
> > +    size_t s, len;
> > +
> > +    if (status != VIRTIO_CRYPTO_OK) {
> > +        return;
> > +    }
> > +
> > +    len = sym_op_info->dst_len;
> > +    /* Save the cipher result */
> > +    s = iov_from_buf(req->in_iov, req->in_num, 0, sym_op_info->dst, len);
> > +    if (s != len) {
> > +        virtio_error(vdev, "virtio-crypto dest data incorrect");
> > +        return;
> > +    }
> > +
> > +    iov_discard_front(&req->in_iov, &req->in_num, len);
> > +
> > +    if (sym_op_info->op_type ==
> > +
> VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
> > +        /* Save the digest result */
> > +        s = iov_from_buf(req->in_iov, req->in_num, 0,
> > +                         sym_op_info->digest_result,
> > +                         sym_op_info->digest_result_len);
> > +        if (s != sym_op_info->digest_result_len) {
> > +            virtio_error(vdev, "virtio-crypto digest result incorrect");
> > +        }
> > +    }
> > +}
> > +
> > +static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint8_t
> status)
> > +{
> > +    VirtIOCrypto *vcrypto = req->vcrypto;
> > +    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> > +
> > +    if (req->flags == CRYPTODEV_BACKEND_ALG_SYM) {
> > +        virtio_crypto_sym_input_data_helper(vdev, req, status,
> > +                                            req->u.sym_op_info);
> > +    }
> > +    stb_p(&req->in->status, status);
> > +    virtqueue_push(req->vq, &req->elem, req->in_len);
> > +    virtio_notify(vdev, req->vq);
> > +}
> > +
> > +static VirtIOCryptoReq *
> > +virtio_crypto_get_request(VirtIOCrypto *s, VirtQueue *vq)
> > +{
> > +    VirtIOCryptoReq *req = virtqueue_pop(vq, sizeof(VirtIOCryptoReq));
> > +
> > +    if (req) {
> > +        virtio_crypto_init_request(s, vq, req);
> > +    }
> > +    return req;
> > +}
> > +
> > +static CryptoDevBackendSymOpInfo *
> > +virtio_crypto_sym_op_helper(VirtIODevice *vdev,
> > +           struct virtio_crypto_cipher_para *cipher_para,
> > +           struct virtio_crypto_alg_chain_data_para *alg_chain_para,
> > +           struct iovec *iov, unsigned int out_num)
> > +{
> > +    CryptoDevBackendSymOpInfo *op_info;
> > +    uint32_t src_len = 0, dst_len = 0;
> > +    uint32_t iv_len = 0;
> > +    uint32_t aad_len = 0, hash_result_len = 0;
> > +    uint32_t hash_start_src_offset = 0, len_to_hash = 0;
> > +    uint32_t cipher_start_src_offset = 0, len_to_cipher = 0;
> > +
> > +    size_t max_len, curr_size = 0;
> > +    size_t s;
> > +
> > +    /* Plain cipher */
> > +    if (cipher_para) {
> > +        iv_len = virtio_ldl_p(vdev, &cipher_para->iv_len);
> > +        src_len = virtio_ldl_p(vdev, &cipher_para->src_data_len);
> > +        dst_len = virtio_ldl_p(vdev, &cipher_para->dst_data_len);
> > +    } else if (alg_chain_para) { /* Algorithm chain */
> > +        iv_len = virtio_ldl_p(vdev, &alg_chain_para->iv_len);
> > +        src_len = virtio_ldl_p(vdev, &alg_chain_para->src_data_len);
> > +        dst_len = virtio_ldl_p(vdev, &alg_chain_para->dst_data_len);
> > +
> > +        aad_len = virtio_ldl_p(vdev, &alg_chain_para->aad_len);
> > +        hash_result_len = virtio_ldl_p(vdev,
> > +                              &alg_chain_para->hash_result_len);
> > +        hash_start_src_offset = virtio_ldl_p(vdev,
> > +                         &alg_chain_para->hash_start_src_offset);
> > +        cipher_start_src_offset = virtio_ldl_p(vdev,
> > +                         &alg_chain_para->cipher_start_src_offset);
> > +        len_to_cipher = virtio_ldl_p(vdev,
> &alg_chain_para->len_to_cipher);
> > +        len_to_hash = virtio_ldl_p(vdev, &alg_chain_para->len_to_hash);
> > +    } else {
> > +        return NULL;
> > +    }
> > +
> 
> 
> You don't need virtio_ wrappers for modern devices I think. Just use LE
> accessors.
> 

I think I get your point, you mean using *_le_* function family directly.
Will do.

> > +    max_len = iv_len + aad_len + src_len + dst_len + hash_result_len;
> > +    if (unlikely(max_len > LONG_MAX -
> sizeof(CryptoDevBackendSymOpInfo))) {
> > +        virtio_error(vdev, "virtio-crypto too big length");
> > +        return NULL;
> > +    }
> > +
> > +    op_info = g_malloc0(sizeof(CryptoDevBackendSymOpInfo) + max_len);
> 
> Wow this can allocate up to 2^64 bytes, triggerable by guest. Not nice.

That's true as the boundary value in theory.

> Also, max size depends on long size and guest has no way
> to know it. Not nice either.
> 
Currently yes, the driver only receive a virtio_CRYPTO_ERR if
The total length > LONG_MAX - sizeof(CryptoDevBackendSymOpInfo)

> Add max size in device config?
> 
It makes sense I think.

The max_size expresses the maximum size of per crypto request's content. 
And we can set different max_size values based on different cryptdoev
backends on the device side.

The driver can read it from the device configuration and add corresponding checks.

Let me add it in the following version.

> > +    op_info->iv_len = iv_len;
> > +    op_info->src_len = src_len;
> > +    op_info->dst_len = dst_len;
> > +    op_info->aad_len = aad_len;
> > +    op_info->digest_result_len = hash_result_len;
> > +    op_info->hash_start_src_offset = hash_start_src_offset;
> > +    op_info->len_to_hash = len_to_hash;
> > +    op_info->cipher_start_src_offset = cipher_start_src_offset;
> > +    op_info->len_to_cipher = len_to_cipher;
> > +    /* Handle the initilization vector */
> > +    if (op_info->iv_len > 0) {
> > +        DPRINTF("iv_len=%" PRIu32 "\n", op_info->iv_len);
> > +        op_info->iv = op_info->data + curr_size;
> 
> This shows that splitting a single file like this
> is not helpful. I wanted to know how is data initialized
> and what makes this math safe, and couldn't figure it out
> from this patch alone.
> 
Sorry , I couldn't catch your mean here completely. :(

You mean the method of splitting the patches
about this virtio-crypto.c is not nice? If yes, I
think it's too big if put them in one patch to review. 

> 
> > +
> > +        s = iov_to_buf(iov, out_num, 0, op_info->iv, op_info->iv_len);
> > +        if (unlikely(s != op_info->iv_len)) {
> > +            virtio_error(vdev, "virtio-crypto iv incorrect");
> > +            goto err;
> > +        }
> > +        iov_discard_front(&iov, &out_num, op_info->iv_len);
> > +        curr_size += op_info->iv_len;
> > +    }
> > +
> > +    /* Handle additional authentication data if exist */
> 
> -> if it exists
> 
Yes, will fix it.

> > +    if (op_info->aad_len > 0) {
> > +        DPRINTF("aad_len=%" PRIu32 "\n", op_info->aad_len);
> > +        op_info->aad_data = op_info->data + curr_size;
> > +
> > +        s = iov_to_buf(iov, out_num, 0, op_info->aad_data,
> op_info->aad_len);
> > +        if (unlikely(s != op_info->aad_len)) {
> > +            virtio_error(vdev, "virtio-crypto additional auth data
> incorrect");
> > +            goto err;
> > +        }
> > +        iov_discard_front(&iov, &out_num, op_info->aad_len);
> > +
> > +        curr_size += op_info->aad_len;
> > +    }
> > +
> > +    /* Handle the source data */
> > +    if (op_info->src_len > 0) {
> > +        DPRINTF("src_len=%" PRIu32 "\n", op_info->src_len);
> > +        op_info->src = op_info->data + curr_size;
> > +
> > +        s = iov_to_buf(iov, out_num, 0, op_info->src, op_info->src_len);
> > +        if (unlikely(s != op_info->src_len)) {
> > +            virtio_error(vdev, "virtio-crypto source data incorrect");
> > +            goto err;
> > +        }
> > +        iov_discard_front(&iov, &out_num, op_info->src_len);
> > +
> > +        curr_size += op_info->src_len;
> > +    }
> > +
> > +    /* Handle the destination data */
> > +    op_info->dst = op_info->data + curr_size;
> > +    curr_size += op_info->dst_len;
> > +
> > +    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);
> > +
> > +    /* Handle the hash digest result */
> > +    if (hash_result_len > 0) {
> > +        DPRINTF("hash_result_len=%" PRIu32 "\n", hash_result_len);
> > +        op_info->digest_result = op_info->data + curr_size;
> > +    }
> > +
> > +    return op_info;
> > +
> > +err:
> > +    g_free(op_info);
> > +    return NULL;
> > +}
> > +
> > +static int
> > +virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
> > +               struct virtio_crypto_sym_data_req *req,
> > +               CryptoDevBackendSymOpInfo **sym_op_info,
> > +               struct iovec *iov, unsigned int out_num)
> > +{
> > +    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
> > +    uint32_t op_type;
> > +    CryptoDevBackendSymOpInfo *op_info;
> > +
> > +    op_type = virtio_ldl_p(vdev, &req->op_type);
> > +
> > +    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
> > +        op_info = virtio_crypto_sym_op_helper(vdev, &req->u.cipher.para,
> > +                                              NULL, iov,
> out_num);
> > +        if (!op_info) {
> > +            return -EFAULT;
> > +        }
> > +        op_info->op_type = op_type;
> > +    } else if (op_type ==
> VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
> > +        op_info = virtio_crypto_sym_op_helper(vdev, NULL,
> > +
> &req->u.chain.para,
> > +                                              iov, out_num);
> > +        if (!op_info) {
> > +            return -EFAULT;
> > +        }
> > +        op_info->op_type = op_type;
> > +    } else {
> > +        /* VIRTIO_CRYPTO_SYM_OP_NONE */
> > +        error_report("virtio-crypto unsupported cipher type");
> > +        return -VIRTIO_CRYPTO_NOTSUPP;
> 
> virtio_error?
> 
Stefan also mentioned this. It's just a reminder for host side, not a serious
error that need the frontend driver to reset the device. The driver will
receive VIRTIO_CRYPTO_NOTSUPP to decide what to do next.


Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (13 preceding siblings ...)
  2016-10-25 11:20 ` Gonglei (Arei)
@ 2016-10-30 20:00 ` Halil Pasic
  2016-10-31  2:52   ` Gonglei (Arei)
  14 siblings, 1 reply; 26+ messages in thread
From: Halil Pasic @ 2016-10-30 20:00 UTC (permalink / raw)
  To: Gonglei, qemu-devel, virtio-dev
  Cc: weidong.huang, claudio.fontana, mst, xin.zeng, hanweidong,
	luonengjun, agraf, nmorey, mike.caraman, stefanha, jianjay.zhou,
	pbonzini, peter.huangpeng, vincent.jardin, wu.wubin,
	arei.gonglei

[-- Attachment #1: Type: text/plain, Size: 3338 bytes --]



On 10/20/2016 01:45 PM, Gonglei wrote:
> The front-end linux kernel driver (Experimental at present) is publicly accessible from:
> 
>    https://github.com/gongleiarei/virtio-crypto-linux-driver.git

Hi!

I'm very interested in making sure this work for the s390x architecture
too.  So to familiarize with the stuff I wanted to give it a spin on
x86_64 and then transit to s390x and look for possible issues.

Unfortunately I encountered a problem already on x86_64, more precisely
the guest hangs in virtio_crypto_alg_ablkcipher_init_session after the
kick. But before I start explaining in detail let me ask you: what are
your plans for the linux kernel driver? I used the most current version
from your github, but also tried to look for patches on mailing lists
and I have found none. IMHO the problem causing my hang is in the kernel
module. But I do not know here am I supposed to comment on it -- so I'm
commenting here. Furthermore your kernel module currently do not seem to
care about endianness which is bad for s390x. 

The hangs  basically boils down to the following: after the kick in
virtio_crypto_alg_ablkcipher_init_session we reach the point (in QEMU)
where we want to translate the address for the third descriptor, the one
which designates a buffer for the virtio_crypto_session_input. My
backtrace looks like this:


#0  address_space_translate (as=<optimized out>, as@entry=0x55555607d700 <address_space_memory>, addr=addr@entry=71468256835928, xlat=xlat@entry=0x7fffef4dc1a0, plen=plen@entry=0x7fffef4dc198, is_write=is_write@entry=true)
    at /home/pasic/devel/qemu/exec.c:481
#1  0x000055555575ef19 in address_space_map (as=0x55555607d700 <address_space_memory>, addr=71468256835928, plen=<optimized out>, is_write=<optimized out>) at /home/pasic/devel/qemu/exec.c:2927
#2  0x00005555557e5d00 in virtqueue_map_desc (vdev=0x555557d80de0, p_num_sg=0x7fffef4dc2bc, addr=0x7fffef4dc2f0, iov=0x7fffef4de300, max_num_sg=1022, is_write=true, pa=71468256835928, sz=16)
    at /home/pasic/devel/qemu/hw/virtio/virtio.c:558
#3  0x00005555557e5f86 in virtqueue_pop (vq=0x7fffef4dc2c0, sz=93825003936576) at /home/pasic/devel/qemu/hw/virtio/virtio.c:717
#4  0x00005555557ed80b in virtio_crypto_handle_ctrl (vdev=<optimized out>, vq=0x7fffeec3e090) at /home/pasic/devel/qemu/hw/virtio/virtio-crypto.c:218

Now the first suspicious thing I see is that address_space_translate
returns a pointer to the memory region io_mem_unassigned. Next thing
happening is that we take the !memory_access_is_direct(mr, is_write)
branch in address_space_map and return NULL at line 2932 which however
makes  virtqueue_map_desc report "qemu-system-x86_64: virtio: bogus
descriptor or out of resources" and return with false. Then pop returns
null too and spins virtio_crypto_alg_ablkcipher_init_session till the
end of time waiting for the answer.

Now if I change the code so that the virtio_crypto_session_input
instance's backing memory is allocated with  kzalloc(sizeof(*input),
GFP_DMA|GFP_NOIO) of allocating the on the stack things start working
for me. I'm not too deep into this yet, so please forgive me if
I'm a bit vague.

I was testing with tcrypt mode=500 instead of cryptodev-linux but I
guess that should be irrelevant.

Looking forward to your answer.

Halil



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-30 20:00 ` [Qemu-devel] " Halil Pasic
@ 2016-10-31  2:52   ` Gonglei (Arei)
  2016-10-31  9:41     ` Cornelia Huck
  2016-11-02 17:34     ` Halil Pasic
  0 siblings, 2 replies; 26+ messages in thread
From: Gonglei (Arei) @ 2016-10-31  2:52 UTC (permalink / raw)
  To: Halil Pasic, qemu-devel, virtio-dev
  Cc: Huangweidong (C),
	Claudio Fontana, mst, xin.zeng, Hanweidong (Randy),
	Luonengjun, agraf, nmorey, mike.caraman, stefanha, Zhoujian (jay,
	Euler), pbonzini, Huangpeng (Peter), vincent.jardin, Wubin (H),
	arei.gonglei

> From: Halil Pasic [mailto:pasic@linux.vnet.ibm.com]
> Sent: Monday, October 31, 2016 4:00 AM
> Subject: Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework
> and device emulation
> 
> 
> 
> On 10/20/2016 01:45 PM, Gonglei wrote:
> > The front-end linux kernel driver (Experimental at present) is publicly
> accessible from:
> >
> >    https://github.com/gongleiarei/virtio-crypto-linux-driver.git
> 
> Hi!
> 
> I'm very interested in making sure this work for the s390x architecture
> too.  So to familiarize with the stuff I wanted to give it a spin on
> x86_64 and then transit to s390x and look for possible issues.
> 
Cool.

> Unfortunately I encountered a problem already on x86_64, more precisely
> the guest hangs in virtio_crypto_alg_ablkcipher_init_session after the
> kick. But before I start explaining in detail let me ask you: what are
> your plans for the linux kernel driver? I used the most current version
> from your github, but also tried to look for patches on mailing lists
> and I have found none. 

I haven't submit the virtio-crypto driver to the mailing list yet cause
I wanted to the patches on the QEMU side can be merged firstly,
and then focus to the frontend driver.

> IMHO the problem causing my hang is in the kernel
> module. But I do not know here am I supposed to comment on it -- so I'm
> commenting here. Furthermore your kernel module currently do not seem to
> care about endianness which is bad for s390x.
> 
That's true.

> The hangs  basically boils down to the following: after the kick in
> virtio_crypto_alg_ablkcipher_init_session we reach the point (in QEMU)
> where we want to translate the address for the third descriptor, the one
> which designates a buffer for the virtio_crypto_session_input. My
> backtrace looks like this:
> 
> 
> #0  address_space_translate (as=<optimized out>,
> as@entry=0x55555607d700 <address_space_memory>,
> addr=addr@entry=71468256835928, xlat=xlat@entry=0x7fffef4dc1a0,
> plen=plen@entry=0x7fffef4dc198, is_write=is_write@entry=true)
>     at /home/pasic/devel/qemu/exec.c:481
> #1  0x000055555575ef19 in address_space_map (as=0x55555607d700
> <address_space_memory>, addr=71468256835928, plen=<optimized out>,
> is_write=<optimized out>) at /home/pasic/devel/qemu/exec.c:2927
> #2  0x00005555557e5d00 in virtqueue_map_desc (vdev=0x555557d80de0,
> p_num_sg=0x7fffef4dc2bc, addr=0x7fffef4dc2f0, iov=0x7fffef4de300,
> max_num_sg=1022, is_write=true, pa=71468256835928, sz=16)
>     at /home/pasic/devel/qemu/hw/virtio/virtio.c:558
> #3  0x00005555557e5f86 in virtqueue_pop (vq=0x7fffef4dc2c0,
> sz=93825003936576) at /home/pasic/devel/qemu/hw/virtio/virtio.c:717
> #4  0x00005555557ed80b in virtio_crypto_handle_ctrl (vdev=<optimized out>,
> vq=0x7fffeec3e090) at /home/pasic/devel/qemu/hw/virtio/virtio-crypto.c:218
> 
> Now the first suspicious thing I see is that address_space_translate
> returns a pointer to the memory region io_mem_unassigned. Next thing
> happening is that we take the !memory_access_is_direct(mr, is_write)
> branch in address_space_map and return NULL at line 2932 which however
> makes  virtqueue_map_desc report "qemu-system-x86_64: virtio: bogus
> descriptor or out of resources" and return with false. Then pop returns
> null too and spins virtio_crypto_alg_ablkcipher_init_session till the
> end of time waiting for the answer.
> 
It seems that the frontend driver passed a invalid gpa to the QEMU side,
The Qemu side will invokes virtio_error() to notify the guest to reset the
device.

> Now if I change the code so that the virtio_crypto_session_input
> instance's backing memory is allocated with  kzalloc(sizeof(*input),
> GFP_DMA|GFP_NOIO) of allocating the on the stack things start working
> for me. I'm not too deep into this yet, so please forgive me if
> I'm a bit vague.
> 
Good, maybe you find a bug of the frontend driver. Using stack memory
might not be a good idea ;)

> I was testing with tcrypt mode=500 instead of cryptodev-linux but I
> guess that should be irrelevant.
> 
I think so as well.

> Looking forward to your answer.
> 
> Halil
> 

Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-31  2:52   ` Gonglei (Arei)
@ 2016-10-31  9:41     ` Cornelia Huck
  2016-11-02 17:34     ` Halil Pasic
  1 sibling, 0 replies; 26+ messages in thread
From: Cornelia Huck @ 2016-10-31  9:41 UTC (permalink / raw)
  To: Gonglei (Arei)
  Cc: Halil Pasic, qemu-devel, virtio-dev, Huangweidong (C),
	stefanha, Hanweidong (Randy),
	Claudio Fontana, mst, Luonengjun, xin.zeng, agraf, mike.caraman,
	nmorey, Zhoujian (jay,	Euler), pbonzini, Huangpeng (Peter),
	vincent.jardin, Wubin (H),
	arei.gonglei

On Mon, 31 Oct 2016 02:52:32 +0000
"Gonglei (Arei)" <arei.gonglei@huawei.com> wrote:

> > From: Halil Pasic [mailto:pasic@linux.vnet.ibm.com]
> > Sent: Monday, October 31, 2016 4:00 AM
> > Subject: Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework
> > and device emulation
> > 
> > 
> > 
> > On 10/20/2016 01:45 PM, Gonglei wrote:
> > > The front-end linux kernel driver (Experimental at present) is publicly
> > accessible from:
> > >
> > >    https://github.com/gongleiarei/virtio-crypto-linux-driver.git

> > Unfortunately I encountered a problem already on x86_64, more precisely
> > the guest hangs in virtio_crypto_alg_ablkcipher_init_session after the
> > kick. But before I start explaining in detail let me ask you: what are
> > your plans for the linux kernel driver? I used the most current version
> > from your github, but also tried to look for patches on mailing lists
> > and I have found none. 
> 
> I haven't submit the virtio-crypto driver to the mailing list yet cause
> I wanted to the patches on the QEMU side can be merged firstly,
> and then focus to the frontend driver.

FWIW, I think it would be a good idea to post the frontend driver for
review as well, especially as people may notice stuff like the things
Halil noticed. You don't have to act immediately if you're focusing on
qemu right now, but I think it would make things easier for others
wanting to try this out.

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-10-31  2:52   ` Gonglei (Arei)
  2016-10-31  9:41     ` Cornelia Huck
@ 2016-11-02 17:34     ` Halil Pasic
  2016-11-04  2:49       ` Gonglei (Arei)
  1 sibling, 1 reply; 26+ messages in thread
From: Halil Pasic @ 2016-11-02 17:34 UTC (permalink / raw)
  To: Gonglei (Arei), qemu-devel, virtio-dev
  Cc: Huangweidong (C), stefanha, Hanweidong (Randy),
	Claudio Fontana, mst, Luonengjun, xin.zeng, agraf, mike.caraman,
	nmorey, Zhoujian (jay, Euler), pbonzini, Huangpeng (Peter),
	vincent.jardin, Wubin (H),
	arei.gonglei



On 10/31/2016 03:52 AM, Gonglei (Arei) wrote:
>> > Unfortunately I encountered a problem already on x86_64, more precisely
>> > the guest hangs in virtio_crypto_alg_ablkcipher_init_session after the
>> > kick. But before I start explaining in detail let me ask you: what are
>> > your plans for the linux kernel driver? I used the most current version
>> > from your github, but also tried to look for patches on mailing lists
>> > and I have found none. 
> I haven't submit the virtio-crypto driver to the mailing list yet cause
> I wanted to the patches on the QEMU side can be merged firstly,
> and then focus to the frontend driver.
> 

That is fine and the QEMU stuff does look good :). I'm still curious
about your road map that is what should I expect on the kernel side
and when? You could also cc me ;) when sending to the list.

>> > IMHO the problem causing my hang is in the kernel
>> > module. But I do not know here am I supposed to comment on it -- so I'm
>> > commenting here. Furthermore your kernel module currently do not seem to
>> > care about endianness which is bad for s390x.
>> > 
> That's true.
> 

For the sake of the experiment I have reworked 
virtio_crypto_alg_ablkcipher_init_session so that id does care
about the endianness of the guest. With that the functions seems
to work on s390x (but of course the next byte order problem warrants
that encryption/decryption does not work yet). It is not beautiful
but I can give you a patch if you want.

>> > The hangs  basically boils down to the following: after the kick in
>> > virtio_crypto_alg_ablkcipher_init_session we reach the point (in QEMU)
>> > where we want to translate the address for the third descriptor, the one
>> > which designates a buffer for the virtio_crypto_session_input. My
>> > backtrace looks like this:
>> > 
>> > 
>> > #0  address_space_translate (as=<optimized out>,
>> > as@entry=0x55555607d700 <address_space_memory>,
>> > addr=addr@entry=71468256835928, xlat=xlat@entry=0x7fffef4dc1a0,
>> > plen=plen@entry=0x7fffef4dc198, is_write=is_write@entry=true)
>> >     at /home/pasic/devel/qemu/exec.c:481
>> > #1  0x000055555575ef19 in address_space_map (as=0x55555607d700
>> > <address_space_memory>, addr=71468256835928, plen=<optimized out>,
>> > is_write=<optimized out>) at /home/pasic/devel/qemu/exec.c:2927
>> > #2  0x00005555557e5d00 in virtqueue_map_desc (vdev=0x555557d80de0,
>> > p_num_sg=0x7fffef4dc2bc, addr=0x7fffef4dc2f0, iov=0x7fffef4de300,
>> > max_num_sg=1022, is_write=true, pa=71468256835928, sz=16)
>> >     at /home/pasic/devel/qemu/hw/virtio/virtio.c:558
>> > #3  0x00005555557e5f86 in virtqueue_pop (vq=0x7fffef4dc2c0,
>> > sz=93825003936576) at /home/pasic/devel/qemu/hw/virtio/virtio.c:717
>> > #4  0x00005555557ed80b in virtio_crypto_handle_ctrl (vdev=<optimized out>,
>> > vq=0x7fffeec3e090) at /home/pasic/devel/qemu/hw/virtio/virtio-crypto.c:218
>> > 
>> > Now the first suspicious thing I see is that address_space_translate
>> > returns a pointer to the memory region io_mem_unassigned. Next thing
>> > happening is that we take the !memory_access_is_direct(mr, is_write)
>> > branch in address_space_map and return NULL at line 2932 which however
>> > makes  virtqueue_map_desc report "qemu-system-x86_64: virtio: bogus
>> > descriptor or out of resources" and return with false. Then pop returns
>> > null too and spins virtio_crypto_alg_ablkcipher_init_session till the
>> > end of time waiting for the answer.
>> > 
> It seems that the frontend driver passed a invalid gpa to the QEMU side,
> The Qemu side will invokes virtio_error() to notify the guest to reset the
> device.
> 

I did not say previously but I have checked and the gpa is good, that
is it has a correct offset in respect to ctrl's gpa (the next variable
on stack, which is the previous desc.addr used read only) which is good.
Furthermore the issue seems to be platform dependent as I do not see this
on s390x.

>> > Now if I change the code so that the virtio_crypto_session_input
>> > instance's backing memory is allocated with  kzalloc(sizeof(*input),
>> > GFP_DMA|GFP_NOIO) of allocating the on the stack things start working
>> > for me. I'm not too deep into this yet, so please forgive me if
>> > I'm a bit vague.
>> > 
> Good, maybe you find a bug of the frontend driver. Using stack memory
> might not be a good idea ;)
> 

Yeah, as I said, can't say (that is my understanding too shallow).

Cheers,
Halil

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

* Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation
  2016-11-02 17:34     ` Halil Pasic
@ 2016-11-04  2:49       ` Gonglei (Arei)
  0 siblings, 0 replies; 26+ messages in thread
From: Gonglei (Arei) @ 2016-11-04  2:49 UTC (permalink / raw)
  To: Halil Pasic, qemu-devel, virtio-dev
  Cc: Huangweidong (C), stefanha, Hanweidong (Randy),
	Claudio Fontana, mst, Luonengjun, xin.zeng, agraf, mike.caraman,
	nmorey, Zhoujian (jay, Euler), pbonzini, Huangpeng (Peter),
	vincent.jardin, Wubin (H),
	arei.gonglei


> -----Original Message-----
> From: Halil Pasic [mailto:pasic@linux.vnet.ibm.com]
> Sent: Thursday, November 03, 2016 1:35 AM
> Subject: Re: [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework
> and device emulation
> 
> 
> 
> On 10/31/2016 03:52 AM, Gonglei (Arei) wrote:
> >> > Unfortunately I encountered a problem already on x86_64, more precisely
> >> > the guest hangs in virtio_crypto_alg_ablkcipher_init_session after the
> >> > kick. But before I start explaining in detail let me ask you: what are
> >> > your plans for the linux kernel driver? I used the most current version
> >> > from your github, but also tried to look for patches on mailing lists
> >> > and I have found none.
> > I haven't submit the virtio-crypto driver to the mailing list yet cause
> > I wanted to the patches on the QEMU side can be merged firstly,
> > and then focus to the frontend driver.
> >
> 
> That is fine and the QEMU stuff does look good :). I'm still curious
> about your road map that is what should I expect on the kernel side
> and when? You could also cc me ;) when sending to the list.
> 
Currently a project of my company eats my time, I'll address it in the
following two weeks I guess. 

Sure, I'll cc you when I sending to the mailing list. :)

> >> > IMHO the problem causing my hang is in the kernel
> >> > module. But I do not know here am I supposed to comment on it -- so I'm
> >> > commenting here. Furthermore your kernel module currently do not seem
> to
> >> > care about endianness which is bad for s390x.
> >> >
> > That's true.
> >
> 
> For the sake of the experiment I have reworked
> virtio_crypto_alg_ablkcipher_init_session so that id does care
> about the endianness of the guest. With that the functions seems
> to work on s390x (but of course the next byte order problem warrants
> that encryption/decryption does not work yet). It is not beautiful
> but I can give you a patch if you want.
> 
Sure, Pls. I can merge it with your sign.


Thanks,
-Gonglei

> >> > The hangs  basically boils down to the following: after the kick in
> >> > virtio_crypto_alg_ablkcipher_init_session we reach the point (in QEMU)
> >> > where we want to translate the address for the third descriptor, the one
> >> > which designates a buffer for the virtio_crypto_session_input. My
> >> > backtrace looks like this:
> >> >
> >> >
> >> > #0  address_space_translate (as=<optimized out>,
> >> > as@entry=0x55555607d700 <address_space_memory>,
> >> > addr=addr@entry=71468256835928, xlat=xlat@entry=0x7fffef4dc1a0,
> >> > plen=plen@entry=0x7fffef4dc198, is_write=is_write@entry=true)
> >> >     at /home/pasic/devel/qemu/exec.c:481
> >> > #1  0x000055555575ef19 in address_space_map (as=0x55555607d700
> >> > <address_space_memory>, addr=71468256835928, plen=<optimized
> out>,
> >> > is_write=<optimized out>) at /home/pasic/devel/qemu/exec.c:2927
> >> > #2  0x00005555557e5d00 in virtqueue_map_desc
> (vdev=0x555557d80de0,
> >> > p_num_sg=0x7fffef4dc2bc, addr=0x7fffef4dc2f0, iov=0x7fffef4de300,
> >> > max_num_sg=1022, is_write=true, pa=71468256835928, sz=16)
> >> >     at /home/pasic/devel/qemu/hw/virtio/virtio.c:558
> >> > #3  0x00005555557e5f86 in virtqueue_pop (vq=0x7fffef4dc2c0,
> >> > sz=93825003936576) at /home/pasic/devel/qemu/hw/virtio/virtio.c:717
> >> > #4  0x00005555557ed80b in virtio_crypto_handle_ctrl (vdev=<optimized
> out>,
> >> > vq=0x7fffeec3e090) at
> /home/pasic/devel/qemu/hw/virtio/virtio-crypto.c:218
> >> >
> >> > Now the first suspicious thing I see is that address_space_translate
> >> > returns a pointer to the memory region io_mem_unassigned. Next thing
> >> > happening is that we take the !memory_access_is_direct(mr, is_write)
> >> > branch in address_space_map and return NULL at line 2932 which
> however
> >> > makes  virtqueue_map_desc report "qemu-system-x86_64: virtio: bogus
> >> > descriptor or out of resources" and return with false. Then pop returns
> >> > null too and spins virtio_crypto_alg_ablkcipher_init_session till the
> >> > end of time waiting for the answer.
> >> >
> > It seems that the frontend driver passed a invalid gpa to the QEMU side,
> > The Qemu side will invokes virtio_error() to notify the guest to reset the
> > device.
> >
> 
> I did not say previously but I have checked and the gpa is good, that
> is it has a correct offset in respect to ctrl's gpa (the next variable
> on stack, which is the previous desc.addr used read only) which is good.
> Furthermore the issue seems to be platform dependent as I do not see this
> on s390x.
> 
> >> > Now if I change the code so that the virtio_crypto_session_input
> >> > instance's backing memory is allocated with  kzalloc(sizeof(*input),
> >> > GFP_DMA|GFP_NOIO) of allocating the on the stack things start working
> >> > for me. I'm not too deep into this yet, so please forgive me if
> >> > I'm a bit vague.
> >> >
> > Good, maybe you find a bug of the frontend driver. Using stack memory
> > might not be a good idea ;)
> >
> 
> Yeah, as I said, can't say (that is my understanding too shallow).
> 
> Cheers,
> Halil

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

end of thread, other threads:[~2016-11-04  2:50 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-20 11:45 [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 01/12] cryptodev: introduce cryptodev backend interface Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 02/12] cryptodev: add symmetric algorithm operation stuff Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 03/12] virtio-crypto: introduce virtio_crypto.h Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 04/12] cryptodev: introduce a new cryptodev backend Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 05/12] virtio-crypto: add virtio crypto device emulation Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 06/12] virtio-crypto-pci: add virtio crypto pci support Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 07/12] virtio-crypto: set capacity of algorithms supported Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 08/12] virtio-crypto: add control queue handler Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 09/12] virtio-crypto: add data queue processing handler Gonglei
2016-10-27 16:59   ` Michael S. Tsirkin
2016-10-28  0:50     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 10/12] cryptodev: introduce an unified wrapper for crypto operation Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 11/12] virtio-crypto: using bh to handle dataq's requests Gonglei
2016-10-20 11:45 ` [Qemu-devel] [PATCH v9 12/12] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
2016-10-20 12:25 ` [Qemu-devel] [PATCH v9 00/12] virtio-crypto: introduce framework and device emulation no-reply
2016-10-27  8:03   ` Gonglei (Arei)
2016-10-25 11:20 ` Gonglei (Arei)
2016-10-25 16:50   ` Michael S. Tsirkin
2016-10-26  0:54     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
2016-10-27 16:12       ` Michael S. Tsirkin
2016-10-30 20:00 ` [Qemu-devel] " Halil Pasic
2016-10-31  2:52   ` Gonglei (Arei)
2016-10-31  9:41     ` Cornelia Huck
2016-11-02 17:34     ` Halil Pasic
2016-11-04  2:49       ` Gonglei (Arei)

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