All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
@ 2016-09-28  8:25 Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface Gonglei
                   ` (15 more replies)
  0 siblings, 16 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

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 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 (13):
  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: emulate virtio crypto as a legacy device by default
  virtio-crypto-test: add qtest case for virtio-crypto
  virtio-crypto: add myself as virtio-crypto and cryptodev backends
    maintainer

 MAINTAINERS                                    |  14 +
 backends/Makefile.objs                         |   3 +
 backends/cryptodev-builtin.c                   | 345 ++++++++++
 backends/cryptodev.c                           | 244 +++++++
 docs/specs/pci-ids.txt                         |   2 +
 hw/virtio/Makefile.objs                        |   2 +
 hw/virtio/virtio-crypto-pci.c                  |  79 +++
 hw/virtio/virtio-crypto.c                      | 899 +++++++++++++++++++++++++
 hw/virtio/virtio-pci.h                         |  15 +
 include/hw/pci/pci.h                           |   2 +
 include/hw/virtio/virtio-crypto.h              |  99 +++
 include/standard-headers/linux/virtio_crypto.h | 508 ++++++++++++++
 include/standard-headers/linux/virtio_ids.h    |   2 +-
 include/sysemu/cryptodev.h                     | 279 ++++++++
 qemu-options.hx                                |  18 +
 tests/Makefile.include                         |   3 +
 tests/virtio-crypto-test.c                     | 412 +++++++++++
 17 files changed, 2925 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
 create mode 100644 tests/virtio-crypto-test.c

-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-03 16:10   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff Gonglei
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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       | 175 +++++++++++++++++++++++++++++++++++++++++++++
 include/sysemu/cryptodev.h | 145 +++++++++++++++++++++++++++++++++++++
 3 files changed, 322 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..a15904b
--- /dev/null
+++ b/backends/cryptodev.c
@@ -0,0 +1,175 @@
+/*
+ * QEMU Crypto Device Implement
+ *
+ * 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(, QCryptoCryptoDevBackendClientState) crypto_clients;
+
+
+QCryptoCryptoDevBackendClientState *
+qcrypto_cryptodev_backend_new_client(const char *model,
+                                    const char *name)
+{
+    QCryptoCryptoDevBackendClientState *cc;
+
+    cc = g_malloc0(sizeof(QCryptoCryptoDevBackendClientState));
+    cc->model = g_strdup(model);
+    if (name) {
+        cc->name = g_strdup(name);
+    }
+
+    QTAILQ_INSERT_TAIL(&crypto_clients, cc, next);
+
+    return cc;
+}
+
+void qcrypto_cryptodev_backend_free_client(
+                  QCryptoCryptoDevBackendClientState *cc)
+{
+    QTAILQ_REMOVE(&crypto_clients, cc, next);
+    g_free(cc->name);
+    g_free(cc->model);
+    g_free(cc);
+}
+
+void qcrypto_cryptodev_backend_cleanup(
+             QCryptoCryptoDevBackend *backend,
+             Error **errp)
+{
+    QCryptoCryptoDevBackendClass *bc =
+                  QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->cleanup) {
+        bc->cleanup(backend, errp);
+    }
+
+    backend->ready = 0;
+}
+
+static void
+qcrypto_cryptodev_backend_get_queues(Object *obj, Visitor *v, const char *name,
+                             void *opaque, Error **errp)
+{
+    QCryptoCryptoDevBackend *backend = QCRYPTO_CRYPTODEV_BACKEND(obj);
+    uint32_t value = backend->conf.peers.queues;
+
+    visit_type_uint32(v, name, &value, errp);
+}
+
+static void
+qcrypto_cryptodev_backend_set_queues(Object *obj, Visitor *v, const char *name,
+                             void *opaque, Error **errp)
+{
+    QCryptoCryptoDevBackend *backend = QCRYPTO_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
+qcrypto_cryptodev_backend_complete(UserCreatable *uc, Error **errp)
+{
+    QCryptoCryptoDevBackend *backend = QCRYPTO_CRYPTODEV_BACKEND(uc);
+    QCryptoCryptoDevBackendClass *bc = QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(uc);
+    Error *local_err = NULL;
+
+    if (bc->init) {
+        bc->init(backend, &local_err);
+        if (local_err) {
+            goto out;
+        }
+    }
+    backend->ready = 1;
+    return;
+
+out:
+    backend->ready = 0;
+    error_propagate(errp, local_err);
+}
+
+static void qcrypto_cryptodev_backend_instance_init(Object *obj)
+{
+    object_property_add(obj, "queues", "int",
+                          qcrypto_cryptodev_backend_get_queues,
+                          qcrypto_cryptodev_backend_set_queues,
+                          NULL, NULL, NULL);
+    /* Initialize devices' queues property to 1 */
+    object_property_set_int(obj, 1, "queues", NULL);
+}
+
+static void qcrypto_cryptodev_backend_finalize(Object *obj)
+{
+
+}
+
+static void
+qcrypto_cryptodev_backend_class_init(ObjectClass *oc, void *data)
+{
+    UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc);
+
+    ucc->complete = qcrypto_cryptodev_backend_complete;
+
+    QTAILQ_INIT(&crypto_clients);
+}
+
+static const TypeInfo qcrypto_cryptodev_backend_info = {
+    .name = TYPE_QCRYPTO_CRYPTODEV_BACKEND,
+    .parent = TYPE_OBJECT,
+    .instance_size = sizeof(QCryptoCryptoDevBackend),
+    .instance_init = qcrypto_cryptodev_backend_instance_init,
+    .instance_finalize = qcrypto_cryptodev_backend_finalize,
+    .class_size = sizeof(QCryptoCryptoDevBackendClass),
+    .class_init = qcrypto_cryptodev_backend_class_init,
+    .interfaces = (InterfaceInfo[]) {
+        { TYPE_USER_CREATABLE },
+        { }
+    }
+};
+
+static void
+qcrypto_cryptodev_backend_register_types(void)
+{
+    type_register_static(&qcrypto_cryptodev_backend_info);
+}
+
+type_init(qcrypto_cryptodev_backend_register_types);
diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
new file mode 100644
index 0000000..cc3c3be
--- /dev/null
+++ b/include/sysemu/cryptodev.h
@@ -0,0 +1,145 @@
+/*
+ * QEMU Crypto Device Implement
+ *
+ * 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 QCRYPTO_CRYPTODEV_H
+#define QCRYPTO_CRYPTODEV_H
+
+#include "qom/object.h"
+#include "qemu-common.h"
+
+/**
+ * QCryptoCryptoDevBackend:
+ *
+ * The QCryptoCryptoDevBackend object is an interface
+ * for different cryptodev backends, which provides crypto
+ * operation wrapper.
+ *
+ */
+
+#define TYPE_QCRYPTO_CRYPTODEV_BACKEND "cryptodev-backend"
+
+#define QCRYPTO_CRYPTODEV_BACKEND(obj) \
+    OBJECT_CHECK(QCryptoCryptoDevBackend, \
+                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
+#define QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(obj) \
+    OBJECT_GET_CLASS(QCryptoCryptoDevBackendClass, \
+                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
+#define QCRYPTO_CRYPTODEV_BACKEND_CLASS(klass) \
+    OBJECT_CLASS_CHECK(QCryptoCryptoDevBackendClass, \
+                (klass), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
+
+
+#define MAX_CRYPTO_QUEUE_NUM  64
+
+typedef struct QCryptoCryptoDevBackendConf QCryptoCryptoDevBackendConf;
+typedef struct QCryptoCryptoDevBackendPeers QCryptoCryptoDevBackendPeers;
+typedef struct QCryptoCryptoDevBackendClientState
+                     QCryptoCryptoDevBackendClientState;
+typedef struct QCryptoCryptoDevBackend QCryptoCryptoDevBackend;
+
+
+typedef struct QCryptoCryptoDevBackendClass {
+    ObjectClass parent_class;
+
+    void (*init)(QCryptoCryptoDevBackend *backend, Error **errp);
+    void (*cleanup)(QCryptoCryptoDevBackend *backend, Error **errp);
+} QCryptoCryptoDevBackendClass;
+
+
+struct QCryptoCryptoDevBackendClientState {
+    char *model;
+    char *name;
+    char info_str[128];
+    unsigned int queue_index;
+    QTAILQ_ENTRY(QCryptoCryptoDevBackendClientState) next;
+};
+
+struct QCryptoCryptoDevBackendPeers {
+    QCryptoCryptoDevBackendClientState *ccs[MAX_CRYPTO_QUEUE_NUM];
+    uint32_t queues;
+};
+
+struct QCryptoCryptoDevBackendConf {
+    QCryptoCryptoDevBackendPeers 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 QCryptoCryptoDevBackend {
+    Object parent_obj;
+
+    int ready;
+    QCryptoCryptoDevBackendConf conf;
+};
+
+/**
+ * qcrypto_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 mode @mode.
+ *
+ * The returned object must be released with
+ * qcrypto_cryptodev_backend_free_client() when no
+ * longer required
+ *
+ * Returns: a new cryptodev backend client object
+ */
+QCryptoCryptoDevBackendClientState *
+qcrypto_cryptodev_backend_new_client(const char *model,
+                                    const char *name);
+/**
+ * qcrypto_cryptodev_backend_free_client:
+ * @cc: the cryptodev backend client object
+ *
+ * Release the memory associated with @cc that
+ * was previously allocated by qcrypto_cryptodev_backend_new_client()
+ */
+void qcrypto_cryptodev_backend_free_client(
+                  QCryptoCryptoDevBackendClientState *cc);
+
+/**
+ * qcrypto_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 qcrypto_cryptodev_backend_cleanup(
+           QCryptoCryptoDevBackend *backend,
+           Error **errp);
+
+#endif /* QCRYPTO_CRYPTODEV_H */
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-03 16:13   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h Gonglei
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

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

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

diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index a15904b..8963019 100644
--- a/backends/cryptodev.c
+++ b/backends/cryptodev.c
@@ -74,6 +74,51 @@ void qcrypto_cryptodev_backend_cleanup(
     backend->ready = 0;
 }
 
+int64_t qcrypto_cryptodev_backend_sym_create_session(
+           QCryptoCryptoDevBackend *backend,
+           QCryptoCryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendClass *bc =
+                      QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->create_session) {
+        return bc->create_session(backend, sess_info, queue_index, errp);
+    }
+
+    return -1;
+}
+
+int qcrypto_cryptodev_backend_sym_close_session(
+           QCryptoCryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendClass *bc =
+                      QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(backend);
+
+    if (bc->close_session) {
+        return bc->close_session(backend, session_id, queue_index, errp);
+    }
+
+    return -1;
+}
+
+int qcrypto_cryptodev_backend_sym_operation(
+                 QCryptoCryptoDevBackend *backend,
+                 QCryptoCryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendClass *bc =
+                      QCRYPTO_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
 qcrypto_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 cc3c3be..ea5e1bb 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -56,12 +56,95 @@ typedef struct QCryptoCryptoDevBackendClientState
                      QCryptoCryptoDevBackendClientState;
 typedef struct QCryptoCryptoDevBackend QCryptoCryptoDevBackend;
 
+enum QCryptoCryptoDevBackendAlgType {
+    QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM,
+    QCRYPTO_CRYPTODEV_BACKEND_ALG__MAX,
+};
+
+/**
+ * QCryptoCryptoDevBackendSymSessionInfo:
+ *
+ * @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: pointer to a key of CIPHER
+ * @auth_key: pointer to an authenticated key of MAC
+ *
+ */
+typedef struct QCryptoCryptoDevBackendSymSessionInfo {
+    /* 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;
+} QCryptoCryptoDevBackendSymSessionInfo;
+
+/**
+ * QCryptoCryptoDevBackendSymOpInfo:
+ *
+ * @session_id: session index which was previously
+ *              created by qcrypto_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, which is equal to
+ *           src_len + hash_result_len if HASH alg configured
+ * @op_type: operation type (refer to virtio_crypto.h)
+ * @iv: pointer to the initialization vector or counter
+ * @src: pointer to the source data
+ * @dst: pointer to the destination data
+ * @dst: pointer to the additional authenticated data
+ * @data[0]: pointer to the extensional memory by one memory allocation
+ *
+ */
+typedef struct QCryptoCryptoDevBackendSymOpInfo {
+    uint64_t session_id;
+    uint32_t aad_len;
+    uint32_t iv_len;
+    uint32_t src_len;
+    /* dst_len is equal to src_len + hash_result_len if hash alg configured */
+    uint32_t dst_len;
+    uint8_t op_type; /* cipher or algo chainning */
+    uint8_t *iv;
+    uint8_t *src;
+    uint8_t *dst;
+    uint8_t *aad_data; /* additional auth data */
+    uint8_t data[0];
+} QCryptoCryptoDevBackendSymOpInfo;
 
 typedef struct QCryptoCryptoDevBackendClass {
     ObjectClass parent_class;
 
     void (*init)(QCryptoCryptoDevBackend *backend, Error **errp);
     void (*cleanup)(QCryptoCryptoDevBackend *backend, Error **errp);
+
+    int64_t (*create_session)(QCryptoCryptoDevBackend *backend,
+                       QCryptoCryptoDevBackendSymSessionInfo *sess_info,
+                       uint32_t queue_index, Error **errp);
+    int (*close_session)(QCryptoCryptoDevBackend *backend,
+                           uint64_t session_id,
+                           uint32_t queue_index, Error **errp);
+    int (*do_sym_op)(QCryptoCryptoDevBackend *backend,
+                     QCryptoCryptoDevBackendSymOpInfo *op_info,
+                     uint32_t queue_index, Error **errp);
 } QCryptoCryptoDevBackendClass;
 
 
@@ -142,4 +225,54 @@ void qcrypto_cryptodev_backend_cleanup(
            QCryptoCryptoDevBackend *backend,
            Error **errp);
 
+/**
+ * qcrypto_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 qcrypto_cryptodev_backend_sym_create_session(
+           QCryptoCryptoDevBackend *backend,
+           QCryptoCryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp);
+
+/**
+ * qcrypto_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 qcrypto_cryptodev_backend_sym_create_session()
+ *
+ * Returns: 0 on success, or Negative on error
+ */
+int qcrypto_cryptodev_backend_sym_close_session(
+           QCryptoCryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp);
+
+/**
+ * qcrypto_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 qcrypto_cryptodev_backend_sym_operation(
+                 QCryptoCryptoDevBackend *backend,
+                 QCryptoCryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp);
+
 #endif /* QCRYPTO_CRYPTODEV_H */
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-03 16:14   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend Gonglei
                   ` (12 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

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

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 include/standard-headers/linux/virtio_crypto.h | 508 +++++++++++++++++++++++++
 1 file changed, 508 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..1b29791
--- /dev/null
+++ b/include/standard-headers/linux/virtio_crypto.h
@@ -0,0 +1,508 @@
+#ifndef _VIRTIO_CRYPTO_H
+#define _VIRTIO_CRYPTO_H
+
+#include "standard-headers/linux/types.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_types.h"
+
+
+struct virtio_crypto_iovec {
+    /* Guest physical address */
+    __virtio64 addr;
+    /* Length of guest physical address */
+    __virtio32 len;
+
+/* This marks a buffer as continuing via the next field */
+#define VIRTIO_CRYPTO_IOVEC_F_NEXT 1
+    /* The flags as indicated above. */
+    __virtio32 flags;
+    /* Pointer to next struct virtio_crypto_iovec if flags & NEXT */
+    __virtio64 next_iovec;
+};
+
+
+#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_output {
+    __virtio64 key_addr; /* guest key physical address */
+};
+
+struct virtio_crypto_cipher_session_req {
+    struct virtio_crypto_cipher_session_para para;
+    struct virtio_crypto_cipher_session_output out;
+    struct virtio_crypto_session_input input;
+};
+
+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_session_input input;
+};
+
+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_session_output {
+    __virtio64 auth_key_addr; /* guest key physical address */
+};
+
+struct virtio_crypto_mac_create_session_req {
+    struct virtio_crypto_mac_session_para para;
+    struct virtio_crypto_mac_session_output out;
+    struct virtio_crypto_session_input input;
+};
+
+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_session_output {
+    __virtio64 key_addr; /* guest key physical address */
+};
+
+struct virtio_crypto_aead_create_session_req {
+    struct virtio_crypto_aead_session_para para;
+    struct virtio_crypto_aead_session_output out;
+    struct virtio_crypto_session_input input;
+};
+
+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_output {
+    struct virtio_crypto_cipher_session_output cipher;
+    struct virtio_crypto_mac_session_output mac;
+};
+
+struct virtio_crypto_alg_chain_session_req {
+    struct virtio_crypto_alg_chain_session_para para;
+    struct virtio_crypto_alg_chain_session_output out;
+    struct virtio_crypto_session_input input;
+};
+
+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;
+    /* Device-writable part */
+    __virtio32  status;
+    __virtio32  padding;
+};
+
+/* 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_sym_input {
+    /* destination data, it's useless for plain HASH and MAC */
+    struct virtio_crypto_iovec dst_data;
+    /* digest result guest address, it's useless for plain cipher algos */
+    __virtio64 digest_result_addr;
+    /* digest result length which is the same with session para above */
+    __virtio32 digest_result_len;
+
+    __virtio32 status;
+};
+
+struct virtio_crypto_cipher_para {
+    /*
+     * Byte Length of valid IV/Counter data pointed to by the below iv_addr
+     * parameter.
+     *
+     * - 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).
+     */
+    __virtio32 iv_len;
+    /* length of source data */
+    __virtio32 src_data_len;
+    /* length of dst data */
+    __virtio32 dst_data_len;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_cipher_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_cipher_output {
+    /*
+     * Initialization Vector or Counter Guest Address.
+     *
+     * - For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
+     *   SNOW3G in UEA2 mode, this is the Initialization Vector (IV)
+     *   value.
+     * - For block ciphers in CTR mode, this is the counter.
+     * - 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.
+     */
+    __virtio64 iv_addr;
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+};
+
+struct virtio_crypto_hash_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_hash_output {
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+    __virtio32 padding;
+};
+
+struct virtio_crypto_mac_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_mac_output {
+    struct virtio_crypto_hash_output hash_output;
+};
+
+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_aead_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_aead_output {
+    /*
+     * Initialization Vector Guest Address.
+     *
+     * - For GCM mode, this is either the IV (if the length is 96 bits) or J0
+     *   (for other sizes), where J0 is as defined by NIST SP800-38D.
+     *   Regardless of the IV length, a full 16 bytes needs to be allocated.
+     * - For CCM mode, the first byte is reserved, and the nonce should be
+     *   written starting at &iv_addr[1] (to allow space for the implementation
+     *   to write in the flags in the first byte).  Note that a full 16 bytes
+     *   should be allocated, even though the iv_len field will have
+     *   a value less than this.
+     *
+     * The IV will be updated after every partial cryptographic operation.
+     */
+    __virtio64 iv_addr;
+    /* source data */
+    struct virtio_crypto_iovec src_data;
+    /* additional auth data guest address */
+    struct virtio_crypto_iovec add_data;
+};
+
+struct virtio_crypto_cipher_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_cipher_para para;
+    struct virtio_crypto_cipher_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_cipher_input idata;
+};
+
+struct virtio_crypto_hash_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_hash_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_hash_input idata;
+};
+
+struct virtio_crypto_mac_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_mac_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_mac_input idata;
+};
+
+struct virtio_crypto_alg_chain_data_para {
+    struct virtio_crypto_cipher_para cipher;
+};
+
+struct virtio_crypto_alg_chain_data_output {
+    /* Device-writable part */
+    struct virtio_crypto_cipher_output cipher;
+
+    /* Device-readable part */
+    /* additional auth data guest address */
+    struct virtio_crypto_iovec add_data;
+};
+
+struct virtio_crypto_alg_chain_data_input {
+    struct virtio_crypto_sym_input input;
+};
+
+struct virtio_crypto_alg_chain_data_req {
+    /* Device-readable part */
+    struct virtio_crypto_alg_chain_data_para para;
+    struct virtio_crypto_alg_chain_data_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_alg_chain_data_input idata;
+};
+
+struct virtio_crypto_sym_data_req {
+    union {
+        struct virtio_crypto_cipher_data_req cipher;
+        struct virtio_crypto_alg_chain_data_req chain;
+    } u;
+
+    /* Device-readable part */
+
+    /* 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;
+    struct virtio_crypto_aead_output odata;
+    /* Device-writable part */
+    struct virtio_crypto_aead_input idata;
+};
+
+/* 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_OP_* 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;
+};
+
+#endif
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (2 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-03 16:31   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation Gonglei
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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 | 345 +++++++++++++++++++++++++++++++++++++++++++
 qemu-options.hx              |  18 +++
 3 files changed, 364 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..22fbe84
--- /dev/null
+++ b/backends/cryptodev-builtin.c
@@ -0,0 +1,345 @@
+/*
+ * 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_QCRYPTO_CRYPTODEV_BACKEND_BUILTIN:
+ * name of backend that uses QEMU cipher API
+ */
+#define TYPE_QCRYPTO_CRYPTODEV_BACKEND_BUILTIN "cryptodev-backend-builtin"
+
+#define QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(obj) \
+    OBJECT_CHECK(QCryptoCryptoDevBackendBuiltin, \
+                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND_BUILTIN)
+
+typedef struct QCryptoCryptoDevBackendBuiltin
+                         QCryptoCryptoDevBackendBuiltin;
+
+typedef struct QCryptoCryptoDevBackendBuiltinSession {
+    QCryptoCipher *cipher;
+    uint8_t direction; /* encryption or decryption */
+    uint8_t type; /* cipher? hash? aead? */
+    QTAILQ_ENTRY(QCryptoCryptoDevBackendBuiltinSession) next;
+} QCryptoCryptoDevBackendBuiltinSession;
+
+/* Max number of symetrical sessions */
+#define MAX_NUM_SESSIONS 256
+
+
+struct QCryptoCryptoDevBackendBuiltin {
+    QCryptoCryptoDevBackend parent_obj;
+
+    QCryptoCryptoDevBackendBuiltinSession *sessions[MAX_NUM_SESSIONS];
+};
+
+static void qcrypto_cryptodev_backend_builtin_init(
+             QCryptoCryptoDevBackend *backend, Error **errp)
+{
+    /* Only support one queue */
+    int queues = MAX(backend->conf.peers.queues, 1);
+    size_t i;
+    QCryptoCryptoDevBackendClientState *cc;
+
+    for (i = 0; i < queues; i++) {
+        cc = qcrypto_cryptodev_backend_new_client(
+                  "cryptodev-builtin", NULL);
+        snprintf(cc->info_str, sizeof(cc->info_str),
+                 "cryptodev-builtin%lu", i);
+        cc->queue_index = i;
+
+        backend->conf.peers.ccs[i] = 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
+qcrypto_cryptodev_backend_builtin_get_unused_session_index(
+      QCryptoCryptoDevBackendBuiltin *builtin)
+{
+    size_t i;
+
+    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
+        if (builtin->sessions[i] == NULL) {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+static int
+qcrypto_cryptodev_backend_builtin_get_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 qcrypto_cryptodev_backend_builtin_create_cipher_session(
+                    QCryptoCryptoDevBackendBuiltin *builtin,
+                    QCryptoCryptoDevBackendSymSessionInfo *sess_info,
+                    Error **errp)
+{
+    int algo;
+    int mode;
+    QCryptoCipher *cipher;
+    int index;
+    QCryptoCryptoDevBackendBuiltinSession *sess;
+
+    if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        error_setg(errp, "unsupported optype :%u", sess_info->op_type);
+        return -1;
+    }
+
+    index = qcrypto_cryptodev_backend_builtin_get_unused_session_index(builtin);
+    if (index < 0) {
+        error_setg(errp, "the total number of created session exceed %u",
+                  MAX_NUM_SESSIONS);
+        return -1;
+    }
+
+    switch (sess_info->cipher_alg) {
+    case VIRTIO_CRYPTO_CIPHER_AES_ECB:
+        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_ECB;
+        break;
+    case VIRTIO_CRYPTO_CIPHER_AES_CBC:
+        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_CBC;
+        break;
+    case VIRTIO_CRYPTO_CIPHER_AES_CTR:
+        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
+                                                          errp);
+        if (algo < 0)  {
+            return -1;
+        }
+        mode = QCRYPTO_CIPHER_MODE_CTR;
+        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(QCryptoCryptoDevBackendBuiltinSession, 1);
+    sess->cipher = cipher;
+    sess->direction = sess_info->direction;
+    sess->type = sess_info->op_type;
+
+    builtin->sessions[index] = sess;
+
+    return index;
+}
+
+static int64_t qcrypto_cryptodev_backend_builtin_sym_create_session(
+           QCryptoCryptoDevBackend *backend,
+           QCryptoCryptoDevBackendSymSessionInfo *sess_info,
+           uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendBuiltin *builtin =
+                      QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(backend);
+    int64_t session_id = -1;
+    int ret;
+
+    switch (sess_info->op_code) {
+    case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+        ret = qcrypto_cryptodev_backend_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 qcrypto_cryptodev_backend_builtin_sym_close_session(
+           QCryptoCryptoDevBackend *backend,
+           uint64_t session_id,
+           uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendBuiltin *builtin =
+                      QCRYPTO_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 qcrypto_cryptodev_backend_builtin_sym_operation(
+                 QCryptoCryptoDevBackend *backend,
+                 QCryptoCryptoDevBackendSymOpInfo *op_info,
+                 uint32_t queue_index, Error **errp)
+{
+    QCryptoCryptoDevBackendBuiltin *builtin =
+                      QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(backend);
+    QCryptoCryptoDevBackendBuiltinSession *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;
+    }
+
+    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 0;
+}
+
+static void qcrypto_cryptodev_backend_builtin_cleanup(
+             QCryptoCryptoDevBackend *backend,
+             Error **errp)
+{
+    QCryptoCryptoDevBackendBuiltin *builtin =
+                      QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(backend);
+    size_t i;
+    int queues = backend->conf.peers.queues;
+    QCryptoCryptoDevBackendClientState *cc;
+
+    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
+        if (builtin->sessions[i] != NULL) {
+            qcrypto_cryptodev_backend_builtin_sym_close_session(
+                    backend, i, 0, errp);
+        }
+    }
+
+    for (i = 0; i < queues; i++) {
+        cc = backend->conf.peers.ccs[i];
+        if (cc) {
+            qcrypto_cryptodev_backend_free_client(cc);
+            backend->conf.peers.ccs[i] = NULL;
+        }
+    }
+}
+
+static void qcrypto_cryptodev_backend_builtin_finalize(Object *obj)
+{
+
+}
+
+static void
+qcrypto_cryptodev_backend_builtin_class_init(ObjectClass *oc, void *data)
+{
+    QCryptoCryptoDevBackendClass *bc = QCRYPTO_CRYPTODEV_BACKEND_CLASS(oc);
+
+    bc->init = qcrypto_cryptodev_backend_builtin_init;
+    bc->cleanup = qcrypto_cryptodev_backend_builtin_cleanup;
+    bc->create_session = qcrypto_cryptodev_backend_builtin_sym_create_session;
+    bc->close_session = qcrypto_cryptodev_backend_builtin_sym_close_session;
+    bc->do_sym_op = qcrypto_cryptodev_backend_builtin_sym_operation;
+}
+
+static const TypeInfo qcrypto_cryptodev_backend_builtin_info = {
+    .name = TYPE_QCRYPTO_CRYPTODEV_BACKEND_BUILTIN,
+    .parent = TYPE_QCRYPTO_CRYPTODEV_BACKEND,
+    .class_init = qcrypto_cryptodev_backend_builtin_class_init,
+    .instance_finalize = qcrypto_cryptodev_backend_builtin_finalize,
+    .instance_size = sizeof(QCryptoCryptoDevBackendBuiltin),
+};
+
+static void
+qcrypto_cryptodev_backend_builtin_register_types(void)
+{
+    type_register_static(&qcrypto_cryptodev_backend_builtin_info);
+}
+
+type_init(qcrypto_cryptodev_backend_builtin_register_types);
diff --git a/qemu-options.hx b/qemu-options.hx
index 01f01df..616cd30 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.7.12.4

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

* [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (3 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-04  9:38   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 06/13] virtio-crypto-pci: add virtio crypto pci support Gonglei
                   ` (10 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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                   | 199 ++++++++++++++++++++++++++++
 include/hw/virtio/virtio-crypto.h           |  74 +++++++++++
 include/standard-headers/linux/virtio_ids.h |   2 +-
 4 files changed, 275 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..e639fb3
--- /dev/null
+++ b/hw/virtio/virtio-crypto.c
@@ -0,0 +1,199 @@
+/*
+ * 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"
+
+
+static void virtio_crypto_process(VirtIOCrypto *vcrypto)
+{
+}
+
+static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
+{
+
+}
+
+static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
+{
+
+}
+
+static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
+                                           uint64_t features,
+                                           Error **errp)
+{
+    return features;
+}
+
+static void virtio_crypto_set_features(VirtIODevice *vdev, uint64_t features)
+{
+
+}
+
+static void virtio_crypto_save(QEMUFile *f, void *opaque)
+{
+    VirtIODevice *vdev = opaque;
+
+    virtio_save(vdev, f);
+}
+
+static int virtio_crypto_load(QEMUFile *f, void *opaque, int version_id)
+{
+    VirtIOCrypto *vcrypto = opaque;
+    int ret;
+
+    if (version_id != 1) {
+        return -EINVAL;
+    }
+    ret = virtio_load(VIRTIO_DEVICE(vcrypto), f, version_id);
+    if (ret != 0) {
+        return ret;
+    }
+
+    /* We may have an element ready but couldn't process it due to a quota
+     * limit.  Make sure to try again after live migration when the quota may
+     * have been reset.
+     */
+    virtio_crypto_process(vcrypto);
+
+    return 0;
+}
+
+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 - 1);
+        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, virtio_crypto_handle_dataq);
+    }
+
+    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
+    if (!vcrypto->cryptodev->ready) {
+        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
+    } else {
+        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
+    }
+    register_savevm(dev, "virtio-crypto", -1, 1, virtio_crypto_save,
+                    virtio_crypto_load, vcrypto);
+}
+
+static void virtio_crypto_device_unrealize(DeviceState *dev, Error **errp)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
+    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(dev);
+
+    unregister_savevm(dev, "virtio-crypto", vcrypto);
+
+    virtio_cleanup(vdev);
+}
+
+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_set_config(VirtIODevice *vdev, const 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;
+    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->set_config = virtio_crypto_set_config;
+    vdc->get_features = virtio_crypto_get_features;
+    vdc->set_features = virtio_crypto_set_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_QCRYPTO_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..484062c
--- /dev/null
+++ b/include/hw/virtio/virtio-crypto.h
@@ -0,0 +1,74 @@
+/*
+ * 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 */
+
+#ifdef DEBUG_VIRTIO_CRYPTO
+#define DPRINTF(fmt, ...) \
+do { printf("virtio_crypto: " fmt , ## __VA_ARGS__); } while (0)
+#else
+#define DPRINTF(fmt, ...) do { } while (0)
+#endif
+
+#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 {
+    QCryptoCryptoDevBackend *cryptodev;
+} VirtIOCryptoConf;
+
+struct VirtIOCrypto;
+
+typedef struct VirtIOCryptoReq {
+    VirtQueueElement elem;
+    /* flags of operation, such as type of algorithm */
+    uint32_t flags;
+    /* address of in data (Device to Driver) */
+    void *idata_hva;
+    VirtQueue *vq;
+    struct VirtIOCrypto *vcrypto;
+    union {
+        QCryptoCryptoDevBackendSymOpInfo *sym_op_info;
+    } u;
+} VirtIOCryptoReq;
+
+typedef struct VirtIOCrypto {
+    VirtIODevice parent_obj;
+
+    VirtQueue *ctrl_vq;
+
+    VirtIOCryptoConf conf;
+    QCryptoCryptoDevBackend *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.7.12.4

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

* [Qemu-devel] [PATCH v4 06/13] virtio-crypto-pci: add virtio crypto pci support
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (4 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported Gonglei
                   ` (9 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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 541cbdb..c493692 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.7.12.4

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

* [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (5 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 06/13] virtio-crypto-pci: add virtio crypto pci support Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-04  9:46   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler Gonglei
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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         | 32 +++++++++++++++++++++++++++++++-
 include/hw/virtio/virtio-crypto.h | 14 ++++++++++++++
 2 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index e639fb3..e74a15f 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -89,6 +89,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);
@@ -122,6 +138,7 @@ static void virtio_crypto_device_realize(DeviceState *dev, Error **errp)
     } else {
         vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
     }
+    virtio_crypto_init_config(vdev);
     register_savevm(dev, "virtio-crypto", -1, 1, virtio_crypto_save,
                     virtio_crypto_load, vcrypto);
 }
@@ -142,7 +159,20 @@ 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;
+
+    crypto_cfg.status = c->status;
+    crypto_cfg.max_dataqueues = c->max_queues;
+    crypto_cfg.crypto_services = c->conf.crypto_services;
+    crypto_cfg.cipher_algo_l = c->conf.cipher_algo_l;
+    crypto_cfg.cipher_algo_h = c->conf.cipher_algo_h;
+    crypto_cfg.hash_algo = c->conf.hash_algo;
+    crypto_cfg.mac_algo_l = c->conf.mac_algo_l;
+    crypto_cfg.mac_algo_h = c->conf.mac_algo_h;
+    crypto_cfg.aead_algo = c->conf.aead_algo;
+
+    memcpy(config, &crypto_cfg, c->config_size);
 }
 
 static void virtio_crypto_set_config(VirtIODevice *vdev, const uint8_t *config)
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
index 484062c..8aa2fe9 100644
--- a/include/hw/virtio/virtio-crypto.h
+++ b/include/hw/virtio/virtio-crypto.h
@@ -38,6 +38,20 @@ do { printf("virtio_crypto: " fmt , ## __VA_ARGS__); } while (0)
 
 typedef struct VirtIOCryptoConf {
     QCryptoCryptoDevBackend *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 asym_algo;
+    uint32_t kdf_algo;
+    uint32_t aead_algo;
+    uint32_t primitive_algo;
 } VirtIOCryptoConf;
 
 struct VirtIOCrypto;
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (6 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-10-04 10:09   ` Stefan Hajnoczi
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 09/13] virtio-crypto: add data queue processing handler Gonglei
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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 | 234 +++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 233 insertions(+), 1 deletion(-)

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index e74a15f..ee1dcdc 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -26,9 +26,241 @@ static void virtio_crypto_process(VirtIOCrypto *vcrypto)
 {
 }
 
-static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
+static inline int virtio_crypto_vq2q(int queue_index)
+{
+    return queue_index;
+}
+
+static void
+virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
+           QCryptoCryptoDevBackendSymSessionInfo *info,
+           struct virtio_crypto_cipher_session_para *cipher_para,
+           struct virtio_crypto_cipher_session_output *cipher_out)
+{
+    hwaddr key_gpa;
+    void *key_hva;
+    hwaddr len;
+
+    info->cipher_alg = cipher_para->algo;
+    info->key_len = cipher_para->keylen;
+    info->direction = cipher_para->op;
+    len = info->key_len;
+    /* get cipher key */
+    if (len > 0) {
+        DPRINTF("keylen=%" PRIu32 "\n", info->key_len);
+        key_gpa = cipher_out->key_addr;
+
+        key_hva = cpu_physical_memory_map(key_gpa, &len, 0);
+
+        info->cipher_key = g_malloc(info->key_len);
+        memcpy(info->cipher_key, key_hva, info->key_len);
+        cpu_physical_memory_unmap(key_hva, len, 0, len);
+    }
+}
+
+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,
+               VirtQueueElement *elem)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    QCryptoCryptoDevBackendSymSessionInfo info;
+    int64_t session_id;
+    int queue_index;
+    uint32_t op_type;
+    hwaddr auth_key_gpa;
+    void *auth_key_hva;
+    struct virtio_crypto_session_input *input;
+    hwaddr len;
+    size_t input_offset;
+    Error *local_err = NULL;
+    struct iovec *iov = elem->in_sg;
+
+    memset(&info, 0, sizeof(info));
+    op_type = sess_req->op_type;
+    info.op_type = op_type;
+    info.op_code = opcode;
+
+    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        virtio_crypto_cipher_session_helper(vdev, &info,
+                           &sess_req->u.cipher.para,
+                           &sess_req->u.cipher.out);
+        /* calculate the offset of input data */
+        input_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                          u.sym_create_session.u.cipher.input);
+        input = (void *)iov[0].iov_base + input_offset;
+    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        /* cipher part */
+        virtio_crypto_cipher_session_helper(vdev, &info,
+                           &sess_req->u.chain.para.cipher_param,
+                           &sess_req->u.chain.out.cipher);
+        /* calculate the offset of input data */
+        input_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                                u.sym_create_session.u.chain.input);
+        input = (void *)iov[0].iov_base + input_offset;
+        /* hash part */
+        info.alg_chain_order = sess_req->u.chain.para.alg_chain_order;
+        info.add_len = sess_req->u.chain.para.aad_len;
+        info.hash_mode = sess_req->u.chain.para.hash_mode;
+        if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH) {
+            info.hash_alg = sess_req->u.chain.para.u.mac_param.algo;
+            len = info.auth_key_len =
+                       sess_req->u.chain.para.u.mac_param.auth_key_len;
+            info.hash_result_len =
+                    sess_req->u.chain.para.u.mac_param.hash_result_len;
+            /* get auth key */
+            if (len > 0) {
+                DPRINTF("keylen=%" PRIu32 "\n", info.auth_key_len);
+                auth_key_gpa = sess_req->u.chain.out.mac.auth_key_addr;
+                auth_key_hva = cpu_physical_memory_map(auth_key_gpa,
+                               &len, false);
+                info.auth_key = g_malloc(len);
+                memcpy(info.auth_key, auth_key_hva, len);
+                cpu_physical_memory_unmap(auth_key_hva, len, false, len);
+            }
+        } else if (info.hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN) {
+            info.hash_alg = sess_req->u.chain.para.u.hash_param.algo;
+            info.hash_result_len =
+                   sess_req->u.chain.para.u.hash_param.hash_result_len;
+        } else {
+            /* VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */
+            error_report("unsupported hash mode");
+            goto err;
+        }
+    } else {
+        /* calculate the offset of input data */
+        input_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                                u.sym_create_session.u.cipher.input);
+        input = (void *)iov[0].iov_base + input_offset;
+        /* VIRTIO_CRYPTO_SYM_OP_NONE */
+        error_report("unsupported cipher type");
+        goto err;
+    }
+
+    queue_index = virtio_crypto_vq2q(queue_id);
+    session_id = qcrypto_cryptodev_backend_sym_create_session(
+                                     vcrypto->cryptodev,
+                                     &info, queue_index, &local_err);
+    if (session_id >= 0) {
+        DPRINTF("create session_id=%" PRIu64 "\n", session_id);
+        /* Set the result, notify the frontend driver soon */
+        input->status = VIRTIO_CRYPTO_OK;
+        input->session_id = session_id;
+
+        g_free(info.cipher_key);
+        g_free(info.auth_key);
+        return 0;
+    } else {
+        if (local_err) {
+            error_report_err(local_err);
+        }
+    }
+
+err:
+    g_free(info.cipher_key);
+    g_free(info.auth_key);
+    input->status = VIRTIO_CRYPTO_ERR;
+    return -1;
+}
+
+static void
+virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
+         struct virtio_crypto_destroy_session_req *close_sess_req,
+         uint32_t queue_id,
+         VirtQueueElement *elem)
 {
+    int ret;
+    uint64_t session_id;
+    uint32_t status;
+    struct iovec *iov = elem->in_sg;
+    size_t status_offset;
+    void *in_status_ptr;
+    Error *local_err = NULL;
+
+    session_id = close_sess_req->session_id;
+    DPRINTF("close session, id=%" PRIu64 "\n", session_id);
+
+    ret = qcrypto_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;
+    }
 
+    /* Calculate the offset of status bits */
+    status_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                             u.destroy_session.status);
+    in_status_ptr = (void *)iov[0].iov_base + status_offset;
+    /* Set the result, notify the frontend driver soon */
+    memcpy(in_status_ptr, &status, sizeof(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;
+    size_t s;
+    struct iovec *iov;
+    unsigned int iov_cnt;
+    uint32_t queue_id;
+    uint32_t opcode;
+
+    for (;;) {
+        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
+        if (!elem) {
+            break;
+        }
+        if (elem->in_num < 1 ||
+            iov_size(elem->in_sg, elem->in_num) < sizeof(ctrl)) {
+            error_report("virtio-crypto ctrl missing headers");
+            exit(1);
+        }
+
+        iov_cnt = elem->in_num;
+        iov = elem->in_sg;
+        s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
+        assert(s == sizeof(ctrl));
+        opcode = ctrl.header.opcode;
+        queue_id = ctrl.header.queue_id;
+
+        switch (opcode) {
+        case VIRTIO_CRYPTO_CIPHER_CREATE_SESSION:
+            virtio_crypto_create_sym_session(vcrypto,
+                             &ctrl.u.sym_create_session,
+                             queue_id, opcode,
+                             elem);
+
+            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:
+            virtio_crypto_handle_close_session(vcrypto,
+                   &ctrl.u.destroy_session, queue_id,
+                   elem);
+            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: %u",
+                         opcode);
+            exit(1);
+        }
+
+        virtqueue_push(vq, elem, sizeof(ctrl));
+        virtio_notify(vdev, vq);
+        g_free(elem);
+    }
 }
 
 static void virtio_crypto_handle_dataq(VirtIODevice *vdev, VirtQueue *vq)
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 09/13] virtio-crypto: add data queue processing handler
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (7 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 10/13] cryptodev: introduce an unified wrapper for crypto operation Gonglei
                   ` (6 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

Firstly I introduce VirtIOCryptoReq structure to store
crypto request so that we can support sync and async
crypto operation in the future.

Secondly, VirtIOCryptoBuffer structure is used to
support sg list on source data, destionation data and
associated anthentication data according virtio
crypto sepcification.

At present, we only support cipher and algorithm
chainning.

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

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index ee1dcdc..a35dbcd 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -263,9 +263,447 @@ static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
     }
 }
 
+static void virtio_crypto_init_request(VirtIOCrypto *vcrypto, VirtQueue *vq,
+                                VirtIOCryptoReq *req)
+{
+    req->vcrypto = vcrypto;
+    req->vq = vq;
+    req->idata_hva = NULL;
+}
+
+static void virtio_crypto_free_request(VirtIOCryptoReq *req)
+{
+    if (req) {
+        if (req->flags == QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM) {
+            g_free(req->u.sym_op_info);
+        }
+        g_free(req);
+    }
+}
+
+static void
+virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
+                void *idata_hva,
+                uint32_t status,
+                QCryptoCryptoDevBackendSymOpInfo *sym_op_info);
+
+static void virtio_crypto_req_complete(VirtIOCryptoReq *req, uint32_t status)
+{
+    VirtIOCrypto *vcrypto = req->vcrypto;
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+
+    if (req->flags == QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM) {
+        virtio_crypto_sym_input_data_helper(vdev, req->idata_hva, status,
+                                            req->u.sym_op_info);
+    }
+
+    virtqueue_push(req->vq, &req->elem,
+                   sizeof(struct virtio_crypto_op_data_req));
+    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 void virtio_crypto_map_iovec(unsigned int *p_num_sg, hwaddr *addr,
+                               struct iovec *iov,
+                               unsigned int max_num_sg,
+                               hwaddr pa, size_t sz,
+                               bool is_write)
+{
+    unsigned num_sg = *p_num_sg;
+    assert(num_sg <= max_num_sg);
+
+    if (!sz) {
+        error_report("virtio-crypto: zero sized buffers are not allowed");
+        exit(1);
+    }
+
+    while (sz) {
+        hwaddr len = sz;
+
+        if (num_sg == max_num_sg) {
+            error_report("virtio-crypto: too many entries "
+                        "in the scatter gather list");
+            exit(1);
+        }
+
+        iov[num_sg].iov_base = cpu_physical_memory_map(pa, &len, is_write);
+        iov[num_sg].iov_len = len;
+        addr[num_sg] = pa;
+
+        sz -= len;
+        pa += len;
+        num_sg++;
+    }
+    *p_num_sg = num_sg;
+}
+
+static void virtio_crypto_unmap_iovec(VirtIOCryptoBuffer *buf,
+                               unsigned int len,
+                               bool is_write)
+{
+    unsigned int offset;
+    size_t i;
+
+    if (is_write) {
+        offset = 0;
+        for (i = 0; i < buf->num; i++) {
+            size_t size = MIN(len - offset, buf->sg[i].iov_len);
+
+            cpu_physical_memory_unmap(buf->sg[i].iov_base,
+                                      buf->sg[i].iov_len,
+                                      1, size);
+
+            offset += size;
+        }
+    } else {
+        for (i = 0; i < buf->num; i++) {
+            cpu_physical_memory_unmap(buf->sg[i].iov_base,
+                                      buf->sg[i].iov_len,
+                                      0, buf->sg[i].iov_len);
+        }
+    }
+}
+
+static void *virtio_crypto_read_next_iovec(VirtIODevice *vdev,
+                                struct virtio_crypto_iovec *iovec,
+                                bool is_write,
+                                struct iovec *iov,
+                                unsigned int *num)
+{
+    struct virtio_crypto_iovec *iovec_hva;
+    hwaddr pa;
+    hwaddr len;
+
+    /* If this descriptor says it doesn't chain, we're done. */
+    if (!(iovec->flags & VIRTIO_CRYPTO_IOVEC_F_NEXT)) {
+        return NULL;
+    }
+
+    pa = iovec->next_iovec;
+    len = sizeof(*iovec_hva);
+    iovec_hva = cpu_physical_memory_map(pa, &len, is_write);
+    assert(len == sizeof(*iovec_hva));
+
+    iov[*num].iov_base = iovec_hva;
+    iov[*num].iov_len = len;
+    (*num)++;
+
+    return iovec_hva;
+}
+
+static void *virtio_crypto_alloc_buf(unsigned num)
+{
+    VirtIOCryptoBuffer *buf;
+    size_t addr_ofs = QEMU_ALIGN_UP(sizeof(*buf), __alignof__(buf->addr[0]));
+    size_t addr_end = addr_ofs + num * sizeof(buf->addr[0]);
+    size_t sg_ofs = QEMU_ALIGN_UP(addr_end, __alignof__(buf->sg[0]));
+    size_t sg_end = sg_ofs + num * sizeof(buf->sg[0]);
+
+    buf = g_malloc(sg_end);
+    buf->num = num;
+
+    buf->addr = (void *)buf + addr_ofs;
+    buf->sg = (void *)buf + sg_ofs;
+    return buf;
+}
+
+static void *virtio_crypto_iovec_read(VirtIODevice *vdev,
+                      struct virtio_crypto_iovec *iovec,
+                      bool is_write)
+{
+
+    VirtIOCryptoBuffer *buf;
+    hwaddr addr[VIRTIO_CRYPTO_SG_MAX];
+    struct iovec iov[VIRTIO_CRYPTO_SG_MAX];
+    unsigned int num = 0;
+    /* Save virtio_crypto_iov structure's hva information in sg_list */
+    struct iovec vc_iov[VIRTIO_CRYPTO_SG_MAX];
+    unsigned int vc_num = 0;
+    size_t i;
+
+    struct virtio_crypto_iovec *p_iovec = iovec;
+
+    /* Collect all the sgs */
+    do {
+        virtio_crypto_map_iovec(&num, addr, iov,
+                           VIRTIO_CRYPTO_SG_MAX,
+                           p_iovec->addr, p_iovec->len,
+                           is_write);
+    } while ((p_iovec = virtio_crypto_read_next_iovec(vdev,
+                p_iovec, false, vc_iov, &vc_num))
+                != NULL);
+
+    /* Now copy what we have collected and mapped */
+    buf = virtio_crypto_alloc_buf(num);
+    for (i = 0; i < num; i++) {
+        buf->addr[i] = addr[i];
+        buf->sg[i] = iov[i];
+    }
+    /* Unmap all virtio_crypto_iov structure if exists */
+    for (i = 0; i < vc_num; i++) {
+        cpu_physical_memory_unmap(vc_iov[i].iov_base,
+                                  vc_iov[i].iov_len,
+                                  false, vc_iov[i].iov_len);
+    }
+
+    return buf;
+}
+
+static QCryptoCryptoDevBackendSymOpInfo *
+virtio_crypto_cipher_op_helper(VirtIODevice *vdev,
+           struct virtio_crypto_cipher_para *para,
+           struct virtio_crypto_cipher_output *out,
+           struct virtio_crypto_iovec *add_data)
+{
+    QCryptoCryptoDevBackendSymOpInfo *op_info;
+    uint32_t src_len, dst_len;
+    uint32_t iv_len;
+    size_t max_len, curr_size = 0;
+    hwaddr iv_gpa;
+    void *iv_hva;
+    hwaddr len;
+    uint32_t aad_len = 0;
+    VirtIOCryptoBuffer *buf;
+    size_t s;
+
+    iv_len = para->iv_len;
+    src_len = para->src_data_len;
+    dst_len = para->dst_data_len;
+
+    if (add_data) {
+        aad_len = add_data->len;
+    }
+
+    max_len = iv_len + aad_len + src_len + dst_len;
+    op_info = g_malloc0(sizeof(QCryptoCryptoDevBackendSymOpInfo) + 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;
+    /* handle the initilization vector */
+    if (op_info->iv_len > 0) {
+        len = op_info->iv_len;
+        DPRINTF("iv_len=%" PRIu32 "\n", len);
+        op_info->iv = op_info->data + curr_size;
+
+        iv_gpa = out->iv_addr;
+        iv_hva = cpu_physical_memory_map(iv_gpa, &len, false);
+        memcpy(op_info->iv, iv_hva, len);
+        cpu_physical_memory_unmap(iv_hva, len, false, len);
+        curr_size += len;
+    }
+
+    /* handle additional authentication data if exist */
+    if (op_info->aad_len > 0) {
+        DPRINTF("aad_len=%" PRIu32 "\n", len);
+        op_info->aad_data = op_info->data + curr_size;
+
+        buf = virtio_crypto_iovec_read(vdev, add_data, false);
+        s = iov_to_buf(buf->sg, buf->num, 0, op_info->aad_data,
+                       op_info->aad_len);
+        assert(s == op_info->aad_len);
+
+        virtio_crypto_unmap_iovec(buf, op_info->aad_len, false);
+        g_free(buf);
+        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;
+
+        buf = virtio_crypto_iovec_read(vdev, &out->src_data, false);
+        s = iov_to_buf(buf->sg, buf->num, 0, op_info->src, op_info->src_len);
+        assert(s == op_info->src_len);
+
+        virtio_crypto_unmap_iovec(buf, op_info->src_len, false);
+        g_free(buf);
+
+        curr_size += op_info->src_len;
+    }
+    op_info->dst = op_info->data + curr_size;
+    DPRINTF("dst_len=%" PRIu32 "\n", op_info->dst_len);
+
+    return op_info;
+}
+
+static void
+virtio_crypto_sym_input_data_helper(VirtIODevice *vdev,
+                void *idata_hva,
+                uint32_t status,
+                QCryptoCryptoDevBackendSymOpInfo *sym_op_info)
+{
+    struct virtio_crypto_sym_input *idata = idata_hva;
+    hwaddr len;
+    VirtIOCryptoBuffer *buf;
+    size_t s;
+
+    idata->status = status;
+    if (status != VIRTIO_CRYPTO_OK) {
+        return;
+    }
+
+    buf = virtio_crypto_iovec_read(vdev, &idata->dst_data, true);
+    /* Note: length of dest_data is equal to length of src_data for cipher */
+    len = sym_op_info->src_len;
+    /* save the cipher result */
+    s = iov_from_buf(buf->sg, buf->num, 0, sym_op_info->dst, len);
+    assert(s == len);
+
+    virtio_crypto_unmap_iovec(buf, len, false);
+    g_free(buf);
+
+    if (sym_op_info->op_type ==
+                      VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        hwaddr digest_gpa;
+        void *digest_hva;
+
+        /* save the digest result */
+        digest_gpa = idata->digest_result_addr;
+        len = idata->digest_result_len;
+        if (len != sym_op_info->dst_len - sym_op_info->src_len) {
+            len = sym_op_info->dst_len - sym_op_info->src_len;
+        }
+        digest_hva = cpu_physical_memory_map(digest_gpa, &len, true);
+        /* find the digest result, then copy it into guest's memory */
+        memcpy(digest_hva, sym_op_info->dst + sym_op_info->src_len, len);
+        cpu_physical_memory_unmap(digest_hva, len, true, len);
+    }
+}
+
+static void
+virtio_crypto_handle_sym_req(VirtIOCrypto *vcrypto,
+               struct virtio_crypto_sym_data_req *req,
+               QCryptoCryptoDevBackendSymOpInfo **sym_op_info,
+               void **idata_hva,
+               VirtQueueElement *elem)
+{
+    VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
+    uint32_t op_type;
+    void *idata;
+    size_t idata_offset;
+    struct iovec *iov = elem->in_sg;
+    QCryptoCryptoDevBackendSymOpInfo *op_info;
+
+    op_type = req->op_type;
+
+    if (op_type == VIRTIO_CRYPTO_SYM_OP_CIPHER) {
+        op_info = virtio_crypto_cipher_op_helper(vdev, &req->u.cipher.para,
+                                              &req->u.cipher.odata, NULL);
+        op_info->op_type = op_type;
+        /* calculate the offset of input data */
+        idata_offset = offsetof(struct virtio_crypto_op_data_req,
+                                u.sym_req.u.cipher.idata.input);
+        idata = (void *)iov[0].iov_base + idata_offset;
+    } else if (op_type == VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING) {
+        /* cipher part */
+        op_info = virtio_crypto_cipher_op_helper(vdev, &req->u.cipher.para,
+                                              &req->u.cipher.odata,
+                                              &req->u.chain.odata.add_data);
+        op_info->op_type = op_type;
+
+        /* calculate the offset of input data */
+        idata_offset = offsetof(struct virtio_crypto_op_data_req,
+                                u.sym_req.u.chain.idata.input);
+        idata = (void *)iov[0].iov_base + idata_offset;
+    } else {
+        /* VIRTIO_CRYPTO_SYM_OP_NONE */
+        error_report("unsupported cipher type");
+        exit(1);
+    }
+
+    *sym_op_info = op_info;
+    *idata_hva = idata;
+}
+
+static void
+virtio_crypto_handle_request(VirtIOCryptoReq *request)
+{
+    VirtIOCrypto *vcrypto = request->vcrypto;
+    VirtQueueElement *elem = &request->elem;
+    int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq));
+    struct virtio_crypto_op_data_req req;
+    size_t s;
+    int ret;
+    struct iovec *iov;
+    unsigned int iov_cnt;
+    uint32_t opcode, status = VIRTIO_CRYPTO_ERR;
+    uint64_t session_id;
+    QCryptoCryptoDevBackendSymOpInfo *sym_op_info = NULL;
+    void *idata_hva = NULL;
+    Error *local_err = NULL;
+
+    if (elem->in_num < 1 ||
+        iov_size(elem->in_sg, elem->in_num) < sizeof(req)) {
+        error_report("virtio-crypto dataq missing headers");
+        exit(1);
+    }
+
+    iov_cnt = elem->in_num;
+    iov = elem->in_sg;
+
+    s = iov_to_buf(iov, iov_cnt, 0, &req, sizeof(req));
+    assert(s == sizeof(req));
+    opcode = req.header.opcode;
+    session_id = req.header.session_id;
+
+    switch (opcode) {
+    case VIRTIO_CRYPTO_CIPHER_ENCRYPT:
+    case VIRTIO_CRYPTO_CIPHER_DECRYPT:
+        virtio_crypto_handle_sym_req(vcrypto,
+                         &req.u.sym_req,
+                         &sym_op_info,
+                         &idata_hva,
+                         elem);
+        sym_op_info->session_id = session_id;
+
+        /* Set request's parameter */
+        request->flags = QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM;
+        request->u.sym_op_info = sym_op_info;
+        request->idata_hva = idata_hva;
+        ret = qcrypto_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);
+        exit(1);
+    }
+}
+
 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))) {
+        virtio_crypto_handle_request(req);
+    }
 }
 
 static uint64_t virtio_crypto_get_features(VirtIODevice *vdev,
diff --git a/include/hw/virtio/virtio-crypto.h b/include/hw/virtio/virtio-crypto.h
index 8aa2fe9..0685ae1 100644
--- a/include/hw/virtio/virtio-crypto.h
+++ b/include/hw/virtio/virtio-crypto.h
@@ -35,6 +35,17 @@ do { printf("virtio_crypto: " fmt , ## __VA_ARGS__); } while (0)
 #define VIRTIO_CRYPTO_GET_PARENT_CLASS(obj) \
         OBJECT_GET_PARENT_CLASS(obj, TYPE_VIRTIO_CRYPTO)
 
+/* Max entries of scatter gather list in one virtio-crypto buffer */
+#define VIRTIO_CRYPTO_SG_MAX 256
+
+typedef struct VirtIOCryptoBuffer {
+    unsigned int num;
+    /* Guest physical address */
+    hwaddr *addr;
+    /* Store host virtual address and length */
+    struct iovec *sg;
+    uint8_t data[0];
+} VirtIOCryptoBuffer;
 
 typedef struct VirtIOCryptoConf {
     QCryptoCryptoDevBackend *cryptodev;
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 10/13] cryptodev: introduce an unified wrapper for crypto operation
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (8 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 09/13] virtio-crypto: add data queue processing handler Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 11/13] virtio-crypto: emulate virtio crypto as a legacy device by default Gonglei
                   ` (5 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	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-builtin.c |  2 +-
 backends/cryptodev.c         | 28 ++++++++++++++++++++++++++--
 hw/virtio/virtio-crypto.c    | 10 +++++-----
 include/sysemu/cryptodev.h   | 13 +++++++------
 4 files changed, 39 insertions(+), 14 deletions(-)

diff --git a/backends/cryptodev-builtin.c b/backends/cryptodev-builtin.c
index 22fbe84..fa207da 100644
--- a/backends/cryptodev-builtin.c
+++ b/backends/cryptodev-builtin.c
@@ -282,7 +282,7 @@ static int qcrypto_cryptodev_backend_builtin_sym_operation(
             return -VIRTIO_CRYPTO_ERR;
         }
     }
-    return 0;
+    return VIRTIO_CRYPTO_OK;
 }
 
 static void qcrypto_cryptodev_backend_builtin_cleanup(
diff --git a/backends/cryptodev.c b/backends/cryptodev.c
index 8963019..6c2381d 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(, QCryptoCryptoDevBackendClientState) crypto_clients;
 
@@ -104,7 +106,7 @@ int qcrypto_cryptodev_backend_sym_close_session(
     return -1;
 }
 
-int qcrypto_cryptodev_backend_sym_operation(
+static int qcrypto_cryptodev_backend_sym_operation(
                  QCryptoCryptoDevBackend *backend,
                  QCryptoCryptoDevBackendSymOpInfo *op_info,
                  uint32_t queue_index, Error **errp)
@@ -116,7 +118,29 @@ int qcrypto_cryptodev_backend_sym_operation(
         return bc->do_sym_op(backend, op_info, queue_index, errp);
     }
 
-    return -1;
+    return -VIRTIO_CRYPTO_ERR;
+}
+
+int qcrypto_cryptodev_backend_crypto_operation(
+                 QCryptoCryptoDevBackend *backend,
+                 void *opaque,
+                 uint32_t queue_index, Error **errp)
+{
+    VirtIOCryptoReq *req = opaque;
+
+    if (req->flags == QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM) {
+        QCryptoCryptoDevBackendSymOpInfo *op_info;
+        op_info = req->u.sym_op_info;
+
+        return qcrypto_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 a35dbcd..6d006c3 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -672,15 +672,15 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request)
         request->flags = QCRYPTO_CRYPTODEV_BACKEND_ALG_SYM;
         request->u.sym_op_info = sym_op_info;
         request->idata_hva = idata_hva;
-        ret = qcrypto_cryptodev_backend_sym_operation(vcrypto->cryptodev,
-                                sym_op_info, queue_index, &local_err);
+        ret = qcrypto_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 ea5e1bb..9ae5b22 100644
--- a/include/sysemu/cryptodev.h
+++ b/include/sysemu/cryptodev.h
@@ -259,20 +259,21 @@ int qcrypto_cryptodev_backend_sym_close_session(
            uint32_t queue_index, Error **errp);
 
 /**
- * qcrypto_cryptodev_backend_sym_operation:
+ * qcrypto_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 qcrypto_cryptodev_backend_sym_operation(
+int qcrypto_cryptodev_backend_crypto_operation(
                  QCryptoCryptoDevBackend *backend,
-                 QCryptoCryptoDevBackendSymOpInfo *op_info,
+                 void *opaque,
                  uint32_t queue_index, Error **errp);
 
 #endif /* QCRYPTO_CRYPTODEV_H */
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 11/13] virtio-crypto: emulate virtio crypto as a legacy device by default
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (9 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 10/13] cryptodev: introduce an unified wrapper for crypto operation Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 12/13] virtio-crypto-test: add qtest case for virtio-crypto Gonglei
                   ` (4 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

the scenario of virtio crypto device is mostly NFV, which require
the existing Guest can't need to do any changes to support virtio
crypto, so that they can easily migrate the existing network units
to VM. That's also a basic requirement came from our customers
in production environment.

For virtio crypto driver, we can both support virtio-1.0 or earlier. But
Virtio pci driver module can't discovery the virtio-1.0 devices in most
existing Guests. If we want do this, we have to require the customers
change the virtio pci module for existing guests influence all virtio
devices, which is impossible.

So, let's emulate the virtio crypto device as a legacy virtio
device by default. Using 0x1014 as virtio crypto pci device ID
because virtio crypto ID is 20 (0x14).

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 docs/specs/pci-ids.txt        | 2 ++
 hw/virtio/virtio-crypto-pci.c | 4 +++-
 include/hw/pci/pci.h          | 2 ++
 3 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/docs/specs/pci-ids.txt b/docs/specs/pci-ids.txt
index fd27c67..662d4f8 100644
--- a/docs/specs/pci-ids.txt
+++ b/docs/specs/pci-ids.txt
@@ -22,6 +22,7 @@ maintained as part of the virtio specification.
 1af4:1004  SCSI host bus adapter device (legacy)
 1af4:1005  entropy generator device (legacy)
 1af4:1009  9p filesystem device (legacy)
+1af4:1014  crypto device (legacy)
 
 1af4:1041  network device (modern)
 1af4:1042  block device (modern)
@@ -32,6 +33,7 @@ maintained as part of the virtio specification.
 1af4:1049  9p filesystem device (modern)
 1af4:1050  virtio gpu device (modern)
 1af4:1052  virtio input device (modern)
+1af4:1054  crypto device (modern)
 
 1af4:10f0  Available for experimental usage without registration.  Must get
    to      official ID when the code leaves the test lab (i.e. when seeking
diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c
index 21d9984..30c10f0 100644
--- a/hw/virtio/virtio-crypto-pci.c
+++ b/hw/virtio/virtio-crypto-pci.c
@@ -32,7 +32,6 @@ static void virtio_crypto_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
     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",
@@ -49,6 +48,9 @@ static void virtio_crypto_pci_class_init(ObjectClass *klass, void *data)
     set_bit(DEVICE_CATEGORY_MISC, dc->categories);
     dc->props = virtio_crypto_pci_properties;
 
+    pcidev_k->vendor_id = PCI_VENDOR_ID_REDHAT_QUMRANET;
+    pcidev_k->device_id = PCI_DEVICE_ID_VIRTIO_CRYPTO;
+    pcidev_k->revision = 0;
     pcidev_k->class_id = PCI_CLASS_OTHERS;
 }
 
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 772692f..5881101 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -83,6 +83,8 @@
 #define PCI_DEVICE_ID_VIRTIO_RNG         0x1005
 #define PCI_DEVICE_ID_VIRTIO_9P          0x1009
 #define PCI_DEVICE_ID_VIRTIO_VSOCK       0x1012
+#define PCI_DEVICE_ID_VIRTIO_CRYPTO      0x1014
+
 
 #define PCI_VENDOR_ID_REDHAT             0x1b36
 #define PCI_DEVICE_ID_REDHAT_BRIDGE      0x0001
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 12/13] virtio-crypto-test: add qtest case for virtio-crypto
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (10 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 11/13] virtio-crypto: emulate virtio crypto as a legacy device by default Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 13/13] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
                   ` (3 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

We can simply test the functions of virtio crypto
device, including session creation, session closing,
cipher encryption and decryption.

Quick usage:
 # make tests/virtio-crypto-test && ./tests/virtio-crypto-test
  CC    tests/virtio-crypto-test.o
  LINK  tests/virtio-crypto-test
 /x86_64/virtio/crypto/pci/basic: OK

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 tests/Makefile.include     |   3 +
 tests/virtio-crypto-test.c | 412 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 415 insertions(+)
 create mode 100644 tests/virtio-crypto-test.c

diff --git a/tests/Makefile.include b/tests/Makefile.include
index 8162f6f..b1baa5c 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -152,6 +152,8 @@ check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF)
 gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c
 check-qtest-virtio-y += $(check-qtest-virtioserial-y)
 gcov-files-virtio-y += $(gcov-files-virtioserial-y)
+check-qtest-virtio-y += tests/virtio-crypto-test$(EXESUF)
+gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-crypto.c
 
 check-qtest-pci-y += tests/e1000-test$(EXESUF)
 gcov-files-pci-y += hw/net/e1000.c
@@ -638,6 +640,7 @@ tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y)
 tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
 tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
 tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
+tests/virtio-crypto-test$(EXESUF): tests/virtio-crypto-test.o $(libqos-virtio-obj-y)
 tests/tpci200-test$(EXESUF): tests/tpci200-test.o
 tests/display-vga-test$(EXESUF): tests/display-vga-test.o
 tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
diff --git a/tests/virtio-crypto-test.c b/tests/virtio-crypto-test.c
new file mode 100644
index 0000000..bbc4089
--- /dev/null
+++ b/tests/virtio-crypto-test.c
@@ -0,0 +1,412 @@
+/*
+ * QTest testcase for 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 later.
+ * See the COPYING file in the top-level directory.
+ */
+
+#include <stdlib.h>
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+#include "libqos/virtio-mmio.h"
+#include "libqos/pci-pc.h"
+#include "libqos/malloc.h"
+#include "libqos/malloc-pc.h"
+#include "libqos/malloc-generic.h"
+#include "qemu/bswap.h"
+#include "standard-headers/linux/virtio_ids.h"
+#include "standard-headers/linux/virtio_config.h"
+#include "standard-headers/linux/virtio_ring.h"
+#include "standard-headers/linux/virtio_crypto.h"
+#include "standard-headers/linux/virtio_pci.h"
+
+#define QVIRTIO_CRYPTO_TIMEOUT_US  (30 * 1000 * 1000)
+
+#define PCI_SLOT_HP             0x06
+#define PCI_SLOT                0x04
+#define PCI_FN                  0x00
+
+/*
+ * VirtIOCryptoCipherTestData:  structure to describe a cipher test
+ * @key:    A pointer to a key used by the test
+ * @key_len:    The length of @key
+ * @iv:     A pointer to the IV/Counter used by the test
+ * @iv_len: The length of @iv
+ * @input:  A pointer to data used as input
+ * @ilen    The length of data in @input
+ * @output: A pointer to what the test need to produce
+ * @olen:   The length of data in @output
+ * @algo:   The type of algorithm, refer to VIRTIO_CRYPTO_CIPHER_AES_*
+ */
+typedef struct VirtIOCryptoCipherTestData {
+    unsigned short algo;
+    const char *key;
+    const char *iv;
+    const char *input;
+    const char *output;
+    unsigned char key_len;
+    unsigned char iv_len;
+    unsigned short ilen;
+    unsigned short olen;
+} VirtIOCryptoCipherTestData;
+
+
+static VirtIOCryptoCipherTestData cipher_test_data[] = {
+    { /* From RFC 3602 */
+        .algo = VIRTIO_CRYPTO_CIPHER_AES_CBC,
+        .key  = "\x06\xa9\x21\x40\x36\xb8\xa1\x5b"
+                "\x51\x2e\x03\xd5\x34\x12\x00\x06",
+        .key_len   = 16,
+        .iv = "\x3d\xaf\xba\x42\x9d\x9e\xb4\x30"
+              "\xb4\x22\xda\x80\x2c\x9f\xac\x41",
+        .iv_len = 16,
+        .input  = "Single block msg",
+        .ilen   = 16,
+        .output = "\xe3\x53\x77\x9c\x10\x79\xae\xb8"
+                  "\x27\x08\x94\x2d\xbe\x77\x18\x1a",
+        .olen   = 16,
+    },
+};
+
+static QPCIBus *virtio_crypto_test_start(void)
+{
+    char *cmdline;
+
+    cmdline = g_strdup_printf(
+               "-object cryptodev-backend-builtin,id=cryptodev0 "
+               "-device virtio-crypto-pci,id=crypto0,"
+               "cryptodev=cryptodev0");
+
+    qtest_start(cmdline);
+    g_free(cmdline);
+
+    return qpci_init_pc();
+}
+
+static void test_end(void)
+{
+    qtest_end();
+}
+
+static QVirtioPCIDevice *virtio_crypto_pci_init(QPCIBus *bus, int slot)
+{
+    QVirtioPCIDevice *dev;
+
+    dev = qvirtio_pci_device_find(bus, VIRTIO_ID_CRYPTO);
+    g_assert(dev != NULL);
+    g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_CRYPTO);
+
+    qvirtio_pci_device_enable(dev);
+    qvirtio_reset(&qvirtio_pci, &dev->vdev);
+    qvirtio_set_acknowledge(&qvirtio_pci, &dev->vdev);
+    qvirtio_set_driver(&qvirtio_pci, &dev->vdev);
+
+    return dev;
+}
+
+static uint64_t
+virtio_crypto_ctrl_request(QGuestAllocator *alloc,
+                           struct virtio_crypto_op_ctrl_req *req)
+{
+    uint64_t addr;
+
+    addr = guest_alloc(alloc, sizeof(*req));
+
+    memwrite(addr, req, sizeof(*req));
+
+    return addr;
+}
+
+static uint64_t
+virtio_crypto_data_request(QGuestAllocator *alloc,
+                           struct virtio_crypto_op_data_req *req)
+{
+    uint64_t addr;
+
+    addr = guest_alloc(alloc, sizeof(*req));
+
+    memwrite(addr, req, sizeof(*req));
+
+    return addr;
+}
+
+static void
+virtio_crypto_driver_init(const QVirtioBus *bus, QVirtioDevice *dev)
+{
+    /* Read configure space to get  supported crypto services */
+
+    qvirtio_set_driver_ok(bus, dev);
+}
+
+static uint64_t
+virtio_crypto_create_session(const QVirtioBus *bus, QVirtioDevice *dev,
+            QGuestAllocator *alloc, QVirtQueue *vq,
+            VirtIOCryptoCipherTestData *data,
+            int encrypt)
+{
+    uint32_t free_head;
+    struct virtio_crypto_op_ctrl_req ctrl;
+    struct virtio_crypto_session_input *input;
+    uint32_t key_len = data->key_len;
+    uint64_t req_addr;
+    uint64_t key_addr; /* cipher key guest physical address */
+    uint64_t session_id;
+    size_t input_offset;
+
+    /* Create an encryption session */
+    ctrl.header.opcode = VIRTIO_CRYPTO_CIPHER_CREATE_SESSION;
+    ctrl.header.algo = data->algo;
+    /* Set the default dataqueue id to 0 */
+    ctrl.header.queue_id = 0;
+
+    ctrl.u.sym_create_session.u.cipher.input.status = VIRTIO_CRYPTO_ERR;
+    /* Pad cipher's parameters */
+    ctrl.u.sym_create_session.op_type = VIRTIO_CRYPTO_SYM_OP_CIPHER;
+    ctrl.u.sym_create_session.u.cipher.para.algo = ctrl.header.algo;
+    ctrl.u.sym_create_session.u.cipher.para.keylen = key_len;
+    if (encrypt) {
+        ctrl.u.sym_create_session.u.cipher.para.op = VIRTIO_CRYPTO_OP_ENCRYPT;
+    } else {
+        ctrl.u.sym_create_session.u.cipher.para.op = VIRTIO_CRYPTO_OP_DECRYPT;
+    }
+    /* Pad cipher's output data */
+    key_addr = guest_alloc(alloc, key_len);
+    memwrite(key_addr, data->key, key_len);
+    ctrl.u.sym_create_session.u.cipher.out.key_addr = key_addr;
+
+    req_addr = virtio_crypto_ctrl_request(alloc, &ctrl);
+
+    free_head = qvirtqueue_add(vq, req_addr, sizeof(ctrl), true, false);
+
+    qvirtqueue_kick(bus, dev, vq, free_head);
+
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_CRYPTO_TIMEOUT_US);
+
+    /* calculate the offset of input data */
+    input_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                      u.sym_create_session.u.cipher.input);
+    input = g_new(struct virtio_crypto_session_input, 1);
+    memread(req_addr + input_offset, (void *)input, sizeof(*input));
+
+    /* Verify the result */
+    g_assert_cmpint(input->status, ==, VIRTIO_CRYPTO_OK);
+
+    session_id = input->session_id;
+
+    g_free(input);
+    guest_free(alloc, key_addr);
+    guest_free(alloc, req_addr);
+
+    return session_id;
+}
+
+static void
+virtio_crypto_close_session(const QVirtioBus *bus, QVirtioDevice *dev,
+            QGuestAllocator *alloc, QVirtQueue *vq,
+            uint64_t session_id)
+{
+    uint32_t free_head;
+    struct virtio_crypto_op_ctrl_req ctrl;
+    uint64_t req_addr;
+    size_t status_offset;
+    uint32_t status;
+
+    /* Create an encryption session */
+    ctrl.header.opcode = VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION;
+    /* Set the default dataqueue id to 0 */
+    ctrl.header.queue_id = 0;
+
+    ctrl.u.destroy_session.session_id = session_id;
+    ctrl.u.destroy_session.status = VIRTIO_CRYPTO_ERR;
+
+    req_addr = virtio_crypto_ctrl_request(alloc, &ctrl);
+
+    free_head = qvirtqueue_add(vq, req_addr, sizeof(ctrl), true, false);
+
+    qvirtqueue_kick(bus, dev, vq, free_head);
+
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_CRYPTO_TIMEOUT_US);
+
+    /* calculate the offset of input data */
+    status_offset = offsetof(struct virtio_crypto_op_ctrl_req,
+                      u.destroy_session.status);
+    memread(req_addr + status_offset, (void *)&status, sizeof(status));
+
+    /* Verify the result */
+    g_assert_cmpint(status, ==, VIRTIO_CRYPTO_OK);
+
+    guest_free(alloc, req_addr);
+}
+
+
+static void
+virtio_crypto_test_cipher(const QVirtioBus *bus, QVirtioDevice *dev,
+            QGuestAllocator *alloc, QVirtQueue *ctrlq,
+            QVirtQueue *vq, VirtIOCryptoCipherTestData *data,
+            int encrypt)
+{
+    uint32_t free_head;
+    struct virtio_crypto_op_data_req req;
+    struct virtio_crypto_sym_input *idata;
+    uint64_t req_addr;
+    uint64_t iv_addr, src_addr, dst_addr;
+    uint64_t session_id;
+    char *output;
+    size_t idata_offset;
+    uint32_t src_len, dst_len;
+
+    /* Create a session */
+    session_id = virtio_crypto_create_session(bus, dev, alloc,
+                                             ctrlq, data, encrypt);
+
+    /* Head of operation */
+    req.header.session_id = session_id;
+    if (encrypt) {
+        req.header.opcode = VIRTIO_CRYPTO_CIPHER_ENCRYPT;
+    } else {
+        req.header.opcode = VIRTIO_CRYPTO_CIPHER_DECRYPT;
+    }
+
+    req.u.sym_req.op_type = VIRTIO_CRYPTO_SYM_OP_CIPHER;
+    req.u.sym_req.u.cipher.para.iv_len = data->iv_len;
+    req.u.sym_req.u.cipher.para.src_data_len = data->ilen;
+    req.u.sym_req.u.cipher.para.dst_data_len = data->olen;
+    /* IV */
+    if (data->iv_len > 0) {
+        iv_addr = guest_alloc(alloc, data->iv_len);
+        memwrite(iv_addr, data->iv, data->iv_len);
+        req.u.sym_req.u.cipher.odata.iv_addr = iv_addr;
+    }
+
+    if (encrypt) {
+        src_len = data->ilen;
+        dst_len = data->olen;
+        /* Source data is the input data which is a single s/g */
+        src_addr = guest_alloc(alloc, src_len);
+        memwrite(src_addr, data->input, src_len);
+    } else {
+        src_len = data->olen;
+        dst_len = data->ilen;
+        /* Source data is the output data which is a single s/g */
+        src_addr = guest_alloc(alloc, src_len);
+        memwrite(src_addr, data->output, src_len);
+    }
+    req.u.sym_req.u.cipher.odata.src_data.addr = src_addr;
+    req.u.sym_req.u.cipher.odata.src_data.len = src_len;
+    req.u.sym_req.u.cipher.odata.src_data.flags = ~VIRTIO_CRYPTO_IOVEC_F_NEXT;
+
+    /* Destination data, a single s/g */
+    dst_addr = guest_alloc(alloc, dst_len);
+    req.u.sym_req.u.cipher.idata.input.dst_data.addr = dst_addr;
+    req.u.sym_req.u.cipher.idata.input.dst_data.len = dst_len;
+    req.u.sym_req.u.cipher.idata.input.dst_data.flags =
+                                                  ~VIRTIO_CRYPTO_IOVEC_F_NEXT;
+
+    req_addr = virtio_crypto_data_request(alloc, &req);
+
+    free_head = qvirtqueue_add(vq, req_addr, sizeof(req), true, false);
+
+    qvirtqueue_kick(bus, dev, vq, free_head);
+
+    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_CRYPTO_TIMEOUT_US);
+
+    /* Calculate the offset of input data */
+    idata_offset = offsetof(struct virtio_crypto_op_data_req,
+                            u.sym_req.u.cipher.idata.input);
+    idata = g_new(struct virtio_crypto_sym_input, 1);
+    memread(req_addr + idata_offset, (void *)idata, sizeof(*idata));
+
+    /* Verify the result */
+    g_assert_cmpint(idata->status, ==, VIRTIO_CRYPTO_OK);
+    g_free(idata);
+
+    output = g_malloc(dst_len);
+    memread(dst_addr, output, dst_len);
+    if (encrypt) {
+        g_assert_cmpstr(output, ==, data->output);
+    } else {
+        g_assert_cmpstr(output, ==, data->input);
+    }
+    g_free(output);
+
+    if (data->iv_len > 0) {
+        guest_free(alloc, iv_addr);
+    }
+    guest_free(alloc, src_addr);
+    guest_free(alloc, dst_addr);
+    guest_free(alloc, req_addr);
+
+    /* Close the session */
+    virtio_crypto_close_session(bus, dev, alloc, ctrlq, session_id);
+}
+
+static void virtio_crypto_pci_basic(void)
+{
+    QVirtioPCIDevice *dev;
+    QPCIBus *bus;
+    QGuestAllocator *alloc;
+    QVirtQueuePCI *dataq, *controlq;
+    size_t i;
+
+    bus = virtio_crypto_test_start();
+    dev = virtio_crypto_pci_init(bus, PCI_SLOT);
+
+    alloc = pc_alloc_init();
+    dataq = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                           alloc, 0);
+    controlq = (QVirtQueuePCI *)qvirtqueue_setup(&qvirtio_pci, &dev->vdev,
+                                           alloc, 1);
+
+    virtio_crypto_driver_init(&qvirtio_pci, &dev->vdev);
+    for (i = 0; i < G_N_ELEMENTS(cipher_test_data); i++) {
+        /* Step 1: Encryption */
+        virtio_crypto_test_cipher(&qvirtio_pci, &dev->vdev, alloc,
+                                  &controlq->vq, &dataq->vq,
+                                  &cipher_test_data[i], 1);
+        /* Step 2: Decryption */
+        virtio_crypto_test_cipher(&qvirtio_pci, &dev->vdev, alloc,
+                                  &controlq->vq, &dataq->vq,
+                                  &cipher_test_data[i], 0);
+    }
+
+    /* End test */
+    qvirtqueue_cleanup(&qvirtio_pci, &dataq->vq, alloc);
+    qvirtqueue_cleanup(&qvirtio_pci, &controlq->vq, alloc);
+    pc_alloc_uninit(alloc);
+    qvirtio_pci_device_disable(dev);
+    g_free(dev);
+    qpci_free_pc(bus);
+    test_end();
+}
+
+int main(int argc, char **argv)
+{
+    const char *qemu;
+    const char *arch;
+    int ret;
+
+    qemu = getenv("QTEST_QEMU_BINARY");
+    if (qemu == NULL) {
+        ret = setenv("QTEST_QEMU_BINARY",
+                     "x86_64-softmmu/qemu-system-x86_64", 0);
+        g_assert(ret == 0);
+    }
+
+    arch = qtest_get_arch();
+
+    g_test_init(&argc, &argv, NULL);
+
+    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+        qtest_add_func("/virtio/crypto/pci/basic", virtio_crypto_pci_basic);
+    }
+
+    return g_test_run();
+}
-- 
1.7.12.4

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

* [Qemu-devel] [PATCH v4 13/13] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (11 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 12/13] virtio-crypto-test: add qtest case for virtio-crypto Gonglei
@ 2016-09-28  8:25 ` Gonglei
  2016-09-28  9:14 ` [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation no-reply
                   ` (2 subsequent siblings)
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei @ 2016-09-28  8:25 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,
	Gonglei

This patch including 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 | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index f3c1f7f..1d5d6c3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -963,6 +963,14 @@ 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
+F: tests/virtio-crypto-test.c
+
 nvme
 M: Keith Busch <keith.busch@intel.com>
 L: qemu-block@nongnu.org
@@ -1199,6 +1207,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.7.12.4

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

* Re: [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (12 preceding siblings ...)
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 13/13] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
@ 2016-09-28  9:14 ` no-reply
  2016-09-28  9:18   ` Gonglei (Arei)
  2016-10-03 12:02 ` Gonglei (Arei)
  2016-10-04 10:13 ` Stefan Hajnoczi
  15 siblings, 1 reply; 35+ messages in thread
From: no-reply @ 2016-09-28  9:14 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

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: 1475051152-400276-1-git-send-email-arei.gonglei@huawei.com
Subject: [Qemu-devel] [PATCH v4 00/13] 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
make J=8 docker-test-quick@centos6
make J=8 docker-test-mingw@fedora
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
Switched to a new branch 'test'
e3a4834 virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer
be93cad virtio-crypto-test: add qtest case for virtio-crypto
94b6765 virtio-crypto: emulate virtio crypto as a legacy device by default
cbcdfa0 cryptodev: introduce an unified wrapper for crypto operation
002bcdc virtio-crypto: add data queue processing handler
234f166 virtio-crypto: add control queue handler
fb27d76 virtio-crypto: set capacity of algorithms supported
389ed7c virtio-crypto-pci: add virtio crypto pci support
25980fc virtio-crypto: add virtio crypto device emulation
7ab6fc8 cryptodev: introduce a new cryptodev backend
403015b virtio-crypto: introduce virtio_crypto.h
e6c85ff cryptodev: add symmetric algorithm operation stuff
b8f95b1 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
  ARCHIVE qemu.tgz
  ARCHIVE dtc.tgz
  COPY RUNNER
  RUN test-quick in 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=c938d8018dd1
TERM=xterm
MAKEFLAGS= -j8
HISTSIZE=1000
J=8
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=/tmp/qemu-test/src/tests/docker/install
No C++ compiler available; disabling C++ specific optional code
Install prefix    /tmp/qemu-test/src/tests/docker/install
BIOS directory    /tmp/qemu-test/src/tests/docker/install/share/qemu
binary directory  /tmp/qemu-test/src/tests/docker/install/bin
library directory /tmp/qemu-test/src/tests/docker/install/lib
module directory  /tmp/qemu-test/src/tests/docker/install/lib/qemu
libexec directory /tmp/qemu-test/src/tests/docker/install/libexec
include directory /tmp/qemu-test/src/tests/docker/install/include
config directory  /tmp/qemu-test/src/tests/docker/install/etc
local state directory   /tmp/qemu-test/src/tests/docker/install/var
Manual directory  /tmp/qemu-test/src/tests/docker/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 -pthread -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include   -g 
QEMU_CFLAGS       -I/usr/include/pixman-1    -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
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   x86_64-softmmu/config-devices.mak
  GEN   aarch64-softmmu/config-devices.mak
  GEN   qmp-introspect.h
  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   config-all-devices.mak
  GEN   trace/generated-events.h
  GEN   trace/generated-tracers.h
  GEN   trace/generated-tcg-tracers.h
  GEN   trace/generated-helpers-wrappers.h
  GEN   trace/generated-helpers.h
  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-input-visitor.o
  CC    qapi/qmp-output-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-events.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/qemu-thread-posix.o
  CC    util/memfd.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/rfifolock.o
  CC    util/readline.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/log.o
  CC    util/qdist.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
/tmp/qemu-test/src/util/qht.c: In function ‘qht_reset_size’:
/tmp/qemu-test/src/util/qht.c:413: warning: ‘new’ may be used uninitialized in this function
  CC    stubs/arch-query-cpu-model-baseline.o
  CC    stubs/bdrv-next-monitor-owned.o
  CC    stubs/blk-commit-all.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-add-fd.o
  CC    stubs/fdset-find-fd.o
  CC    stubs/fdset-get-fd.o
  CC    stubs/fdset-remove-fd.o
  CC    stubs/gdbstub.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/migr-blocker.o
  CC    stubs/machine-init-done.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/vm-stop.o
  CC    stubs/uuid.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-essiv.o
  CC    crypto/ivgen.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    os-posix.o
  CC    qemu-char.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    audio/audio.o
  CC    audio/noaudio.o
  CC    audio/wavaudio.o
  CC    audio/mixeng.o
  CC    audio/sdlaudio.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/cryptodev.o
  CC    backends/hostmem-file.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
/tmp/qemu-test/src/backends/cryptodev-builtin.c: In function ‘qcrypto_cryptodev_backend_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:107: 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] 35+ messages in thread

* Re: [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
  2016-09-28  9:14 ` [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation no-reply
@ 2016-09-28  9:18   ` Gonglei (Arei)
  0 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-09-28  9:18 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)

> -----Original Message-----
> From: no-reply@patchew.org [mailto:no-reply@patchew.org]
> Sent: Wednesday, September 28, 2016 5:15 PM
> Subject: Re: [Qemu-devel] [PATCH v4 00/13] 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.
> 
>   CC    hw/acpi/pcihp.o
>   CC    hw/acpi/ich9.o
> /tmp/qemu-test/src/backends/cryptodev-builtin.c: In function
> ‘qcrypto_cryptodev_backend_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:107: recipe for target
> 'docker-run-test-quick@centos6' failed
> make: *** [docker-run-test-quick@centos6] Error 2
> === OUTPUT END ===
> 
About 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

Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (13 preceding siblings ...)
  2016-09-28  9:14 ` [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation no-reply
@ 2016-10-03 12:02 ` Gonglei (Arei)
  2016-10-04 10:13 ` Stefan Hajnoczi
  15 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-03 12:02 UTC (permalink / raw)
  To: qemu-devel, virtio-dev
  Cc: Luonengjun, Michael S. Tsirkin, Stefan Hajnoczi, Paolo Bonzini,
	Daniel P. Berrange, Huangweidong (C), Wubin (H),
	Mihai Claudiu Caraman, Alexander Graf, Zeng, Xin,
	Claudio Fontana, Nicolas Morey-Chaisemartin, Vincent JARDIN,
	Zhoujian (jay, Euler), Hanweidong (Randy), Huangpeng (Peter)

Ping...

Please help to review the patch set in order to catch up with the qemu-2.8' time window if possible. Thanks a lot!

Regards,
-Gonglei
发件人:龚磊
收件人:qemu-devel,virtio-dev@lists.oasis-open.org,
抄送:骆能军,Michael S. Tsirkin,Stefan Hajnoczi,Paolo Bonzini,Daniel P. Berrange,黄伟栋,吴斌,Mihai Claudiu Caraman,Alexander Graf,Zeng, Xin,Claudio Fontana,Nicolas Morey-Chaisemartin,Vincent JARDIN,周健,韩伟东,黄鹏,龚磊,
时间:2016-09-28 16:26:20
主题:[PATCH v4 00/13] virtio-crypto: introduce framework and device emulation

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 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 (13):
  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: emulate virtio crypto as a legacy device by default
  virtio-crypto-test: add qtest case for virtio-crypto
  virtio-crypto: add myself as virtio-crypto and cryptodev backends
    maintainer

 MAINTAINERS                                    |  14 +
 backends/Makefile.objs                         |   3 +
 backends/cryptodev-builtin.c                   | 345 ++++++++++
 backends/cryptodev.c                           | 244 +++++++
 docs/specs/pci-ids.txt                         |   2 +
 hw/virtio/Makefile.objs                        |   2 +
 hw/virtio/virtio-crypto-pci.c                  |  79 +++
 hw/virtio/virtio-crypto.c                      | 899 +++++++++++++++++++++++++
 hw/virtio/virtio-pci.h                         |  15 +
 include/hw/pci/pci.h                           |   2 +
 include/hw/virtio/virtio-crypto.h              |  99 +++
 include/standard-headers/linux/virtio_crypto.h | 508 ++++++++++++++
 include/standard-headers/linux/virtio_ids.h    |   2 +-
 include/sysemu/cryptodev.h                     | 279 ++++++++
 qemu-options.hx                                |  18 +
 tests/Makefile.include                         |   3 +
 tests/virtio-crypto-test.c                     | 412 +++++++++++
 17 files changed, 2925 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
 create mode 100644 tests/virtio-crypto-test.c

--
1.7.12.4



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

* Re: [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface Gonglei
@ 2016-10-03 16:10   ` Stefan Hajnoczi
  2016-10-03 16:15     ` Daniel P. Berrange
  2016-10-05  3:06     ` Gonglei (Arei)
  0 siblings, 2 replies; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-03 16:10 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:40PM +0800, Gonglei wrote:
