diff mbox

[v1,13/14] virtio-crypto: get correct input data address for each request

Message ID 1473306156-176628-14-git-send-email-arei.gonglei@huawei.com (mailing list archive)
State New, archived
Headers show

Commit Message

Gonglei (Arei) Sept. 8, 2016, 3:42 a.m. UTC
We MUST use the original hva for input data, but not the
copyed address, otherwise the guest can't get the results.
Fix a non-initial problem in an exception case as well.

Signed-off-by: Gonglei <arei.gonglei@huawei.com>
---
 hw/virtio/virtio-crypto.c | 40 +++++++++++++++++++++++++++++++++-------
 1 file changed, 33 insertions(+), 7 deletions(-)
diff mbox

Patch

diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c
index 0888725..55ce330 100644
--- a/hw/virtio/virtio-crypto.c
+++ b/hw/virtio/virtio-crypto.c
@@ -62,7 +62,8 @@  static int64_t
 virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
                struct virtio_crypto_sym_create_session_req *sess_req,
                uint32_t queue_id,
-               uint64_t *session_id)
+               uint64_t *session_id,
+               VirtQueueElement *elem)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
     CryptoSymSessionInfo info;
@@ -74,6 +75,8 @@  virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
     void *auth_key_hva;
     struct virtio_crypto_session_input *input;
     hwaddr len;
+    size_t input_offset;
+    struct iovec *iov = elem->in_sg;
 
     op_type = virtio_ldl_p(vdev, &sess_req->op_type);
     info.op_type = op_type;
@@ -82,13 +85,20 @@  virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
         virtio_crypto_cipher_session_helper(vdev, &info,
                            &sess_req->u.cipher.para,
                            &sess_req->u.cipher.out);
-        input = &sess_req->u.cipher.input;
+        /* 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);
-        input = &sess_req->u.chain.input;
+        /* 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 = virtio_ldl_p(vdev,
                                &sess_req->u.chain.para.alg_chain_order);
@@ -124,6 +134,10 @@  virtio_crypto_create_sym_session(VirtIOCrypto *vcrypto,
             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;
@@ -148,7 +162,8 @@  err:
 static void
 virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
          struct virtio_crypto_destroy_session_req *close_sess_req,
-         uint32_t queue_id)
+         uint32_t queue_id,
+         VirtQueueElement *elem)
 {
     VirtIODevice *vdev = VIRTIO_DEVICE(vcrypto);
     int ret;
@@ -156,6 +171,9 @@  virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
     uint64_t session_id;
     uint32_t status;
     int queue_index = virtio_crypto_vq2q(queue_id);
+    struct iovec *iov = elem->in_sg;
+    size_t status_offset;
+    void *in_status_ptr;
 
     session_id = virtio_ldq_p(vdev, &close_sess_req->session_id);
     DPRINTF("close session, id=%" PRIu64 "\n", session_id);
@@ -168,8 +186,13 @@  virtio_crypto_handle_close_session(VirtIOCrypto *vcrypto,
         status = VIRTIO_CRYPTO_OP_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 */
-    virtio_stl_p(vdev, &close_sess_req->status, status);
+    virtio_stl_p(vdev, in_status_ptr, status);
 }
 
 static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
@@ -197,6 +220,7 @@  static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
 
         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 = virtio_ldl_p(vdev, &ctrl.header.opcode);
@@ -207,7 +231,8 @@  static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
             virtio_crypto_create_sym_session(vcrypto,
                              &ctrl.u.sym_create_session,
                              queue_id,
-                             &session_id);
+                             &session_id,
+                             elem);
 
             break;
         case VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION:
@@ -215,7 +240,8 @@  static void virtio_crypto_handle_ctrl(VirtIODevice *vdev, VirtQueue *vq)
         case VIRTIO_CRYPTO_MAC_DESTROY_SESSION:
         case VIRTIO_CRYPTO_AEAD_DESTROY_SESSION:
             virtio_crypto_handle_close_session(vcrypto,
-                   &ctrl.u.destroy_session, queue_id);
+                   &ctrl.u.destroy_session, queue_id,
+                   elem);
             break;
         case VIRTIO_CRYPTO_HASH_CREATE_SESSION:
         case VIRTIO_CRYPTO_MAC_CREATE_SESSION: