Message ID | 20220424104140.44841-3-pizhenwei@bytedance.com |
---|---|
State | Superseded |
Headers | show |
Series | virtio-crypto: Improve performance | expand |
Hi zhenwei, url: https://github.com/intel-lab-lkp/linux/commits/zhenwei-pi/virtio-crypto-Improve-performance/20220424-184732 base: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git master config: i386-randconfig-m021 (https://download.01.org/0day-ci/archive/20220424/202204242344.JepUMdzP-lkp@intel.com/config) compiler: gcc-11 (Debian 11.2.0-20) 11.2.0 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> Reported-by: Dan Carpenter <dan.carpenter@oracle.com> smatch warnings: drivers/crypto/virtio/virtio_crypto_akcipher_algs.c:165 virtio_crypto_alg_akcipher_init_session() error: potentially dereferencing uninitialized 'input'. drivers/crypto/virtio/virtio_crypto_akcipher_algs.c:230 virtio_crypto_alg_akcipher_close_session() error: uninitialized symbol 'vc_ctrl_req'. drivers/crypto/virtio/virtio_crypto_akcipher_algs.c:232 virtio_crypto_alg_akcipher_close_session() error: potentially dereferencing uninitialized 'ctrl_status'. drivers/crypto/virtio/virtio_crypto_akcipher_algs.c:232 virtio_crypto_alg_akcipher_close_session() error: potentially dereferencing uninitialized 'destroy_session'. vim +/input +165 drivers/crypto/virtio/virtio_crypto_akcipher_algs.c 59ca6c93387d32 zhenwei pi 2022-03-02 99 static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher_ctx *ctx, 59ca6c93387d32 zhenwei pi 2022-03-02 100 struct virtio_crypto_ctrl_header *header, void *para, 59ca6c93387d32 zhenwei pi 2022-03-02 101 const uint8_t *key, unsigned int keylen) 59ca6c93387d32 zhenwei pi 2022-03-02 102 { 59ca6c93387d32 zhenwei pi 2022-03-02 103 struct scatterlist outhdr_sg, key_sg, inhdr_sg, *sgs[3]; 59ca6c93387d32 zhenwei pi 2022-03-02 104 struct virtio_crypto *vcrypto = ctx->vcrypto; 59ca6c93387d32 zhenwei pi 2022-03-02 105 uint8_t *pkey; 59ca6c93387d32 zhenwei pi 2022-03-02 106 unsigned int inlen; 59ca6c93387d32 zhenwei pi 2022-03-02 107 int err; 59ca6c93387d32 zhenwei pi 2022-03-02 108 unsigned int num_out = 0, num_in = 0; bb26cab9a7c25d zhenwei pi 2022-04-24 109 struct virtio_crypto_op_ctrl_req *ctrl; bb26cab9a7c25d zhenwei pi 2022-04-24 110 struct virtio_crypto_session_input *input; 286da9ed04239c zhenwei pi 2022-04-24 111 struct virtio_crypto_ctrl_request *vc_ctrl_req; 59ca6c93387d32 zhenwei pi 2022-03-02 112 59ca6c93387d32 zhenwei pi 2022-03-02 113 pkey = kmemdup(key, keylen, GFP_ATOMIC); 59ca6c93387d32 zhenwei pi 2022-03-02 114 if (!pkey) 59ca6c93387d32 zhenwei pi 2022-03-02 115 return -ENOMEM; 59ca6c93387d32 zhenwei pi 2022-03-02 116 286da9ed04239c zhenwei pi 2022-04-24 117 vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); 286da9ed04239c zhenwei pi 2022-04-24 118 if (!vc_ctrl_req) { 286da9ed04239c zhenwei pi 2022-04-24 119 err = -ENOMEM; 286da9ed04239c zhenwei pi 2022-04-24 120 goto out; 286da9ed04239c zhenwei pi 2022-04-24 121 } 286da9ed04239c zhenwei pi 2022-04-24 122 286da9ed04239c zhenwei pi 2022-04-24 123 ctrl = &vc_ctrl_req->ctrl; bb26cab9a7c25d zhenwei pi 2022-04-24 124 memcpy(&ctrl->header, header, sizeof(ctrl->header)); bb26cab9a7c25d zhenwei pi 2022-04-24 125 memcpy(&ctrl->u, para, sizeof(ctrl->u)); 286da9ed04239c zhenwei pi 2022-04-24 126 input = &vc_ctrl_req->input; bb26cab9a7c25d zhenwei pi 2022-04-24 127 input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR); 59ca6c93387d32 zhenwei pi 2022-03-02 128 bb26cab9a7c25d zhenwei pi 2022-04-24 129 sg_init_one(&outhdr_sg, ctrl, sizeof(*ctrl)); 59ca6c93387d32 zhenwei pi 2022-03-02 130 sgs[num_out++] = &outhdr_sg; 59ca6c93387d32 zhenwei pi 2022-03-02 131 59ca6c93387d32 zhenwei pi 2022-03-02 132 sg_init_one(&key_sg, pkey, keylen); 59ca6c93387d32 zhenwei pi 2022-03-02 133 sgs[num_out++] = &key_sg; 59ca6c93387d32 zhenwei pi 2022-03-02 134 bb26cab9a7c25d zhenwei pi 2022-04-24 135 sg_init_one(&inhdr_sg, input, sizeof(*input)); 59ca6c93387d32 zhenwei pi 2022-03-02 136 sgs[num_out + num_in++] = &inhdr_sg; 59ca6c93387d32 zhenwei pi 2022-03-02 137 286da9ed04239c zhenwei pi 2022-04-24 138 spin_lock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 139 err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); 286da9ed04239c zhenwei pi 2022-04-24 140 if (err < 0) { 286da9ed04239c zhenwei pi 2022-04-24 141 spin_unlock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 142 goto out; 286da9ed04239c zhenwei pi 2022-04-24 143 } 59ca6c93387d32 zhenwei pi 2022-03-02 144 59ca6c93387d32 zhenwei pi 2022-03-02 145 virtqueue_kick(vcrypto->ctrl_vq); 59ca6c93387d32 zhenwei pi 2022-03-02 146 while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && 59ca6c93387d32 zhenwei pi 2022-03-02 147 !virtqueue_is_broken(vcrypto->ctrl_vq)) 59ca6c93387d32 zhenwei pi 2022-03-02 148 cpu_relax(); 286da9ed04239c zhenwei pi 2022-04-24 149 spin_unlock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 150 bb26cab9a7c25d zhenwei pi 2022-04-24 151 if (le32_to_cpu(input->status) != VIRTIO_CRYPTO_OK) { 59ca6c93387d32 zhenwei pi 2022-03-02 152 err = -EINVAL; 59ca6c93387d32 zhenwei pi 2022-03-02 153 goto out; 59ca6c93387d32 zhenwei pi 2022-03-02 154 } 59ca6c93387d32 zhenwei pi 2022-03-02 155 bb26cab9a7c25d zhenwei pi 2022-04-24 156 ctx->session_id = le64_to_cpu(input->session_id); 59ca6c93387d32 zhenwei pi 2022-03-02 157 ctx->session_valid = true; 59ca6c93387d32 zhenwei pi 2022-03-02 158 err = 0; 59ca6c93387d32 zhenwei pi 2022-03-02 159 59ca6c93387d32 zhenwei pi 2022-03-02 160 out: 286da9ed04239c zhenwei pi 2022-04-24 161 kfree(vc_ctrl_req); 59ca6c93387d32 zhenwei pi 2022-03-02 162 kfree_sensitive(pkey); 59ca6c93387d32 zhenwei pi 2022-03-02 163 59ca6c93387d32 zhenwei pi 2022-03-02 164 if (err < 0) 59ca6c93387d32 zhenwei pi 2022-03-02 @165 pr_err("virtio_crypto: Create session failed status: %u\n", bb26cab9a7c25d zhenwei pi 2022-04-24 166 le32_to_cpu(input->status)); goto out is always suspicious. "input" is not initialized. 59ca6c93387d32 zhenwei pi 2022-03-02 167 59ca6c93387d32 zhenwei pi 2022-03-02 168 return err; 59ca6c93387d32 zhenwei pi 2022-03-02 169 } 59ca6c93387d32 zhenwei pi 2022-03-02 170 59ca6c93387d32 zhenwei pi 2022-03-02 171 static int virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akcipher_ctx *ctx) 59ca6c93387d32 zhenwei pi 2022-03-02 172 { 59ca6c93387d32 zhenwei pi 2022-03-02 173 struct scatterlist outhdr_sg, inhdr_sg, *sgs[2]; 59ca6c93387d32 zhenwei pi 2022-03-02 174 struct virtio_crypto_destroy_session_req *destroy_session; 59ca6c93387d32 zhenwei pi 2022-03-02 175 struct virtio_crypto *vcrypto = ctx->vcrypto; 59ca6c93387d32 zhenwei pi 2022-03-02 176 unsigned int num_out = 0, num_in = 0, inlen; 59ca6c93387d32 zhenwei pi 2022-03-02 177 int err; bb26cab9a7c25d zhenwei pi 2022-04-24 178 struct virtio_crypto_op_ctrl_req *ctrl; bb26cab9a7c25d zhenwei pi 2022-04-24 179 struct virtio_crypto_inhdr *ctrl_status; 286da9ed04239c zhenwei pi 2022-04-24 180 struct virtio_crypto_ctrl_request *vc_ctrl_req; 59ca6c93387d32 zhenwei pi 2022-03-02 181 59ca6c93387d32 zhenwei pi 2022-03-02 182 if (!ctx->session_valid) { 59ca6c93387d32 zhenwei pi 2022-03-02 183 err = 0; 59ca6c93387d32 zhenwei pi 2022-03-02 184 goto out; 59ca6c93387d32 zhenwei pi 2022-03-02 185 } 286da9ed04239c zhenwei pi 2022-04-24 186 286da9ed04239c zhenwei pi 2022-04-24 187 vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); 286da9ed04239c zhenwei pi 2022-04-24 188 if (!vc_ctrl_req) { 286da9ed04239c zhenwei pi 2022-04-24 189 err = -ENOMEM; 286da9ed04239c zhenwei pi 2022-04-24 190 goto out; 286da9ed04239c zhenwei pi 2022-04-24 191 } 286da9ed04239c zhenwei pi 2022-04-24 192 286da9ed04239c zhenwei pi 2022-04-24 193 ctrl_status = &vc_ctrl_req->ctrl_status; bb26cab9a7c25d zhenwei pi 2022-04-24 194 ctrl_status->status = VIRTIO_CRYPTO_ERR; 286da9ed04239c zhenwei pi 2022-04-24 195 ctrl = &vc_ctrl_req->ctrl; bb26cab9a7c25d zhenwei pi 2022-04-24 196 ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION); bb26cab9a7c25d zhenwei pi 2022-04-24 197 ctrl->header.queue_id = 0; 59ca6c93387d32 zhenwei pi 2022-03-02 198 bb26cab9a7c25d zhenwei pi 2022-04-24 199 destroy_session = &ctrl->u.destroy_session; 59ca6c93387d32 zhenwei pi 2022-03-02 200 destroy_session->session_id = cpu_to_le64(ctx->session_id); 59ca6c93387d32 zhenwei pi 2022-03-02 201 bb26cab9a7c25d zhenwei pi 2022-04-24 202 sg_init_one(&outhdr_sg, ctrl, sizeof(*ctrl)); 59ca6c93387d32 zhenwei pi 2022-03-02 203 sgs[num_out++] = &outhdr_sg; 59ca6c93387d32 zhenwei pi 2022-03-02 204 bb26cab9a7c25d zhenwei pi 2022-04-24 205 sg_init_one(&inhdr_sg, &ctrl_status->status, sizeof(ctrl_status->status)); 59ca6c93387d32 zhenwei pi 2022-03-02 206 sgs[num_out + num_in++] = &inhdr_sg; 59ca6c93387d32 zhenwei pi 2022-03-02 207 286da9ed04239c zhenwei pi 2022-04-24 208 spin_lock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 209 err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); 286da9ed04239c zhenwei pi 2022-04-24 210 if (err < 0) { 286da9ed04239c zhenwei pi 2022-04-24 211 spin_unlock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 212 goto out; 286da9ed04239c zhenwei pi 2022-04-24 213 } 59ca6c93387d32 zhenwei pi 2022-03-02 214 59ca6c93387d32 zhenwei pi 2022-03-02 215 virtqueue_kick(vcrypto->ctrl_vq); 59ca6c93387d32 zhenwei pi 2022-03-02 216 while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && 59ca6c93387d32 zhenwei pi 2022-03-02 217 !virtqueue_is_broken(vcrypto->ctrl_vq)) 59ca6c93387d32 zhenwei pi 2022-03-02 218 cpu_relax(); 286da9ed04239c zhenwei pi 2022-04-24 219 spin_unlock(&vcrypto->ctrl_lock); 59ca6c93387d32 zhenwei pi 2022-03-02 220 bb26cab9a7c25d zhenwei pi 2022-04-24 221 if (ctrl_status->status != VIRTIO_CRYPTO_OK) { 59ca6c93387d32 zhenwei pi 2022-03-02 222 err = -EINVAL; 59ca6c93387d32 zhenwei pi 2022-03-02 223 goto out; 59ca6c93387d32 zhenwei pi 2022-03-02 224 } 59ca6c93387d32 zhenwei pi 2022-03-02 225 59ca6c93387d32 zhenwei pi 2022-03-02 226 err = 0; 59ca6c93387d32 zhenwei pi 2022-03-02 227 ctx->session_valid = false; 59ca6c93387d32 zhenwei pi 2022-03-02 228 59ca6c93387d32 zhenwei pi 2022-03-02 229 out: 286da9ed04239c zhenwei pi 2022-04-24 @230 kfree(vc_ctrl_req); 59ca6c93387d32 zhenwei pi 2022-03-02 231 if (err < 0) { 59ca6c93387d32 zhenwei pi 2022-03-02 @232 pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", bb26cab9a7c25d zhenwei pi 2022-04-24 233 ctrl_status->status, destroy_session->session_id); More canonical goto out bugs. 59ca6c93387d32 zhenwei pi 2022-03-02 234 } 59ca6c93387d32 zhenwei pi 2022-03-02 235 59ca6c93387d32 zhenwei pi 2022-03-02 236 return err; 59ca6c93387d32 zhenwei pi 2022-03-02 237 }
diff --git a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c index 20901a263fc8..509884e8b201 100644 --- a/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_akcipher_algs.c @@ -108,16 +108,22 @@ static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher unsigned int num_out = 0, num_in = 0; struct virtio_crypto_op_ctrl_req *ctrl; struct virtio_crypto_session_input *input; + struct virtio_crypto_ctrl_request *vc_ctrl_req; pkey = kmemdup(key, keylen, GFP_ATOMIC); if (!pkey) return -ENOMEM; - spin_lock(&vcrypto->ctrl_lock); - ctrl = &vcrypto->ctrl; + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + if (!vc_ctrl_req) { + err = -ENOMEM; + goto out; + } + + ctrl = &vc_ctrl_req->ctrl; memcpy(&ctrl->header, header, sizeof(ctrl->header)); memcpy(&ctrl->u, para, sizeof(ctrl->u)); - input = &vcrypto->input; + input = &vc_ctrl_req->input; input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR); sg_init_one(&outhdr_sg, ctrl, sizeof(*ctrl)); @@ -129,14 +135,18 @@ static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher sg_init_one(&inhdr_sg, input, sizeof(*input)); sgs[num_out + num_in++] = &inhdr_sg; + spin_lock(&vcrypto->ctrl_lock); err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); - if (err < 0) + if (err < 0) { + spin_unlock(&vcrypto->ctrl_lock); goto out; + } virtqueue_kick(vcrypto->ctrl_vq); while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && !virtqueue_is_broken(vcrypto->ctrl_vq)) cpu_relax(); + spin_unlock(&vcrypto->ctrl_lock); if (le32_to_cpu(input->status) != VIRTIO_CRYPTO_OK) { err = -EINVAL; @@ -148,7 +158,7 @@ static int virtio_crypto_alg_akcipher_init_session(struct virtio_crypto_akcipher err = 0; out: - spin_unlock(&vcrypto->ctrl_lock); + kfree(vc_ctrl_req); kfree_sensitive(pkey); if (err < 0) @@ -167,15 +177,22 @@ static int virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akciphe int err; struct virtio_crypto_op_ctrl_req *ctrl; struct virtio_crypto_inhdr *ctrl_status; + struct virtio_crypto_ctrl_request *vc_ctrl_req; - spin_lock(&vcrypto->ctrl_lock); if (!ctx->session_valid) { err = 0; goto out; } - ctrl_status = &vcrypto->ctrl_status; + + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + if (!vc_ctrl_req) { + err = -ENOMEM; + goto out; + } + + ctrl_status = &vc_ctrl_req->ctrl_status; ctrl_status->status = VIRTIO_CRYPTO_ERR; - ctrl = &vcrypto->ctrl; + ctrl = &vc_ctrl_req->ctrl; ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_AKCIPHER_DESTROY_SESSION); ctrl->header.queue_id = 0; @@ -188,14 +205,18 @@ static int virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akciphe sg_init_one(&inhdr_sg, &ctrl_status->status, sizeof(ctrl_status->status)); sgs[num_out + num_in++] = &inhdr_sg; + spin_lock(&vcrypto->ctrl_lock); err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); - if (err < 0) + if (err < 0) { + spin_unlock(&vcrypto->ctrl_lock); goto out; + } virtqueue_kick(vcrypto->ctrl_vq); while (!virtqueue_get_buf(vcrypto->ctrl_vq, &inlen) && !virtqueue_is_broken(vcrypto->ctrl_vq)) cpu_relax(); + spin_unlock(&vcrypto->ctrl_lock); if (ctrl_status->status != VIRTIO_CRYPTO_OK) { err = -EINVAL; @@ -206,7 +227,7 @@ static int virtio_crypto_alg_akcipher_close_session(struct virtio_crypto_akciphe ctx->session_valid = false; out: - spin_unlock(&vcrypto->ctrl_lock); + kfree(vc_ctrl_req); if (err < 0) { pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", ctrl_status->status, destroy_session->session_id); diff --git a/drivers/crypto/virtio/virtio_crypto_common.h b/drivers/crypto/virtio/virtio_crypto_common.h index e693d4ee83a6..2422237ec4e6 100644 --- a/drivers/crypto/virtio/virtio_crypto_common.h +++ b/drivers/crypto/virtio/virtio_crypto_common.h @@ -13,6 +13,7 @@ #include <crypto/aead.h> #include <crypto/aes.h> #include <crypto/engine.h> +#include <uapi/linux/virtio_crypto.h> /* Internal representation of a data virtqueue */ @@ -65,11 +66,6 @@ struct virtio_crypto { /* Maximum size of per request */ u64 max_size; - /* Control VQ buffers: protected by the ctrl_lock */ - struct virtio_crypto_op_ctrl_req ctrl; - struct virtio_crypto_session_input input; - struct virtio_crypto_inhdr ctrl_status; - unsigned long status; atomic_t ref_count; struct list_head list; @@ -85,6 +81,17 @@ struct virtio_crypto_sym_session_info { __u64 session_id; }; +/* + * Note: there are padding fields in request, clear them to zero before + * sending to host to avoid to divulge any information. + * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48] + */ +struct virtio_crypto_ctrl_request { + struct virtio_crypto_op_ctrl_req ctrl; + struct virtio_crypto_session_input input; + struct virtio_crypto_inhdr ctrl_status; +}; + struct virtio_crypto_request; typedef void (*virtio_crypto_data_callback) (struct virtio_crypto_request *vc_req, int len); diff --git a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c index e3c5bc8d6112..6aaf0869b211 100644 --- a/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c +++ b/drivers/crypto/virtio/virtio_crypto_skcipher_algs.c @@ -126,6 +126,7 @@ static int virtio_crypto_alg_skcipher_init_session( struct virtio_crypto_op_ctrl_req *ctrl; struct virtio_crypto_session_input *input; struct virtio_crypto_sym_create_session_req *sym_create_session; + struct virtio_crypto_ctrl_request *vc_ctrl_req; /* * Avoid to do DMA from the stack, switch to using @@ -136,15 +137,20 @@ static int virtio_crypto_alg_skcipher_init_session( if (!cipher_key) return -ENOMEM; - spin_lock(&vcrypto->ctrl_lock); + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + if (!vc_ctrl_req) { + err = -ENOMEM; + goto out; + } + /* Pad ctrl header */ - ctrl = &vcrypto->ctrl; + ctrl = &vc_ctrl_req->ctrl; ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_CREATE_SESSION); ctrl->header.algo = cpu_to_le32(alg); /* Set the default dataqueue id to 0 */ ctrl->header.queue_id = 0; - input = &vcrypto->input; + input = &vc_ctrl_req->input; input->status = cpu_to_le32(VIRTIO_CRYPTO_ERR); /* Pad cipher's parameters */ sym_create_session = &ctrl->u.sym_create_session; @@ -164,12 +170,12 @@ static int virtio_crypto_alg_skcipher_init_session( sg_init_one(&inhdr, input, sizeof(*input)); sgs[num_out + num_in++] = &inhdr; + spin_lock(&vcrypto->ctrl_lock); err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); if (err < 0) { spin_unlock(&vcrypto->ctrl_lock); - kfree_sensitive(cipher_key); - return err; + goto out; } virtqueue_kick(vcrypto->ctrl_vq); @@ -180,13 +186,13 @@ static int virtio_crypto_alg_skcipher_init_session( while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && !virtqueue_is_broken(vcrypto->ctrl_vq)) cpu_relax(); + spin_unlock(&vcrypto->ctrl_lock); if (le32_to_cpu(input->status) != VIRTIO_CRYPTO_OK) { - spin_unlock(&vcrypto->ctrl_lock); pr_err("virtio_crypto: Create session failed status: %u\n", le32_to_cpu(input->status)); - kfree_sensitive(cipher_key); - return -EINVAL; + err = -EINVAL; + goto out; } if (encrypt) @@ -194,10 +200,11 @@ static int virtio_crypto_alg_skcipher_init_session( else ctx->dec_sess_info.session_id = le64_to_cpu(input->session_id); - spin_unlock(&vcrypto->ctrl_lock); - + err = 0; +out: + kfree(vc_ctrl_req); kfree_sensitive(cipher_key); - return 0; + return err; } static int virtio_crypto_alg_skcipher_close_session( @@ -212,12 +219,16 @@ static int virtio_crypto_alg_skcipher_close_session( unsigned int num_out = 0, num_in = 0; struct virtio_crypto_op_ctrl_req *ctrl; struct virtio_crypto_inhdr *ctrl_status; + struct virtio_crypto_ctrl_request *vc_ctrl_req; - spin_lock(&vcrypto->ctrl_lock); - ctrl_status = &vcrypto->ctrl_status; + vc_ctrl_req = kzalloc(sizeof(*vc_ctrl_req), GFP_KERNEL); + if (!vc_ctrl_req) + return -ENOMEM; + + ctrl_status = &vc_ctrl_req->ctrl_status; ctrl_status->status = VIRTIO_CRYPTO_ERR; /* Pad ctrl header */ - ctrl = &vcrypto->ctrl; + ctrl = &vc_ctrl_req->ctrl; ctrl->header.opcode = cpu_to_le32(VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION); /* Set the default virtqueue id to 0 */ ctrl->header.queue_id = 0; @@ -236,28 +247,31 @@ static int virtio_crypto_alg_skcipher_close_session( sg_init_one(&status_sg, &ctrl_status->status, sizeof(ctrl_status->status)); sgs[num_out + num_in++] = &status_sg; + spin_lock(&vcrypto->ctrl_lock); err = virtqueue_add_sgs(vcrypto->ctrl_vq, sgs, num_out, num_in, vcrypto, GFP_ATOMIC); if (err < 0) { spin_unlock(&vcrypto->ctrl_lock); - return err; + goto out; } virtqueue_kick(vcrypto->ctrl_vq); while (!virtqueue_get_buf(vcrypto->ctrl_vq, &tmp) && !virtqueue_is_broken(vcrypto->ctrl_vq)) cpu_relax(); + spin_unlock(&vcrypto->ctrl_lock); if (ctrl_status->status != VIRTIO_CRYPTO_OK) { - spin_unlock(&vcrypto->ctrl_lock); pr_err("virtio_crypto: Close session failed status: %u, session_id: 0x%llx\n", ctrl_status->status, destroy_session->session_id); return -EINVAL; } - spin_unlock(&vcrypto->ctrl_lock); - return 0; + err = 0; +out: + kfree(vc_ctrl_req); + return err; } static int virtio_crypto_alg_skcipher_init_sessions(
Originally, all of the control requests share a single buffer( ctrl & input & ctrl_status fields in struct virtio_crypto), this allows queue depth 1 only, the performance of control queue gets limited by this design. In this patch, each request allocates request buffer dynamically, and free buffer after request, so the scope protected by ctrl_lock also get optimized here. It's possible to optimize control queue depth in the next step. A necessary comment is already in code, still describe it again: /* * Note: there are padding fields in request, clear them to zero before * sending to host to avoid to divulge any information. * Ex, virtio_crypto_ctrl_request::ctrl::u::destroy_session::padding[48] */ So use kzalloc to allocate buffer of struct virtio_crypto_ctrl_request. Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Jason Wang <jasowang@redhat.com> Cc: Gonglei <arei.gonglei@huawei.com> Signed-off-by: zhenwei pi <pizhenwei@bytedance.com> --- .../virtio/virtio_crypto_akcipher_algs.c | 41 +++++++++++---- drivers/crypto/virtio/virtio_crypto_common.h | 17 +++++-- .../virtio/virtio_crypto_skcipher_algs.c | 50 ++++++++++++------- 3 files changed, 75 insertions(+), 33 deletions(-)