From patchwork Mon May 8 11:38:21 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Gonglei (Arei)" X-Patchwork-Id: 9716077 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 33FC060234 for ; Mon, 8 May 2017 11:42:35 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 22F821FF27 for ; Mon, 8 May 2017 11:42:35 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 1627F201BC; Mon, 8 May 2017 11:42:35 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id EA1A0200E9 for ; Mon, 8 May 2017 11:42:33 +0000 (UTC) Received: from localhost ([::1]:58923 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d7h3h-0004mm-8i for patchwork-qemu-devel@patchwork.kernel.org; Mon, 08 May 2017 07:42:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50686) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1d7h0T-0002xA-Fh for qemu-devel@nongnu.org; Mon, 08 May 2017 07:39:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1d7h0O-0004Uj-Pr for qemu-devel@nongnu.org; Mon, 08 May 2017 07:39:13 -0400 Received: from szxga01-in.huawei.com ([45.249.212.187]:3975) by eggs.gnu.org with esmtps (TLS1.0:RSA_ARCFOUR_SHA1:16) (Exim 4.71) (envelope-from ) id 1d7h0N-0004Sy-W0 for qemu-devel@nongnu.org; Mon, 08 May 2017 07:39:08 -0400 Received: from 172.30.72.53 (EHLO DGGEML402-HUB.china.huawei.com) ([172.30.72.53]) by dggrg01-dlp.huawei.com (MOS 4.4.6-GA FastPath queued) with ESMTP id AOD07411; Mon, 08 May 2017 19:38:49 +0800 (CST) Received: from localhost (10.177.18.62) by DGGEML402-HUB.china.huawei.com (10.3.17.38) with Microsoft SMTP Server id 14.3.301.0; Mon, 8 May 2017 19:38:37 +0800 From: Gonglei To: Date: Mon, 8 May 2017 19:38:21 +0800 Message-ID: <1494243504-127980-7-git-send-email-arei.gonglei@huawei.com> X-Mailer: git-send-email 2.8.2.windows.1 In-Reply-To: <1494243504-127980-1-git-send-email-arei.gonglei@huawei.com> References: <1494243504-127980-1-git-send-email-arei.gonglei@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.177.18.62] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090201.591058CB.0049, ss=1, re=0.000, recu=0.000, reip=0.000, cl=1, cld=1, fgs=0, ip=0.0.0.0, so=2014-11-16 11:51:01, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 1fdab46b78938e3e3d3354b9c4ae4013 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.4.x-2.6.x [generic] [fuzzy] X-Received-From: 45.249.212.187 Subject: [Qemu-devel] [RFC v1 6/9] virtio-crypto: rework virtio_crypto_handle_request X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: pasic@linux.vnet.ibm.com, weidong.huang@huawei.com, mst@redhat.com, xin.zeng@intel.com, luonengjun@huawei.com, linqiangmin@huawei.com, Gonglei , stefanha@redhat.com, cornelia.huck@de.ibm.com, wu.wubin@huawei.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP According to the new spec, we should use different requst structure to store the data request based on whether VIRTIO_CRYPTO_F_MUX_MODE feature bit is negotiated or not. In this patch, we havn't supported stateless mode yet. The device reportes an error if both VIRTIO_CRYPTO_F_MUX_MODE and VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE are negotiated, meanwhile the header.flag doesn't set to VIRTIO_CRYPTO_FLAG_SESSION_MODE. Let's handle this scenario in the following patches. Signed-off-by: Gonglei --- hw/virtio/virtio-crypto.c | 83 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 71 insertions(+), 12 deletions(-) diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 0353eb6..c4b8a2c 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -577,6 +577,7 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) VirtQueueElement *elem = &request->elem; int queue_index = virtio_crypto_vq2q(virtio_get_queue_index(request->vq)); struct virtio_crypto_op_data_req req; + struct virtio_crypto_op_data_req_mux req_mux; int ret; struct iovec *in_iov; struct iovec *out_iov; @@ -587,6 +588,9 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) uint64_t session_id; CryptoDevBackendSymOpInfo *sym_op_info = NULL; Error *local_err = NULL; + bool mux_mode_is_negotiated; + struct virtio_crypto_op_header *header; + bool is_stateless_req = false; if (elem->out_num < 1 || elem->in_num < 1) { virtio_error(vdev, "virtio-crypto dataq missing headers"); @@ -597,12 +601,28 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) out_iov = elem->out_sg; in_num = elem->in_num; in_iov = elem->in_sg; - if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req)) - != sizeof(req))) { - virtio_error(vdev, "virtio-crypto request outhdr too short"); - return -1; + + mux_mode_is_negotiated = + virtio_vdev_has_feature(vdev, VIRTIO_CRYPTO_F_MUX_MODE); + if (!mux_mode_is_negotiated) { + if (unlikely(iov_to_buf(out_iov, out_num, 0, &req, sizeof(req)) + != sizeof(req))) { + virtio_error(vdev, "virtio-crypto request outhdr too short"); + return -1; + } + iov_discard_front(&out_iov, &out_num, sizeof(req)); + + header = &req.header; + } else { + if (unlikely(iov_to_buf(out_iov, out_num, 0, &req_mux, + sizeof(req_mux)) != sizeof(req_mux))) { + virtio_error(vdev, "virtio-crypto request outhdr too short"); + return -1; + } + iov_discard_front(&out_iov, &out_num, sizeof(req_mux)); + + header = &req_mux.header; } - iov_discard_front(&out_iov, &out_num, sizeof(req)); if (in_iov[in_num - 1].iov_len < sizeof(struct virtio_crypto_inhdr)) { @@ -623,16 +643,51 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) request->in_num = in_num; request->in_iov = in_iov; - opcode = ldl_le_p(&req.header.opcode); - session_id = ldq_le_p(&req.header.session_id); + opcode = ldl_le_p(&header->opcode); switch (opcode) { case VIRTIO_CRYPTO_CIPHER_ENCRYPT: case VIRTIO_CRYPTO_CIPHER_DECRYPT: - ret = virtio_crypto_handle_sym_req(vcrypto, + if (!mux_mode_is_negotiated) { + ret = virtio_crypto_handle_sym_req(vcrypto, &req.u.sym_req, &sym_op_info, out_iov, out_num); + } else { + if (!virtio_vdev_has_feature(vdev, + VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE)) { + /* + * If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is not + * negotiated, the driver MUST use the session mode + */ + ret = virtio_crypto_handle_sym_req(vcrypto, + &req_mux.u.sym_req.data, + &sym_op_info, + out_iov, out_num); + } else { + /* + * If the VIRTIO_CRYPTO_F_CIPHER_STATELESS_MODE is + * negotiated, the device MUST parse header.flag + * in order to decide which mode the driver uses. + */ + if (header->flag == VIRTIO_CRYPTO_FLAG_SESSION_MODE) { + ret = virtio_crypto_handle_sym_req(vcrypto, + &req_mux.u.sym_req.data, + &sym_op_info, + out_iov, out_num); + } else { + is_stateless_req = true; + /* + * Handle stateless mode, that is + * header->flag == VIRTIO_CRYPTO_FLAG_STATELESS_MODE + */ + virtio_error(vdev, + "virtio-crypto do not support stateless mode"); + return -1; + } + } + } + /* Serious errors, need to reset virtio crypto device */ if (ret == -EFAULT) { return -1; @@ -640,11 +695,15 @@ virtio_crypto_handle_request(VirtIOCryptoReq *request) virtio_crypto_req_complete(request, VIRTIO_CRYPTO_NOTSUPP); virtio_crypto_free_request(request); } else { - sym_op_info->session_id = session_id; + if (!is_stateless_req) { + sym_op_info->op_code = opcode; + session_id = ldq_le_p(&header->session_id); + sym_op_info->session_id = session_id; + /* Set request's parameter */ + request->flags = CRYPTODEV_BACKEND_ALG_SYM; + request->u.sym_op_info = sym_op_info; + } - /* Set request's parameter */ - request->flags = CRYPTODEV_BACKEND_ALG_SYM; - request->u.sym_op_info = sym_op_info; ret = cryptodev_backend_crypto_operation(vcrypto->cryptodev, request, queue_index, &local_err); if (ret < 0) {