> diff --git a/backends/cryptodev.c b/backends/cryptodev.c
> new file mode 100644
> index 0000000..a15904b
> --- /dev/null
> +++ b/backends/cryptodev.c
> @@ -0,0 +1,175 @@
> +/*
> + * QEMU Crypto Device Implement

s/Implement/Implementation/

> diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
> new file mode 100644
> index 0000000..cc3c3be
> --- /dev/null
> +++ b/include/sysemu/cryptodev.h
> @@ -0,0 +1,145 @@
> +/*
> + * QEMU Crypto Device Implement

s/Implement/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 QCRYPTO_CRYPTODEV_H
> +#define QCRYPTO_CRYPTODEV_H
> +
> +#include "qom/object.h"
> +#include "qemu-common.h"
> +
> +/**
> + * QCryptoCryptoDevBackend:
> + *
> + * The QCryptoCryptoDevBackend object is an interface
> + * for different cryptodev backends, which provides crypto
> + * operation wrapper.

I suggest calling it CryptoDevBackend since that's shorter and doesn't
repeat any information.  I'm not sure why "QCrypto" is necessary.

> + *
> + */
> +
> +#define TYPE_QCRYPTO_CRYPTODEV_BACKEND "cryptodev-backend"
> +
> +#define QCRYPTO_CRYPTODEV_BACKEND(obj) \
> +    OBJECT_CHECK(QCryptoCryptoDevBackend, \
> +                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> +#define QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(obj) \
> +    OBJECT_GET_CLASS(QCryptoCryptoDevBackendClass, \
> +                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> +#define QCRYPTO_CRYPTODEV_BACKEND_CLASS(klass) \
> +    OBJECT_CLASS_CHECK(QCryptoCryptoDevBackendClass, \
> +                (klass), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> +
> +
> +#define MAX_CRYPTO_QUEUE_NUM  64
> +
> +typedef struct QCryptoCryptoDevBackendConf QCryptoCryptoDevBackendConf;
> +typedef struct QCryptoCryptoDevBackendPeers QCryptoCryptoDevBackendPeers;
> +typedef struct QCryptoCryptoDevBackendClientState
> +                     QCryptoCryptoDevBackendClientState;
> +typedef struct QCryptoCryptoDevBackend QCryptoCryptoDevBackend;
> +
> +
> +typedef struct QCryptoCryptoDevBackendClass {
> +    ObjectClass parent_class;
> +
> +    void (*init)(QCryptoCryptoDevBackend *backend, Error **errp);
> +    void (*cleanup)(QCryptoCryptoDevBackend *backend, Error **errp);
> +} QCryptoCryptoDevBackendClass;
> +
> +
> +struct QCryptoCryptoDevBackendClientState {

The naming could be simplified: CryptoDevClient.

> +    char *model;
> +    char *name;
> +    char info_str[128];

This should probably be char *info_str unless there is a specific reason
to use a fixed-size buffer.

> +    unsigned int queue_index;
> +    QTAILQ_ENTRY(QCryptoCryptoDevBackendClientState) next;
> +};
> +
> +struct QCryptoCryptoDevBackendPeers {
> +    QCryptoCryptoDevBackendClientState *ccs[MAX_CRYPTO_QUEUE_NUM];
> +    uint32_t queues;
> +};
> +
> +struct QCryptoCryptoDevBackendConf {
> +    QCryptoCryptoDevBackendPeers 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 QCryptoCryptoDevBackend {
> +    Object parent_obj;
> +
> +    int ready;

Please use bool.  That way it's clear the field only takes true and
false values.

> +    QCryptoCryptoDevBackendConf conf;
> +};
> +
> +/**
> + * qcrypto_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 mode @mode.

s/mode/model/

> + *
> + * The returned object must be released with
> + * qcrypto_cryptodev_backend_free_client() when no
> + * longer required
> + *
> + * Returns: a new cryptodev backend client object
> + */
> +QCryptoCryptoDevBackendClientState *
> +qcrypto_cryptodev_backend_new_client(const char *model,
> +                                    const char *name);
> +/**
> + * qcrypto_cryptodev_backend_free_client:
> + * @cc: the cryptodev backend client object
> + *
> + * Release the memory associated with @cc that
> + * was previously allocated by qcrypto_cryptodev_backend_new_client()
> + */
> +void qcrypto_cryptodev_backend_free_client(
> +                  QCryptoCryptoDevBackendClientState *cc);
> +
> +/**
> + * qcrypto_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 qcrypto_cryptodev_backend_cleanup(
> +           QCryptoCryptoDevBackend *backend,
> +           Error **errp);
> +
> +#endif /* QCRYPTO_CRYPTODEV_H */
> -- 
> 1.7.12.4
> 
> 

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff Gonglei
@ 2016-10-03 16:13   ` Stefan Hajnoczi
  2016-10-05  3:07     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-03 16:13 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:41PM +0800, Gonglei wrote:
> This patch add session operation and crypto operation

s/add/adds/

> stuff in the cryptodev backend, including function
> pointers and correpsonding structures.

s/correpsonding/corresponding/

> +/**
> + * QCryptoCryptoDevBackendSymOpInfo:
> + *
> + * @session_id: session index which was previously
> + *              created by qcrypto_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, which is equal to
> + *           src_len + hash_result_len if HASH alg configured
> + * @op_type: operation type (refer to virtio_crypto.h)
> + * @iv: pointer to the initialization vector or counter
> + * @src: pointer to the source data
> + * @dst: pointer to the destination data
> + * @dst: pointer to the additional authenticated data

s/dst/aad_data/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h Gonglei
@ 2016-10-03 16:14   ` Stefan Hajnoczi
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-03 16:14 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:42PM +0800, Gonglei wrote:
> Introdue the virtio_crypto.h which follows

s/Introdue/Introduce/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface
  2016-10-03 16:10   ` Stefan Hajnoczi
@ 2016-10-03 16:15     ` Daniel P. Berrange
  2016-10-05  3:06     ` Gonglei (Arei)
  1 sibling, 0 replies; 35+ messages in thread
From: Daniel P. Berrange @ 2016-10-03 16:15 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: Gonglei, qemu-devel, virtio-dev, luonengjun, mst, pbonzini,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

On Mon, Oct 03, 2016 at 05:10:48PM +0100, Stefan Hajnoczi wrote:
> On Wed, Sep 28, 2016 at 04:25:40PM +0800, Gonglei wrote:
> > diff --git a/backends/cryptodev.c b/backends/cryptodev.c
> > new file mode 100644
> > index 0000000..a15904b
> > --- /dev/null
> > +++ b/backends/cryptodev.c
> > @@ -0,0 +1,175 @@
> > +/*
> > + * QEMU Crypto Device Implement
> 
> s/Implement/Implementation/
> 
> > diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
> > new file mode 100644
> > index 0000000..cc3c3be
> > --- /dev/null
> > +++ b/include/sysemu/cryptodev.h
> > @@ -0,0 +1,145 @@
> > +/*
> > + * QEMU Crypto Device Implement
> 
> s/Implement/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 QCRYPTO_CRYPTODEV_H
> > +#define QCRYPTO_CRYPTODEV_H
> > +
> > +#include "qom/object.h"
> > +#include "qemu-common.h"
> > +
> > +/**
> > + * QCryptoCryptoDevBackend:
> > + *
> > + * The QCryptoCryptoDevBackend object is an interface
> > + * for different cryptodev backends, which provides crypto
> > + * operation wrapper.
> 
> I suggest calling it CryptoDevBackend since that's shorter and doesn't
> repeat any information.  I'm not sure why "QCrypto" is necessary.

I suggested that naming when we had it under the crypto/ directory,
since that's the standard for code there. We've moved this into
the backends/ directory now, so we don't need that name prefix
anymore.




Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://entangle-photo.org       -o-    http://search.cpan.org/~danberr/ :|

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

* Re: [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend Gonglei
@ 2016-10-03 16:31   ` Stefan Hajnoczi
  2016-10-05  3:19     ` Gonglei (Arei)
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-03 16:31 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:43PM +0800, Gonglei wrote:
> +/* Max number of symetrical sessions */

s/symetrical/symmetric/

But why does the comment say "symetrical" when the constant name
MAX_NUM_SESSIONS seems to be a global limit for *all* sessions (not just
symmetric)?

> +#define MAX_NUM_SESSIONS 256

The guest can only have 256 sessions open?

What are the limits of real crypto libraries and accelerators?

> +
> +
> +struct QCryptoCryptoDevBackendBuiltin {
> +    QCryptoCryptoDevBackend parent_obj;
> +
> +    QCryptoCryptoDevBackendBuiltinSession *sessions[MAX_NUM_SESSIONS];
> +};
> +
> +static void qcrypto_cryptodev_backend_builtin_init(
> +             QCryptoCryptoDevBackend *backend, Error **errp)
> +{
> +    /* Only support one queue */
> +    int queues = MAX(backend->conf.peers.queues, 1);
> +    size_t i;
> +    QCryptoCryptoDevBackendClientState *cc;
> +
> +    for (i = 0; i < queues; i++) {
> +        cc = qcrypto_cryptodev_backend_new_client(
> +                  "cryptodev-builtin", NULL);
> +        snprintf(cc->info_str, sizeof(cc->info_str),
> +                 "cryptodev-builtin%lu", i);
> +        cc->queue_index = i;
> +
> +        backend->conf.peers.ccs[i] = 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
> +qcrypto_cryptodev_backend_builtin_get_unused_session_index(
> +      QCryptoCryptoDevBackendBuiltin *builtin)
> +{
> +    size_t i;
> +
> +    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
> +        if (builtin->sessions[i] == NULL) {
> +            return i;
> +        }
> +    }
> +
> +    return -1;
> +}
> +
> +static int
> +qcrypto_cryptodev_backend_builtin_get_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 qcrypto_cryptodev_backend_builtin_create_cipher_session(
> +                    QCryptoCryptoDevBackendBuiltin *builtin,
> +                    QCryptoCryptoDevBackendSymSessionInfo *sess_info,
> +                    Error **errp)
> +{
> +    int algo;
> +    int mode;
> +    QCryptoCipher *cipher;
> +    int index;
> +    QCryptoCryptoDevBackendBuiltinSession *sess;
> +
> +    if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
> +        error_setg(errp, "unsupported optype :%u", sess_info->op_type);
> +        return -1;
> +    }
> +
> +    index = qcrypto_cryptodev_backend_builtin_get_unused_session_index(builtin);

Feel free to omit the function name prefix for static functions.  These
names are very long.

> +    if (index < 0) {
> +        error_setg(errp, "the total number of created session exceed %u",

"Total number of sessions created exceeds %u"

> +                  MAX_NUM_SESSIONS);
> +        return -1;
> +    }
> +
> +    switch (sess_info->cipher_alg) {
> +    case VIRTIO_CRYPTO_CIPHER_AES_ECB:
> +        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> +                                                          errp);
> +        if (algo < 0)  {
> +            return -1;
> +        }
> +        mode = QCRYPTO_CIPHER_MODE_ECB;
> +        break;
> +    case VIRTIO_CRYPTO_CIPHER_AES_CBC:
> +        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> +                                                          errp);
> +        if (algo < 0)  {
> +            return -1;
> +        }
> +        mode = QCRYPTO_CIPHER_MODE_CBC;
> +        break;
> +    case VIRTIO_CRYPTO_CIPHER_AES_CTR:
> +        algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> +                                                          errp);
> +        if (algo < 0)  {
> +            return -1;
> +        }
> +        mode = QCRYPTO_CIPHER_MODE_CTR;
> +        break;
> +    default:
> +        error_setg(errp, "unsupported cipher alg :%u",
> +                   sess_info->cipher_alg);
> +        return -1;
> +    }

Code duplication can be eliminated:

switch (sess_info->cipher_alg) {
case VIRTIO_CRYPTO_CIPHER_AES_ECB:
    mode = QCRYPTO_CIPHER_MODE_ECB;
    break;
...
}

algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
                                                  errp);
if (algo < 0) {
    return -1;
}

> +static void qcrypto_cryptodev_backend_builtin_cleanup(
> +             QCryptoCryptoDevBackend *backend,
> +             Error **errp)
> +{
> +    QCryptoCryptoDevBackendBuiltin *builtin =
> +                      QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(backend);
> +    size_t i;
> +    int queues = backend->conf.peers.queues;
> +    QCryptoCryptoDevBackendClientState *cc;
> +
> +    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
> +        if (builtin->sessions[i] != NULL) {
> +            qcrypto_cryptodev_backend_builtin_sym_close_session(
> +                    backend, i, 0, errp);
> +        }
> +    }
> +
> +    for (i = 0; i < queues; i++) {

This device doesn't seem to support queues because queue_index is
ignored by all functions that take it.

Perhaps there should be an error if the device is realized with more
than 1 queue?

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation Gonglei
@ 2016-10-04  9:38   ` Stefan Hajnoczi
  2016-10-05  3:26     ` Gonglei (Arei)
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-04  9:38 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:44PM +0800, Gonglei wrote:
> 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

This patch contains functions and struct fields that are unused.  It
would make code review easier if you add them when they are needed
throughout the patch series.

> +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 - 1);

The error message is off by 1:

must be a positive integer less than 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, virtio_crypto_handle_dataq);
> +    }
> +
> +    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64, virtio_crypto_handle_ctrl);
> +    if (!vcrypto->cryptodev->ready) {
> +        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
> +    } else {
> +        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
> +    }
> +    register_savevm(dev, "virtio-crypto", -1, 1, virtio_crypto_save,
> +                    virtio_crypto_load, vcrypto);

Please use VMSTATE_VIRTIO_DEVICE() instead of calling register_savevm().

> +#ifdef DEBUG_VIRTIO_CRYPTO
> +#define DPRINTF(fmt, ...) \
> +do { printf("virtio_crypto: " fmt , ## __VA_ARGS__); } while (0)
> +#else
> +#define DPRINTF(fmt, ...) do { } while (0)
> +#endif

Please use tracing (see docs/tracing.txt) or if you really want to use
debug printfs then define DPRINTF() in a way that prevents bitrot:

#define DEBUG_VIRTIO_CRYPTO 0
#define DPRINTF(fmt, ...) \
do { \
    if (DEBUG_VIRTIO_CRYPTO) { \
        fprintf(stderr, "virtio_crypto: " fmt, ##__VA_ARGS__); \
    } \
} while (0)

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported Gonglei
@ 2016-10-04  9:46   ` Stefan Hajnoczi
  2016-10-05  3:30     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-04  9:46 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:46PM +0800, Gonglei wrote:
>  static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
>  {
> -
> +    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);
> +    struct virtio_crypto_config crypto_cfg;
> +
> +    crypto_cfg.status = c->status;
> +    crypto_cfg.max_dataqueues = c->max_queues;
> +    crypto_cfg.crypto_services = c->conf.crypto_services;
> +    crypto_cfg.cipher_algo_l = c->conf.cipher_algo_l;
> +    crypto_cfg.cipher_algo_h = c->conf.cipher_algo_h;
> +    crypto_cfg.hash_algo = c->conf.hash_algo;
> +    crypto_cfg.mac_algo_l = c->conf.mac_algo_l;
> +    crypto_cfg.mac_algo_h = c->conf.mac_algo_h;
> +    crypto_cfg.aead_algo = c->conf.aead_algo;
> +
> +    memcpy(config, &crypto_cfg, c->config_size);
>  }

What about endianness?  For example, if the host is big-endian then this
VIRTIO 1.0 device needs to byteswap multi-byte fields.  There is a
family of functions to help with this: virtio_stl_p().

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler
  2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler Gonglei
@ 2016-10-04 10:09   ` Stefan Hajnoczi
  2016-10-05  3:38     ` Gonglei (Arei)
  0 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-04 10:09 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:47PM +0800, Gonglei wrote:
> -static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
> +static inline int virtio_crypto_vq2q(int queue_index)
> +{
> +    return queue_index;
> +}

Please document this function.  I think it takes a virtqueue index and
returns the crypto queue.  The ctrl virtqueue is after the op virtqueues
so the input value doesn't need to be adjusted.

Without this information it's hard to understand the function.

> +
> +static void
> +virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
> +           QCryptoCryptoDevBackendSymSessionInfo *info,
> +           struct virtio_crypto_cipher_session_para *cipher_para,
> +           struct virtio_crypto_cipher_session_output *cipher_out)
> +{
> +    hwaddr key_gpa;
> +    void *key_hva;
> +    hwaddr len;
> +
> +    info->cipher_alg = cipher_para->algo;
> +    info->key_len = cipher_para->keylen;
> +    info->direction = cipher_para->op;

Endianness?  Use the virtio_ldl_p() family of functions to load values
from the guest.

This same issue is present in the rest of the code.  I won't mentioned
it again but please fix all occurrences.

> +    len = info->key_len;
> +    /* get cipher key */
> +    if (len > 0) {
> +        DPRINTF("keylen=%" PRIu32 "\n", info->key_len);
> +        key_gpa = cipher_out->key_addr;
> +
> +        key_hva = cpu_physical_memory_map(key_gpa, &len, 0);

virtio devices should not use cpu_physical_memory_map().  Please see my
reply to the virtio-crypto specification about scatter-gather I/O.

> +static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
> +{
> +    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
> +    struct virtio_crypto_op_ctrl_req ctrl;
> +    VirtQueueElement *elem;
> +    size_t s;
> +    struct iovec *iov;
> +    unsigned int iov_cnt;
> +    uint32_t queue_id;
> +    uint32_t opcode;
> +
> +    for (;;) {
> +        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
> +        if (!elem) {
> +            break;
> +        }
> +        if (elem->in_num < 1 ||
> +            iov_size(elem->in_sg, elem->in_num) < sizeof(ctrl)) {
> +            error_report("virtio-crypto ctrl missing headers");
> +            exit(1);
> +        }

Please use virtio_error() instead.  virtio devices should not call
exit(1).  There are other instances of this throughout the code, please
fix all of them.

> +
> +        iov_cnt = elem->in_num;
> +        iov = elem->in_sg;
> +        s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
> +        assert(s == sizeof(ctrl));

This assert is always true because you checked iov_size() above.  Please
move that check down here and drop the assert.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
  2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
                   ` (14 preceding siblings ...)
  2016-10-03 12:02 ` Gonglei (Arei)
@ 2016-10-04 10:13 ` Stefan Hajnoczi
  2016-10-05  3:42   ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
  15 siblings, 1 reply; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-04 10:13 UTC (permalink / raw)
  To: Gonglei
  Cc: qemu-devel, virtio-dev, luonengjun, mst, pbonzini, berrange,
	weidong.huang, wu.wubin, mike.caraman, agraf, xin.zeng,
	claudio.fontana, nmorey, vincent.jardin, jianjay.zhou,
	hanweidong, peter.huangpeng

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

On Wed, Sep 28, 2016 at 04:25:39PM +0800, Gonglei wrote:
> 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.

Please look at my reply to the virtio-crypto spec email thread.  Changes
to the request layout are necessary (dropping custom scatter-gather I/O,
avoiding assumptions about iovec layout, ordering of
device-readable/writable buffers).

This will change the code quite a bit so I won't review further for now.

Stefan

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface
  2016-10-03 16:10   ` Stefan Hajnoczi
  2016-10-03 16:15     ` Daniel P. Berrange
@ 2016-10-05  3:06     ` Gonglei (Arei)
  1 sibling, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:06 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> Sent: Tuesday, October 04, 2016 12:11 AM
> Subject: Re: [PATCH v4 01/13] cryptodev: introduce cryptodev backend
> interface
> 
> On Wed, Sep 28, 2016 at 04:25:40PM +0800, Gonglei wrote:
> > diff --git a/backends/cryptodev.c b/backends/cryptodev.c
> > new file mode 100644
> > index 0000000..a15904b
> > --- /dev/null
> > +++ b/backends/cryptodev.c
> > @@ -0,0 +1,175 @@
> > +/*
> > + * QEMU Crypto Device Implement
> 
> s/Implement/Implementation/
> 
> > diff --git a/include/sysemu/cryptodev.h b/include/sysemu/cryptodev.h
> > new file mode 100644
> > index 0000000..cc3c3be
> > --- /dev/null
> > +++ b/include/sysemu/cryptodev.h
> > @@ -0,0 +1,145 @@
> > +/*
> > + * QEMU Crypto Device Implement
> 
> s/Implement/Implementation/
> 
OK.

> > + *
> > + * 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 QCRYPTO_CRYPTODEV_H
> > +#define QCRYPTO_CRYPTODEV_H
> > +
> > +#include "qom/object.h"
> > +#include "qemu-common.h"
> > +
> > +/**
> > + * QCryptoCryptoDevBackend:
> > + *
> > + * The QCryptoCryptoDevBackend object is an interface
> > + * for different cryptodev backends, which provides crypto
> > + * operation wrapper.
> 
> I suggest calling it CryptoDevBackend since that's shorter and doesn't
> repeat any information.  I'm not sure why "QCrypto" is necessary.
> 
Ok, and Daniel explained the reason in another reply. I'll rename those stuff.

> > + *
> > + */
> > +
> > +#define TYPE_QCRYPTO_CRYPTODEV_BACKEND "cryptodev-backend"
> > +
> > +#define QCRYPTO_CRYPTODEV_BACKEND(obj) \
> > +    OBJECT_CHECK(QCryptoCryptoDevBackend, \
> > +                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> > +#define QCRYPTO_CRYPTODEV_BACKEND_GET_CLASS(obj) \
> > +    OBJECT_GET_CLASS(QCryptoCryptoDevBackendClass, \
> > +                 (obj), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> > +#define QCRYPTO_CRYPTODEV_BACKEND_CLASS(klass) \
> > +    OBJECT_CLASS_CHECK(QCryptoCryptoDevBackendClass, \
> > +                (klass), TYPE_QCRYPTO_CRYPTODEV_BACKEND)
> > +
> > +
> > +#define MAX_CRYPTO_QUEUE_NUM  64
> > +
> > +typedef struct QCryptoCryptoDevBackendConf
> QCryptoCryptoDevBackendConf;
> > +typedef struct QCryptoCryptoDevBackendPeers
> QCryptoCryptoDevBackendPeers;
> > +typedef struct QCryptoCryptoDevBackendClientState
> > +                     QCryptoCryptoDevBackendClientState;
> > +typedef struct QCryptoCryptoDevBackend QCryptoCryptoDevBackend;
> > +
> > +
> > +typedef struct QCryptoCryptoDevBackendClass {
> > +    ObjectClass parent_class;
> > +
> > +    void (*init)(QCryptoCryptoDevBackend *backend, Error **errp);
> > +    void (*cleanup)(QCryptoCryptoDevBackend *backend, Error **errp);
> > +} QCryptoCryptoDevBackendClass;
> > +
> > +
> > +struct QCryptoCryptoDevBackendClientState {
> 
> The naming could be simplified: CryptoDevClient.
> 
> > +    char *model;
> > +    char *name;
> > +    char info_str[128];
> 
> This should probably be char *info_str unless there is a specific reason
> to use a fixed-size buffer.
> 
OK.

> > +    unsigned int queue_index;
> > +    QTAILQ_ENTRY(QCryptoCryptoDevBackendClientState) next;
> > +};
> > +
> > +struct QCryptoCryptoDevBackendPeers {
> > +    QCryptoCryptoDevBackendClientState
> *ccs[MAX_CRYPTO_QUEUE_NUM];
> > +    uint32_t queues;
> > +};
> > +
> > +struct QCryptoCryptoDevBackendConf {
> > +    QCryptoCryptoDevBackendPeers 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 QCryptoCryptoDevBackend {
> > +    Object parent_obj;
> > +
> > +    int ready;
> 
> Please use bool.  That way it's clear the field only takes true and
> false values.
> 
OK.

> > +    QCryptoCryptoDevBackendConf conf;
> > +};
> > +
> > +/**
> > + * qcrypto_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 mode @mode.
> 
> s/mode/model/
> 
Yes.


Regards,
-Gonglei

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff
  2016-10-03 16:13   ` Stefan Hajnoczi
@ 2016-10-05  3:07     ` Gonglei (Arei)
  0 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:07 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Stefan Hajnoczi
> Sent: Tuesday, October 04, 2016 12:14 AM
> Subject: [virtio-dev] Re: [PATCH v4 02/13] cryptodev: add symmetric algorithm
> operation stuff
> 
> On Wed, Sep 28, 2016 at 04:25:41PM +0800, Gonglei wrote:
> > This patch add session operation and crypto operation
> 
> s/add/adds/
> 
> > stuff in the cryptodev backend, including function
> > pointers and correpsonding structures.
> 
> s/correpsonding/corresponding/
> 
> > +/**
> > + * QCryptoCryptoDevBackendSymOpInfo:
> > + *
> > + * @session_id: session index which was previously
> > + *              created by
> qcrypto_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, which is equal to
> > + *           src_len + hash_result_len if HASH alg configured
> > + * @op_type: operation type (refer to virtio_crypto.h)
> > + * @iv: pointer to the initialization vector or counter
> > + * @src: pointer to the source data
> > + * @dst: pointer to the destination data
> > + * @dst: pointer to the additional authenticated data
> 
> s/dst/aad_data/

OK, good catch, thanks!


Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
  2016-10-03 16:31   ` Stefan Hajnoczi
@ 2016-10-05  3:19     ` Gonglei (Arei)
  2016-10-05 12:53       ` Stefan Hajnoczi
  0 siblings, 1 reply; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:19 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> Sent: Tuesday, October 04, 2016 12:32 AM
> Subject: Re: [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
> 
> On Wed, Sep 28, 2016 at 04:25:43PM +0800, Gonglei wrote:
> > +/* Max number of symetrical sessions */
> 
> s/symetrical/symmetric/
> 
> But why does the comment say "symetrical" when the constant name
> MAX_NUM_SESSIONS seems to be a global limit for *all* sessions (not just
> symmetric)?
> 
> > +#define MAX_NUM_SESSIONS 256
> 
> The guest can only have 256 sessions open?
> 
For cipher API backend, it's a experimental cryptodev backend, which
can't be applied in production environment because of the poor performance. 
The limit is just for simplifying code logic, of course we can increase the number
as well, but it doesn't necessary IMO.

> What are the limits of real crypto libraries and accelerators?
> 
The hardware accelerators maybe have a limit, for example the
Intel QAT pmd driver in DPDK limit the maximum num of session is 2048.

> > +
> > +
> > +struct QCryptoCryptoDevBackendBuiltin {
> > +    QCryptoCryptoDevBackend parent_obj;
> > +
> > +    QCryptoCryptoDevBackendBuiltinSession
> *sessions[MAX_NUM_SESSIONS];
> > +};
> > +
> > +static void qcrypto_cryptodev_backend_builtin_init(
> > +             QCryptoCryptoDevBackend *backend, Error **errp)
> > +{
> > +    /* Only support one queue */
> > +    int queues = MAX(backend->conf.peers.queues, 1);
> > +    size_t i;
> > +    QCryptoCryptoDevBackendClientState *cc;
> > +
> > +    for (i = 0; i < queues; i++) {
> > +        cc = qcrypto_cryptodev_backend_new_client(
> > +                  "cryptodev-builtin", NULL);
> > +        snprintf(cc->info_str, sizeof(cc->info_str),
> > +                 "cryptodev-builtin%lu", i);
> > +        cc->queue_index = i;
> > +
> > +        backend->conf.peers.ccs[i] = 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
> > +qcrypto_cryptodev_backend_builtin_get_unused_session_index(
> > +      QCryptoCryptoDevBackendBuiltin *builtin)
> > +{
> > +    size_t i;
> > +
> > +    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
> > +        if (builtin->sessions[i] == NULL) {
> > +            return i;
> > +        }
> > +    }
> > +
> > +    return -1;
> > +}
> > +
> > +static int
> > +qcrypto_cryptodev_backend_builtin_get_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 qcrypto_cryptodev_backend_builtin_create_cipher_session(
> > +                    QCryptoCryptoDevBackendBuiltin *builtin,
> > +                    QCryptoCryptoDevBackendSymSessionInfo
> *sess_info,
> > +                    Error **errp)
> > +{
> > +    int algo;
> > +    int mode;
> > +    QCryptoCipher *cipher;
> > +    int index;
> > +    QCryptoCryptoDevBackendBuiltinSession *sess;
> > +
> > +    if (sess_info->op_type != VIRTIO_CRYPTO_SYM_OP_CIPHER) {
> > +        error_setg(errp, "unsupported optype :%u", sess_info->op_type);
> > +        return -1;
> > +    }
> > +
> > +    index =
> qcrypto_cryptodev_backend_builtin_get_unused_session_index(builtin);
> 
> Feel free to omit the function name prefix for static functions.  These
> names are very long.
> 
> > +    if (index < 0) {
> > +        error_setg(errp, "the total number of created session
> exceed %u",
> 
> "Total number of sessions created exceeds %u"
> 
> > +                  MAX_NUM_SESSIONS);
> > +        return -1;
> > +    }
> > +
> > +    switch (sess_info->cipher_alg) {
> > +    case VIRTIO_CRYPTO_CIPHER_AES_ECB:
> > +        algo =
> qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> > +
> errp);
> > +        if (algo < 0)  {
> > +            return -1;
> > +        }
> > +        mode = QCRYPTO_CIPHER_MODE_ECB;
> > +        break;
> > +    case VIRTIO_CRYPTO_CIPHER_AES_CBC:
> > +        algo =
> qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> > +
> errp);
> > +        if (algo < 0)  {
> > +            return -1;
> > +        }
> > +        mode = QCRYPTO_CIPHER_MODE_CBC;
> > +        break;
> > +    case VIRTIO_CRYPTO_CIPHER_AES_CTR:
> > +        algo =
> qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
> > +
> errp);
> > +        if (algo < 0)  {
> > +            return -1;
> > +        }
> > +        mode = QCRYPTO_CIPHER_MODE_CTR;
> > +        break;
> > +    default:
> > +        error_setg(errp, "unsupported cipher alg :%u",
> > +                   sess_info->cipher_alg);
> > +        return -1;
> > +    }
> 
> Code duplication can be eliminated:
> 
> switch (sess_info->cipher_alg) {
> case VIRTIO_CRYPTO_CIPHER_AES_ECB:
>     mode = QCRYPTO_CIPHER_MODE_ECB;
>     break;
> ...
> }
> 
> algo = qcrypto_cryptodev_backend_builtin_get_algo(sess_info->key_len,
>                                                   errp);
> if (algo < 0) {
>     return -1;
> }
> 
Make sense. :)

> > +static void qcrypto_cryptodev_backend_builtin_cleanup(
> > +             QCryptoCryptoDevBackend *backend,
> > +             Error **errp)
> > +{
> > +    QCryptoCryptoDevBackendBuiltin *builtin =
> > +
> QCRYPTO_CRYPTODEV_BACKEND_BUILTIN(backend);
> > +    size_t i;
> > +    int queues = backend->conf.peers.queues;
> > +    QCryptoCryptoDevBackendClientState *cc;
> > +
> > +    for (i = 0; i < MAX_NUM_SESSIONS; i++) {
> > +        if (builtin->sessions[i] != NULL) {
> > +            qcrypto_cryptodev_backend_builtin_sym_close_session(
> > +                    backend, i, 0, errp);
> > +        }
> > +    }
> > +
> > +    for (i = 0; i < queues; i++) {
> 
> This device doesn't seem to support queues because queue_index is
> ignored by all functions that take it.
> 
> Perhaps there should be an error if the device is realized with more
> than 1 queue?

Yes, we can add the check for cryptodev-builtin backend.


Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation
  2016-10-04  9:38   ` Stefan Hajnoczi
@ 2016-10-05  3:26     ` Gonglei (Arei)
  0 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:26 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)

> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> Sent: Tuesday, October 04, 2016 5:38 PM
> Subject: Re: [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation
> 
> On Wed, Sep 28, 2016 at 04:25:44PM +0800, Gonglei wrote:
> > 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
> 
> This patch contains functions and struct fields that are unused.  It
> would make code review easier if you add them when they are needed
> throughout the patch series.
> 
OK, will remove them.

> > +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 - 1);
> 
> The error message is off by 1:
> 
> must be a positive integer less than VIRTIO_QUEUE_MAX
> 
Yes.

> > +        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, virtio_crypto_handle_dataq);
> > +    }
> > +
> > +    vcrypto->ctrl_vq = virtio_add_queue(vdev, 64,
> virtio_crypto_handle_ctrl);
> > +    if (!vcrypto->cryptodev->ready) {
> > +        vcrypto->status &= ~VIRTIO_CRYPTO_S_HW_READY;
> > +    } else {
> > +        vcrypto->status |= VIRTIO_CRYPTO_S_HW_READY;
> > +    }
> > +    register_savevm(dev, "virtio-crypto", -1, 1, virtio_crypto_save,
> > +                    virtio_crypto_load, vcrypto);
> 
> Please use VMSTATE_VIRTIO_DEVICE() instead of calling register_savevm().
> 
OK.

> > +#ifdef DEBUG_VIRTIO_CRYPTO
> > +#define DPRINTF(fmt, ...) \
> > +do { printf("virtio_crypto: " fmt , ## __VA_ARGS__); } while (0)
> > +#else
> > +#define DPRINTF(fmt, ...) do { } while (0)
> > +#endif
> 
> Please use tracing (see docs/tracing.txt) or if you really want to use

I planned to polish tracing log in my TODO list. So, currently I'd like to use
DPRINTF().

> debug printfs then define DPRINTF() in a way that prevents bitrot:
> 
> #define DEBUG_VIRTIO_CRYPTO 0
> #define DPRINTF(fmt, ...) \
> do { \
>     if (DEBUG_VIRTIO_CRYPTO) { \
>         fprintf(stderr, "virtio_crypto: " fmt, ##__VA_ARGS__); \
>     } \
> } while (0)

Make sense.


Regards,
-Gonglei

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported
  2016-10-04  9:46   ` Stefan Hajnoczi
@ 2016-10-05  3:30     ` Gonglei (Arei)
  2016-10-05 12:55       ` Stefan Hajnoczi
  0 siblings, 1 reply; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:30 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Stefan Hajnoczi
> Sent: Tuesday, October 04, 2016 5:46 PM
> Subject: [virtio-dev] Re: [PATCH v4 07/13] virtio-crypto: set capacity of
> algorithms supported
> 
> On Wed, Sep 28, 2016 at 04:25:46PM +0800, Gonglei wrote:
> >  static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
> >  {
> > -
> > +    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);
> > +    struct virtio_crypto_config crypto_cfg;
> > +
> > +    crypto_cfg.status = c->status;
> > +    crypto_cfg.max_dataqueues = c->max_queues;
> > +    crypto_cfg.crypto_services = c->conf.crypto_services;
> > +    crypto_cfg.cipher_algo_l = c->conf.cipher_algo_l;
> > +    crypto_cfg.cipher_algo_h = c->conf.cipher_algo_h;
> > +    crypto_cfg.hash_algo = c->conf.hash_algo;
> > +    crypto_cfg.mac_algo_l = c->conf.mac_algo_l;
> > +    crypto_cfg.mac_algo_h = c->conf.mac_algo_h;
> > +    crypto_cfg.aead_algo = c->conf.aead_algo;
> > +
> > +    memcpy(config, &crypto_cfg, c->config_size);
> >  }
> 
> What about endianness?  For example, if the host is big-endian then this
> VIRTIO 1.0 device needs to byteswap multi-byte fields.  There is a
> family of functions to help with this: virtio_stl_p().

I did that in v1. Michael told me that Virtio-1.0 devices are always little-endian, so
I removed those helper functions in the following functions. But after this version,
the virtio-crypto device isn't virtio-1.0 device by default, so I should use them again.


Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler
  2016-10-04 10:09   ` Stefan Hajnoczi
@ 2016-10-05  3:38     ` Gonglei (Arei)
  0 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:38 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> Sent: Tuesday, October 04, 2016 6:09 PM
> Subject: Re: [PATCH v4 08/13] virtio-crypto: add control queue handler
> 
> On Wed, Sep 28, 2016 at 04:25:47PM +0800, Gonglei wrote:
> > -static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
> > +static inline int virtio_crypto_vq2q(int queue_index)
> > +{
> > +    return queue_index;
> > +}
> 
> Please document this function.  I think it takes a virtqueue index and
> returns the crypto queue.  The ctrl virtqueue is after the op virtqueues
> so the input value doesn't need to be adjusted.
> 
Yes, it makes very sense. Thanks.

> Without this information it's hard to understand the function.
> 
> > +
> > +static void
> > +virtio_crypto_cipher_session_helper(VirtIODevice *vdev,
> > +           QCryptoCryptoDevBackendSymSessionInfo *info,
> > +           struct virtio_crypto_cipher_session_para *cipher_para,
> > +           struct virtio_crypto_cipher_session_output *cipher_out)
> > +{
> > +    hwaddr key_gpa;
> > +    void *key_hva;
> > +    hwaddr len;
> > +
> > +    info->cipher_alg = cipher_para->algo;
> > +    info->key_len = cipher_para->keylen;
> > +    info->direction = cipher_para->op;
> 
> Endianness?  Use the virtio_ldl_p() family of functions to load values
> from the guest.
> 
> This same issue is present in the rest of the code.  I won't mentioned
> it again but please fix all occurrences.
> 
Will fix them.

> > +    len = info->key_len;
> > +    /* get cipher key */
> > +    if (len > 0) {
> > +        DPRINTF("keylen=%" PRIu32 "\n", info->key_len);
> > +        key_gpa = cipher_out->key_addr;
> > +
> > +        key_hva = cpu_physical_memory_map(key_gpa, &len, 0);
> 
> virtio devices should not use cpu_physical_memory_map().  Please see my
> reply to the virtio-crypto specification about scatter-gather I/O.
> 
OK.

> > +static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
> > +{
> > +    VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev);
> > +    struct virtio_crypto_op_ctrl_req ctrl;
> > +    VirtQueueElement *elem;
> > +    size_t s;
> > +    struct iovec *iov;
> > +    unsigned int iov_cnt;
> > +    uint32_t queue_id;
> > +    uint32_t opcode;
> > +
> > +    for (;;) {
> > +        elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
> > +        if (!elem) {
> > +            break;
> > +        }
> > +        if (elem->in_num < 1 ||
> > +            iov_size(elem->in_sg, elem->in_num) < sizeof(ctrl)) {
> > +            error_report("virtio-crypto ctrl missing headers");
> > +            exit(1);
> > +        }
> 
> Please use virtio_error() instead.  virtio devices should not call
> exit(1).  There are other instances of this throughout the code, please
> fix all of them.
> 
I noticed your patch set introduced virtio_error(), and it seems that merged
a few days ago. 

I'll fix them.

> > +
> > +        iov_cnt = elem->in_num;
> > +        iov = elem->in_sg;
> > +        s = iov_to_buf(iov, iov_cnt, 0, &ctrl, sizeof(ctrl));
> > +        assert(s == sizeof(ctrl));
> 
> This assert is always true because you checked iov_size() above.  Please
> move that check down here and drop the assert.

OK.

Regards,
-Gonglei

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation
  2016-10-04 10:13 ` Stefan Hajnoczi
@ 2016-10-05  3:42   ` Gonglei (Arei)
  0 siblings, 0 replies; 35+ messages in thread
From: Gonglei (Arei) @ 2016-10-05  3:42 UTC (permalink / raw)
  To: Stefan Hajnoczi
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)


> -----Original Message-----
> From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> On Behalf Of Stefan Hajnoczi
> Sent: Tuesday, October 04, 2016 6:13 PM
> Subject: [virtio-dev] Re: [PATCH v4 00/13] virtio-crypto: introduce framework
> and device emulation
> 
> On Wed, Sep 28, 2016 at 04:25:39PM +0800, Gonglei wrote:
> > 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.
> 
> Please look at my reply to the virtio-crypto spec email thread.  Changes
> to the request layout are necessary (dropping custom scatter-gather I/O,
> avoiding assumptions about iovec layout, ordering of
> device-readable/writable buffers).
> 
> This will change the code quite a bit so I won't review further for now.
> 
> Stefan

OK, thank you very much for your comments, Stefan.
I'll fix the spec and corresponding code ASAP.

Regards,
-Gonglei

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

* Re: [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
  2016-10-05  3:19     ` Gonglei (Arei)
@ 2016-10-05 12:53       ` Stefan Hajnoczi
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-05 12:53 UTC (permalink / raw)
  To: Gonglei (Arei)
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)

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

On Wed, Oct 05, 2016 at 03:19:44AM +0000, Gonglei (Arei) wrote:
> > -----Original Message-----
> > From: Stefan Hajnoczi [mailto:stefanha@redhat.com]
> > Sent: Tuesday, October 04, 2016 12:32 AM
> > Subject: Re: [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend
> > 
> > On Wed, Sep 28, 2016 at 04:25:43PM +0800, Gonglei wrote:
> > > +/* Max number of symetrical sessions */
> > 
> > s/symetrical/symmetric/
> > 
> > But why does the comment say "symetrical" when the constant name
> > MAX_NUM_SESSIONS seems to be a global limit for *all* sessions (not just
> > symmetric)?
> > 
> > > +#define MAX_NUM_SESSIONS 256
> > 
> > The guest can only have 256 sessions open?
> > 
> For cipher API backend, it's a experimental cryptodev backend, which
> can't be applied in production environment because of the poor performance. 
> The limit is just for simplifying code logic, of course we can increase the number
> as well, but it doesn't necessary IMO.
> 
> > What are the limits of real crypto libraries and accelerators?
> > 
> The hardware accelerators maybe have a limit, for example the
> Intel QAT pmd driver in DPDK limit the maximum num of session is 2048.

How do we prevent competing guests from creating idle sessions ahead of
time in order to "reserve" them?

Greedy guests could prevent other guests from creating sessions if the
hardware limit is 2048.

Perhaps the max sessions limit should be a user parameter so the host
administrator use it to guarantee session availability.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

* Re: [Qemu-devel] [virtio-dev] Re: [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported
  2016-10-05  3:30     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
@ 2016-10-05 12:55       ` Stefan Hajnoczi
  0 siblings, 0 replies; 35+ messages in thread
From: Stefan Hajnoczi @ 2016-10-05 12:55 UTC (permalink / raw)
  To: Gonglei (Arei)
  Cc: qemu-devel, virtio-dev, Luonengjun, mst, pbonzini, berrange,
	Huangweidong (C), Wubin (H),
	mike.caraman, agraf, xin.zeng, Claudio Fontana, nmorey,
	vincent.jardin, Zhoujian (jay, Euler), Hanweidong (Randy),
	Huangpeng (Peter)

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

On Wed, Oct 05, 2016 at 03:30:42AM +0000, Gonglei (Arei) wrote:
> 
> > -----Original Message-----
> > From: virtio-dev@lists.oasis-open.org [mailto:virtio-dev@lists.oasis-open.org]
> > On Behalf Of Stefan Hajnoczi
> > Sent: Tuesday, October 04, 2016 5:46 PM
> > Subject: [virtio-dev] Re: [PATCH v4 07/13] virtio-crypto: set capacity of
> > algorithms supported
> > 
> > On Wed, Sep 28, 2016 at 04:25:46PM +0800, Gonglei wrote:
> > >  static void virtio_crypto_get_config(VirtIODevice *vdev, uint8_t *config)
> > >  {
> > > -
> > > +    VirtIOCrypto *c = VIRTIO_CRYPTO(vdev);
> > > +    struct virtio_crypto_config crypto_cfg;
> > > +
> > > +    crypto_cfg.status = c->status;
> > > +    crypto_cfg.max_dataqueues = c->max_queues;
> > > +    crypto_cfg.crypto_services = c->conf.crypto_services;
> > > +    crypto_cfg.cipher_algo_l = c->conf.cipher_algo_l;
> > > +    crypto_cfg.cipher_algo_h = c->conf.cipher_algo_h;
> > > +    crypto_cfg.hash_algo = c->conf.hash_algo;
> > > +    crypto_cfg.mac_algo_l = c->conf.mac_algo_l;
> > > +    crypto_cfg.mac_algo_h = c->conf.mac_algo_h;
> > > +    crypto_cfg.aead_algo = c->conf.aead_algo;
> > > +
> > > +    memcpy(config, &crypto_cfg, c->config_size);
> > >  }
> > 
> > What about endianness?  For example, if the host is big-endian then this
> > VIRTIO 1.0 device needs to byteswap multi-byte fields.  There is a
> > family of functions to help with this: virtio_stl_p().
> 
> I did that in v1. Michael told me that Virtio-1.0 devices are always little-endian, so
> I removed those helper functions in the following functions. But after this version,
> the virtio-crypto device isn't virtio-1.0 device by default, so I should use them again.

Endian awareness is still necessary for VIRTIO 1.0-only devices.  The
uint8_t *config data is just a blob.  Therefore nothing automatically
handles little-endian conversion for us.  We *must* read little-endian
from config[].

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]

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

end of thread, other threads:[~2016-10-05 12:55 UTC | newest]

Thread overview: 35+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-28  8:25 [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 01/13] cryptodev: introduce cryptodev backend interface Gonglei
2016-10-03 16:10   ` Stefan Hajnoczi
2016-10-03 16:15     ` Daniel P. Berrange
2016-10-05  3:06     ` Gonglei (Arei)
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 02/13] cryptodev: add symmetric algorithm operation stuff Gonglei
2016-10-03 16:13   ` Stefan Hajnoczi
2016-10-05  3:07     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 03/13] virtio-crypto: introduce virtio_crypto.h Gonglei
2016-10-03 16:14   ` Stefan Hajnoczi
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 04/13] cryptodev: introduce a new cryptodev backend Gonglei
2016-10-03 16:31   ` Stefan Hajnoczi
2016-10-05  3:19     ` Gonglei (Arei)
2016-10-05 12:53       ` Stefan Hajnoczi
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 05/13] virtio-crypto: add virtio crypto device emulation Gonglei
2016-10-04  9:38   ` Stefan Hajnoczi
2016-10-05  3:26     ` Gonglei (Arei)
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 06/13] virtio-crypto-pci: add virtio crypto pci support Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 07/13] virtio-crypto: set capacity of algorithms supported Gonglei
2016-10-04  9:46   ` Stefan Hajnoczi
2016-10-05  3:30     ` [Qemu-devel] [virtio-dev] " Gonglei (Arei)
2016-10-05 12:55       ` Stefan Hajnoczi
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 08/13] virtio-crypto: add control queue handler Gonglei
2016-10-04 10:09   ` Stefan Hajnoczi
2016-10-05  3:38     ` Gonglei (Arei)
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 09/13] virtio-crypto: add data queue processing handler Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 10/13] cryptodev: introduce an unified wrapper for crypto operation Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 11/13] virtio-crypto: emulate virtio crypto as a legacy device by default Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 12/13] virtio-crypto-test: add qtest case for virtio-crypto Gonglei
2016-09-28  8:25 ` [Qemu-devel] [PATCH v4 13/13] virtio-crypto: add myself as virtio-crypto and cryptodev backends maintainer Gonglei
2016-09-28  9:14 ` [Qemu-devel] [PATCH v4 00/13] virtio-crypto: introduce framework and device emulation no-reply
2016-09-28  9:18   ` Gonglei (Arei)
2016-10-03 12:02 ` Gonglei (Arei)
2016-10-04 10:13 ` Stefan Hajnoczi
2016-10-05  3:42   ` [Qemu-devel] [virtio-dev] " 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.