Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2018 HUAWEI TECHNOLOGIES CO., LTD.
3 : : */
4 : : #include <cryptodev_pmd.h>
5 : :
6 : : #include "virtqueue.h"
7 : : #include "virtio_ring.h"
8 : : #include "virtio_cryptodev.h"
9 : : #include "virtio_crypto_algs.h"
10 : :
11 : : static void
12 : 0 : vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
13 : : {
14 : : struct vring_desc *dp, *dp_tail;
15 : : struct vq_desc_extra *dxp;
16 : : uint16_t desc_idx_last = desc_idx;
17 : :
18 : 0 : dp = &vq->vq_split.ring.desc[desc_idx];
19 : 0 : dxp = &vq->vq_descx[desc_idx];
20 : 0 : vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs);
21 [ # # ]: 0 : if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) {
22 [ # # ]: 0 : while (dp->flags & VRING_DESC_F_NEXT) {
23 : 0 : desc_idx_last = dp->next;
24 : 0 : dp = &vq->vq_split.ring.desc[dp->next];
25 : : }
26 : : }
27 : 0 : dxp->ndescs = 0;
28 : :
29 : : /*
30 : : * We must append the existing free chain, if any, to the end of
31 : : * newly freed chain. If the virtqueue was completely used, then
32 : : * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
33 : : */
34 [ # # ]: 0 : if (vq->vq_desc_tail_idx == VQ_RING_DESC_CHAIN_END) {
35 : 0 : vq->vq_desc_head_idx = desc_idx;
36 : : } else {
37 : 0 : dp_tail = &vq->vq_split.ring.desc[vq->vq_desc_tail_idx];
38 : 0 : dp_tail->next = desc_idx;
39 : : }
40 : :
41 : 0 : vq->vq_desc_tail_idx = desc_idx_last;
42 : 0 : dp->next = VQ_RING_DESC_CHAIN_END;
43 : 0 : }
44 : :
45 : : static uint16_t
46 : 0 : virtqueue_dequeue_burst_rx(struct virtqueue *vq,
47 : : struct rte_crypto_op **rx_pkts, uint16_t num)
48 : : {
49 : : struct vring_used_elem *uep;
50 : : struct rte_crypto_op *cop;
51 : : uint16_t used_idx, desc_idx;
52 : : uint16_t i;
53 : : struct virtio_crypto_inhdr *inhdr;
54 : : struct virtio_crypto_op_cookie *op_cookie;
55 : :
56 : : /* Caller does the check */
57 [ # # ]: 0 : for (i = 0; i < num ; i++) {
58 : 0 : used_idx = (uint16_t)(vq->vq_used_cons_idx
59 : 0 : & (vq->vq_nentries - 1));
60 : 0 : uep = &vq->vq_split.ring.used->ring[used_idx];
61 : 0 : desc_idx = (uint16_t)uep->id;
62 : 0 : cop = (struct rte_crypto_op *)
63 : 0 : vq->vq_descx[desc_idx].crypto_op;
64 [ # # ]: 0 : if (unlikely(cop == NULL)) {
65 : 0 : VIRTIO_CRYPTO_RX_LOG_DBG("vring descriptor with no "
66 : : "mbuf cookie at %u",
67 : : vq->vq_used_cons_idx);
68 : 0 : break;
69 : : }
70 : :
71 : 0 : op_cookie = (struct virtio_crypto_op_cookie *)
72 : : vq->vq_descx[desc_idx].cookie;
73 : : inhdr = &(op_cookie->inhdr);
74 [ # # # # : 0 : switch (inhdr->status) {
# # ]
75 : 0 : case VIRTIO_CRYPTO_OK:
76 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
77 : 0 : break;
78 : 0 : case VIRTIO_CRYPTO_ERR:
79 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
80 : 0 : vq->packets_received_failed++;
81 : 0 : break;
82 : 0 : case VIRTIO_CRYPTO_BADMSG:
83 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
84 : 0 : vq->packets_received_failed++;
85 : 0 : break;
86 : 0 : case VIRTIO_CRYPTO_NOTSUPP:
87 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
88 : 0 : vq->packets_received_failed++;
89 : 0 : break;
90 : 0 : case VIRTIO_CRYPTO_INVSESS:
91 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
92 : 0 : vq->packets_received_failed++;
93 : 0 : break;
94 : : default:
95 : : break;
96 : : }
97 : :
98 : 0 : vq->packets_received_total++;
99 : :
100 : 0 : rx_pkts[i] = cop;
101 [ # # ]: 0 : rte_mempool_put(vq->mpool, op_cookie);
102 : :
103 : 0 : vq->vq_used_cons_idx++;
104 : 0 : vq_ring_free_chain(vq, desc_idx);
105 : 0 : vq->vq_descx[desc_idx].crypto_op = NULL;
106 : : }
107 : :
108 : 0 : return i;
109 : : }
110 : :
111 : : static uint16_t
112 : 0 : virtqueue_dequeue_burst_rx_packed(struct virtqueue *vq,
113 : : struct rte_crypto_op **rx_pkts, uint16_t num)
114 : : {
115 : : struct rte_crypto_op *cop;
116 : : uint16_t used_idx;
117 : : uint16_t i;
118 : : struct virtio_crypto_inhdr *inhdr;
119 : : struct virtio_crypto_op_cookie *op_cookie;
120 : : struct vring_packed_desc *desc;
121 : :
122 : 0 : desc = vq->vq_packed.ring.desc;
123 : :
124 : : /* Caller does the check */
125 [ # # ]: 0 : for (i = 0; i < num ; i++) {
126 : 0 : used_idx = vq->vq_used_cons_idx;
127 [ # # ]: 0 : if (!desc_is_used(&desc[used_idx], vq))
128 : : break;
129 : :
130 : 0 : cop = (struct rte_crypto_op *)
131 : 0 : vq->vq_descx[used_idx].crypto_op;
132 [ # # ]: 0 : if (unlikely(cop == NULL)) {
133 : 0 : VIRTIO_CRYPTO_RX_LOG_DBG("vring descriptor with no "
134 : : "mbuf cookie at %u",
135 : : vq->vq_used_cons_idx);
136 : 0 : break;
137 : : }
138 : :
139 : 0 : op_cookie = (struct virtio_crypto_op_cookie *)
140 : : vq->vq_descx[used_idx].cookie;
141 : : inhdr = &(op_cookie->inhdr);
142 [ # # # # : 0 : switch (inhdr->status) {
# # ]
143 : 0 : case VIRTIO_CRYPTO_OK:
144 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_SUCCESS;
145 : 0 : break;
146 : 0 : case VIRTIO_CRYPTO_ERR:
147 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_ERROR;
148 : 0 : vq->packets_received_failed++;
149 : 0 : break;
150 : 0 : case VIRTIO_CRYPTO_BADMSG:
151 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
152 : 0 : vq->packets_received_failed++;
153 : 0 : break;
154 : 0 : case VIRTIO_CRYPTO_NOTSUPP:
155 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_ARGS;
156 : 0 : vq->packets_received_failed++;
157 : 0 : break;
158 : 0 : case VIRTIO_CRYPTO_INVSESS:
159 : 0 : cop->status = RTE_CRYPTO_OP_STATUS_INVALID_SESSION;
160 : 0 : vq->packets_received_failed++;
161 : 0 : break;
162 : : default:
163 : : break;
164 : : }
165 : :
166 : 0 : vq->packets_received_total++;
167 : :
168 [ # # ]: 0 : if (cop->asym->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN)
169 : 0 : memcpy(cop->asym->rsa.sign.data, op_cookie->sign,
170 : : cop->asym->rsa.sign.length);
171 [ # # ]: 0 : else if (cop->asym->rsa.op_type == RTE_CRYPTO_ASYM_OP_VERIFY)
172 : 0 : memcpy(cop->asym->rsa.message.data, op_cookie->message,
173 : : cop->asym->rsa.message.length);
174 [ # # ]: 0 : else if (cop->asym->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT)
175 : 0 : memcpy(cop->asym->rsa.cipher.data, op_cookie->cipher,
176 : : cop->asym->rsa.cipher.length);
177 [ # # ]: 0 : else if (cop->asym->rsa.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT)
178 : 0 : memcpy(cop->asym->rsa.message.data, op_cookie->message,
179 : : cop->asym->rsa.message.length);
180 : :
181 : 0 : rx_pkts[i] = cop;
182 [ # # ]: 0 : rte_mempool_put(vq->mpool, op_cookie);
183 : :
184 : 0 : vq->vq_free_cnt += 4;
185 : 0 : vq->vq_used_cons_idx += 4;
186 : 0 : vq->vq_descx[used_idx].crypto_op = NULL;
187 [ # # ]: 0 : if (vq->vq_used_cons_idx >= vq->vq_nentries) {
188 : 0 : vq->vq_used_cons_idx -= vq->vq_nentries;
189 : 0 : vq->vq_packed.used_wrap_counter ^= 1;
190 : : }
191 : : }
192 : :
193 : 0 : return i;
194 : : }
195 : :
196 : : static inline int
197 : 0 : virtqueue_crypto_sym_pkt_header_arrange(
198 : : struct rte_crypto_op *cop,
199 : : struct virtio_crypto_op_data_req *data,
200 : : struct virtio_crypto_session *session)
201 : : {
202 : : struct rte_crypto_sym_op *sym_op = cop->sym;
203 : : struct virtio_crypto_op_data_req *req_data = data;
204 : : struct virtio_crypto_op_ctrl_req *ctrl = &session->ctrl.hdr;
205 : : struct virtio_crypto_sym_create_session_req *sym_sess_req =
206 : : &ctrl->u.sym_create_session;
207 : : struct virtio_crypto_alg_chain_session_para *chain_para =
208 : : &sym_sess_req->u.chain.para;
209 : : struct virtio_crypto_cipher_session_para *cipher_para;
210 : :
211 : 0 : req_data->header.session_id = session->session_id;
212 : :
213 [ # # # ]: 0 : switch (sym_sess_req->op_type) {
214 : 0 : case VIRTIO_CRYPTO_SYM_OP_CIPHER:
215 : 0 : req_data->u.sym_req.op_type = VIRTIO_CRYPTO_SYM_OP_CIPHER;
216 : :
217 : : cipher_para = &sym_sess_req->u.cipher.para;
218 [ # # ]: 0 : if (cipher_para->op == VIRTIO_CRYPTO_OP_ENCRYPT)
219 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_ENCRYPT;
220 : : else
221 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_DECRYPT;
222 : :
223 : : req_data->u.sym_req.u.cipher.para.iv_len
224 : 0 : = session->iv.length;
225 : :
226 : 0 : req_data->u.sym_req.u.cipher.para.src_data_len =
227 : 0 : (sym_op->cipher.data.length +
228 : 0 : sym_op->cipher.data.offset);
229 : 0 : req_data->u.sym_req.u.cipher.para.dst_data_len =
230 : : req_data->u.sym_req.u.cipher.para.src_data_len;
231 : 0 : break;
232 : 0 : case VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING:
233 : 0 : req_data->u.sym_req.op_type =
234 : : VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING;
235 : :
236 : : cipher_para = &chain_para->cipher_param;
237 [ # # ]: 0 : if (cipher_para->op == VIRTIO_CRYPTO_OP_ENCRYPT)
238 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_ENCRYPT;
239 : : else
240 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_DECRYPT;
241 : :
242 : 0 : req_data->u.sym_req.u.chain.para.iv_len = session->iv.length;
243 : : req_data->u.sym_req.u.chain.para.aad_len = session->aad.length;
244 : :
245 : 0 : req_data->u.sym_req.u.chain.para.src_data_len =
246 : 0 : (sym_op->cipher.data.length +
247 : 0 : sym_op->cipher.data.offset);
248 : 0 : req_data->u.sym_req.u.chain.para.dst_data_len =
249 : : req_data->u.sym_req.u.chain.para.src_data_len;
250 : 0 : req_data->u.sym_req.u.chain.para.cipher_start_src_offset =
251 : : sym_op->cipher.data.offset;
252 : 0 : req_data->u.sym_req.u.chain.para.len_to_cipher =
253 : : sym_op->cipher.data.length;
254 : 0 : req_data->u.sym_req.u.chain.para.hash_start_src_offset =
255 : 0 : sym_op->auth.data.offset;
256 : 0 : req_data->u.sym_req.u.chain.para.len_to_hash =
257 : 0 : sym_op->auth.data.length;
258 : 0 : req_data->u.sym_req.u.chain.para.aad_len =
259 : 0 : chain_para->aad_len;
260 : :
261 [ # # ]: 0 : if (chain_para->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN)
262 : 0 : req_data->u.sym_req.u.chain.para.hash_result_len =
263 : 0 : chain_para->u.hash_param.hash_result_len;
264 [ # # ]: 0 : if (chain_para->hash_mode ==
265 : : VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH)
266 : 0 : req_data->u.sym_req.u.chain.para.hash_result_len =
267 : 0 : chain_para->u.mac_param.hash_result_len;
268 : : break;
269 : : default:
270 : : return -1;
271 : : }
272 : :
273 : : return 0;
274 : : }
275 : :
276 : : static inline int
277 : 0 : virtqueue_crypto_sym_enqueue_xmit_split(
278 : : struct virtqueue *txvq,
279 : : struct rte_crypto_op *cop)
280 : : {
281 : : uint16_t idx = 0;
282 : : uint16_t num_entry;
283 : : uint16_t needed = 1;
284 : : uint16_t head_idx;
285 : : struct vq_desc_extra *dxp;
286 : : struct vring_desc *start_dp;
287 : : struct vring_desc *desc;
288 : : uint64_t indirect_op_data_req_phys_addr;
289 : : uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req);
290 : : uint32_t indirect_vring_addr_offset = req_data_len +
291 : : sizeof(struct virtio_crypto_inhdr);
292 : : uint32_t indirect_iv_addr_offset =
293 : : offsetof(struct virtio_crypto_op_cookie, iv);
294 : : struct rte_crypto_sym_op *sym_op = cop->sym;
295 : 0 : struct virtio_crypto_session *session =
296 : 0 : CRYPTODEV_GET_SYM_SESS_PRIV(cop->sym->session);
297 : : struct virtio_crypto_op_data_req *op_data_req;
298 : : uint32_t hash_result_len = 0;
299 : : struct virtio_crypto_op_cookie *crypto_op_cookie;
300 : : struct virtio_crypto_alg_chain_session_para *para;
301 : :
302 [ # # ]: 0 : if (unlikely(sym_op->m_src->nb_segs != 1))
303 : : return -EMSGSIZE;
304 [ # # ]: 0 : if (unlikely(txvq->vq_free_cnt == 0))
305 : : return -ENOSPC;
306 : : if (unlikely(txvq->vq_free_cnt < needed))
307 : : return -EMSGSIZE;
308 : 0 : head_idx = txvq->vq_desc_head_idx;
309 [ # # ]: 0 : if (unlikely(head_idx >= txvq->vq_nentries))
310 : : return -EFAULT;
311 : : if (unlikely(session == NULL))
312 : : return -EFAULT;
313 : :
314 : 0 : dxp = &txvq->vq_descx[head_idx];
315 : :
316 [ # # # # ]: 0 : if (rte_mempool_get(txvq->mpool, &dxp->cookie)) {
317 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("can not get cookie");
318 : 0 : return -EFAULT;
319 : : }
320 : 0 : crypto_op_cookie = dxp->cookie;
321 : : indirect_op_data_req_phys_addr =
322 : : rte_mempool_virt2iova(crypto_op_cookie);
323 : : op_data_req = (struct virtio_crypto_op_data_req *)crypto_op_cookie;
324 : :
325 [ # # ]: 0 : if (virtqueue_crypto_sym_pkt_header_arrange(cop, op_data_req, session))
326 : : return -EFAULT;
327 : :
328 : : /* status is initialized to VIRTIO_CRYPTO_ERR */
329 : : ((struct virtio_crypto_inhdr *)
330 : 0 : ((uint8_t *)op_data_req + req_data_len))->status =
331 : : VIRTIO_CRYPTO_ERR;
332 : :
333 : : /* point to indirect vring entry */
334 : 0 : desc = (struct vring_desc *)
335 : : ((uint8_t *)op_data_req + indirect_vring_addr_offset);
336 [ # # ]: 0 : for (idx = 0; idx < (NUM_ENTRY_VIRTIO_CRYPTO_OP - 1); idx++)
337 : 0 : desc[idx].next = idx + 1;
338 : 0 : desc[NUM_ENTRY_VIRTIO_CRYPTO_OP - 1].next = VQ_RING_DESC_CHAIN_END;
339 : :
340 : : idx = 0;
341 : :
342 : : /* indirect vring: first part, virtio_crypto_op_data_req */
343 : 0 : desc[idx].addr = indirect_op_data_req_phys_addr;
344 : 0 : desc[idx].len = req_data_len;
345 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
346 : :
347 : : /* indirect vring: iv of cipher */
348 [ # # ]: 0 : if (session->iv.length) {
349 [ # # ]: 0 : if (cop->phys_addr)
350 : 0 : desc[idx].addr = cop->phys_addr + session->iv.offset;
351 : : else {
352 [ # # ]: 0 : if (session->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE)
353 : : return -ENOMEM;
354 : :
355 : 0 : rte_memcpy(crypto_op_cookie->iv,
356 [ # # ]: 0 : rte_crypto_op_ctod_offset(cop,
357 : : uint8_t *, session->iv.offset),
358 : : session->iv.length);
359 : 0 : desc[idx].addr = indirect_op_data_req_phys_addr +
360 : : indirect_iv_addr_offset;
361 : : }
362 : :
363 : 0 : desc[idx].len = session->iv.length;
364 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
365 : : }
366 : :
367 : : /* indirect vring: additional auth data */
368 [ # # ]: 0 : if (session->aad.length) {
369 : 0 : desc[idx].addr = session->aad.phys_addr;
370 : 0 : desc[idx].len = session->aad.length;
371 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
372 : : }
373 : :
374 : : /* indirect vring: src data */
375 [ # # ]: 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_src, 0);
376 : 0 : desc[idx].len = (sym_op->cipher.data.offset
377 : 0 : + sym_op->cipher.data.length);
378 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
379 : :
380 : : /* indirect vring: dst data */
381 [ # # ]: 0 : if (sym_op->m_dst) {
382 : 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_dst, 0);
383 : 0 : desc[idx].len = (sym_op->cipher.data.offset
384 : : + sym_op->cipher.data.length);
385 : : } else {
386 : 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_src, 0);
387 : 0 : desc[idx].len = (sym_op->cipher.data.offset
388 : : + sym_op->cipher.data.length);
389 : : }
390 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
391 : :
392 : : /* indirect vring: digest result */
393 : : para = &(session->ctrl.hdr.u.sym_create_session.u.chain.para);
394 [ # # ]: 0 : if (para->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN)
395 : 0 : hash_result_len = para->u.hash_param.hash_result_len;
396 [ # # ]: 0 : if (para->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH)
397 : 0 : hash_result_len = para->u.mac_param.hash_result_len;
398 [ # # ]: 0 : if (hash_result_len > 0) {
399 : 0 : desc[idx].addr = sym_op->auth.digest.phys_addr;
400 : 0 : desc[idx].len = hash_result_len;
401 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
402 : : }
403 : :
404 : : /* indirect vring: last part, status returned */
405 : 0 : desc[idx].addr = indirect_op_data_req_phys_addr + req_data_len;
406 : 0 : desc[idx].len = sizeof(struct virtio_crypto_inhdr);
407 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE;
408 : :
409 : : num_entry = idx;
410 : :
411 : : /* save the infos to use when receiving packets */
412 : 0 : dxp->crypto_op = (void *)cop;
413 : 0 : dxp->ndescs = needed;
414 : :
415 : : /* use a single buffer */
416 : 0 : start_dp = txvq->vq_split.ring.desc;
417 : 0 : start_dp[head_idx].addr = indirect_op_data_req_phys_addr +
418 : : indirect_vring_addr_offset;
419 : 0 : start_dp[head_idx].len = num_entry * sizeof(struct vring_desc);
420 : 0 : start_dp[head_idx].flags = VRING_DESC_F_INDIRECT;
421 : :
422 : 0 : idx = start_dp[head_idx].next;
423 : 0 : txvq->vq_desc_head_idx = idx;
424 [ # # ]: 0 : if (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
425 : 0 : txvq->vq_desc_tail_idx = idx;
426 [ # # ]: 0 : txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
427 : : vq_update_avail_ring(txvq, head_idx);
428 : :
429 : 0 : return 0;
430 : : }
431 : :
432 : : static inline int
433 : 0 : virtqueue_crypto_sym_enqueue_xmit_packed(
434 : : struct virtqueue *txvq,
435 : : struct rte_crypto_op *cop)
436 : : {
437 : : uint16_t idx = 0;
438 : : uint16_t needed = 1;
439 : : uint16_t head_idx;
440 : : struct vq_desc_extra *dxp;
441 : : struct vring_packed_desc *start_dp;
442 : : struct vring_packed_desc *desc;
443 : : uint64_t op_data_req_phys_addr;
444 : : uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req);
445 : : uint32_t iv_addr_offset =
446 : : offsetof(struct virtio_crypto_op_cookie, iv);
447 : : struct rte_crypto_sym_op *sym_op = cop->sym;
448 : 0 : struct virtio_crypto_session *session =
449 : 0 : CRYPTODEV_GET_SYM_SESS_PRIV(cop->sym->session);
450 : : struct virtio_crypto_op_data_req *op_data_req;
451 : : uint32_t hash_result_len = 0;
452 : : struct virtio_crypto_op_cookie *crypto_op_cookie;
453 : : struct virtio_crypto_alg_chain_session_para *para;
454 : : uint16_t flags = VRING_DESC_F_NEXT;
455 : :
456 [ # # ]: 0 : if (unlikely(sym_op->m_src->nb_segs != 1))
457 : : return -EMSGSIZE;
458 [ # # ]: 0 : if (unlikely(txvq->vq_free_cnt == 0))
459 : : return -ENOSPC;
460 : : if (unlikely(txvq->vq_free_cnt < needed))
461 : : return -EMSGSIZE;
462 : 0 : head_idx = txvq->vq_desc_head_idx;
463 [ # # ]: 0 : if (unlikely(head_idx >= txvq->vq_nentries))
464 : : return -EFAULT;
465 : : if (unlikely(session == NULL))
466 : : return -EFAULT;
467 : :
468 : 0 : dxp = &txvq->vq_descx[head_idx];
469 : :
470 [ # # # # ]: 0 : if (rte_mempool_get(txvq->mpool, &dxp->cookie)) {
471 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("can not get cookie");
472 : 0 : return -EFAULT;
473 : : }
474 : 0 : crypto_op_cookie = dxp->cookie;
475 : : op_data_req_phys_addr = rte_mempool_virt2iova(crypto_op_cookie);
476 : : op_data_req = (struct virtio_crypto_op_data_req *)crypto_op_cookie;
477 : :
478 [ # # ]: 0 : if (virtqueue_crypto_sym_pkt_header_arrange(cop, op_data_req, session))
479 : : return -EFAULT;
480 : :
481 : : /* status is initialized to VIRTIO_CRYPTO_ERR */
482 : : ((struct virtio_crypto_inhdr *)
483 : 0 : ((uint8_t *)op_data_req + req_data_len))->status =
484 : : VIRTIO_CRYPTO_ERR;
485 : :
486 : 0 : desc = &txvq->vq_packed.ring.desc[txvq->vq_desc_head_idx];
487 : : needed = 4;
488 : 0 : flags |= txvq->vq_packed.cached_flags;
489 : :
490 : : start_dp = desc;
491 : : idx = 0;
492 : :
493 : : /* packed vring: first part, virtio_crypto_op_data_req */
494 : 0 : desc[idx].addr = op_data_req_phys_addr;
495 : 0 : desc[idx].len = req_data_len;
496 : 0 : desc[idx++].flags = flags;
497 : :
498 : : /* packed vring: iv of cipher */
499 [ # # ]: 0 : if (session->iv.length) {
500 [ # # ]: 0 : if (cop->phys_addr)
501 : 0 : desc[idx].addr = cop->phys_addr + session->iv.offset;
502 : : else {
503 [ # # ]: 0 : if (session->iv.length > VIRTIO_CRYPTO_MAX_IV_SIZE)
504 : : return -ENOMEM;
505 : :
506 : 0 : rte_memcpy(crypto_op_cookie->iv,
507 [ # # ]: 0 : rte_crypto_op_ctod_offset(cop,
508 : : uint8_t *, session->iv.offset),
509 : : session->iv.length);
510 : 0 : desc[idx].addr = op_data_req_phys_addr + iv_addr_offset;
511 : : }
512 : :
513 : 0 : desc[idx].len = session->iv.length;
514 : 0 : desc[idx++].flags = flags;
515 : : }
516 : :
517 : : /* packed vring: additional auth data */
518 [ # # ]: 0 : if (session->aad.length) {
519 : 0 : desc[idx].addr = session->aad.phys_addr;
520 : 0 : desc[idx].len = session->aad.length;
521 : 0 : desc[idx++].flags = flags;
522 : : }
523 : :
524 : : /* packed vring: src data */
525 [ # # ]: 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_src, 0);
526 : 0 : desc[idx].len = (sym_op->cipher.data.offset
527 : 0 : + sym_op->cipher.data.length);
528 : 0 : desc[idx++].flags = flags;
529 : :
530 : : /* packed vring: dst data */
531 [ # # ]: 0 : if (sym_op->m_dst) {
532 : 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_dst, 0);
533 : 0 : desc[idx].len = (sym_op->cipher.data.offset
534 : : + sym_op->cipher.data.length);
535 : : } else {
536 : 0 : desc[idx].addr = rte_pktmbuf_iova_offset(sym_op->m_src, 0);
537 : 0 : desc[idx].len = (sym_op->cipher.data.offset
538 : : + sym_op->cipher.data.length);
539 : : }
540 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
541 : :
542 : : /* packed vring: digest result */
543 : : para = &(session->ctrl.hdr.u.sym_create_session.u.chain.para);
544 [ # # ]: 0 : if (para->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN)
545 : 0 : hash_result_len = para->u.hash_param.hash_result_len;
546 [ # # ]: 0 : if (para->hash_mode == VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH)
547 : 0 : hash_result_len = para->u.mac_param.hash_result_len;
548 [ # # ]: 0 : if (hash_result_len > 0) {
549 : 0 : desc[idx].addr = sym_op->auth.digest.phys_addr;
550 : 0 : desc[idx].len = hash_result_len;
551 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
552 : : }
553 : :
554 : : /* packed vring: last part, status returned */
555 : 0 : desc[idx].addr = op_data_req_phys_addr + req_data_len;
556 : 0 : desc[idx].len = sizeof(struct virtio_crypto_inhdr);
557 : 0 : desc[idx++].flags = flags | VRING_DESC_F_WRITE;
558 : :
559 : : /* save the infos to use when receiving packets */
560 : 0 : dxp->crypto_op = (void *)cop;
561 : 0 : dxp->ndescs = needed;
562 : :
563 : 0 : txvq->vq_desc_head_idx += idx & (txvq->vq_nentries - 1);
564 [ # # ]: 0 : if (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
565 : 0 : txvq->vq_desc_tail_idx = idx;
566 : 0 : txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
567 : 0 : virtqueue_store_flags_packed(&start_dp[0],
568 : 0 : start_dp[0].flags | flags,
569 [ # # ]: 0 : txvq->hw->weak_barriers);
570 [ # # ]: 0 : virtio_wmb(txvq->hw->weak_barriers);
571 : :
572 : : return 0;
573 : : }
574 : :
575 : : static inline int
576 : 0 : virtqueue_crypto_sym_enqueue_xmit(
577 : : struct virtqueue *txvq,
578 : : struct rte_crypto_op *cop)
579 : : {
580 [ # # ]: 0 : if (vtpci_with_packed_queue(txvq->hw))
581 : 0 : return virtqueue_crypto_sym_enqueue_xmit_packed(txvq, cop);
582 : : else
583 : 0 : return virtqueue_crypto_sym_enqueue_xmit_split(txvq, cop);
584 : : }
585 : :
586 : : static inline int
587 : 0 : virtqueue_crypto_asym_pkt_header_arrange(
588 : : struct rte_crypto_op *cop,
589 : : struct virtio_crypto_op_data_req *data,
590 : : struct virtio_crypto_session *session)
591 : : {
592 : : struct virtio_crypto_op_ctrl_req *ctrl = &session->ctrl.hdr;
593 : : struct virtio_crypto_op_data_req *req_data = data;
594 : : struct rte_crypto_asym_op *asym_op = cop->asym;
595 : :
596 : 0 : req_data->header.session_id = session->session_id;
597 : :
598 [ # # ]: 0 : switch (ctrl->header.algo) {
599 : 0 : case VIRTIO_CRYPTO_AKCIPHER_RSA:
600 : 0 : req_data->header.algo = ctrl->header.algo;
601 [ # # ]: 0 : if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
602 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_AKCIPHER_SIGN;
603 : : req_data->u.akcipher_req.para.src_data_len
604 : 0 : = asym_op->rsa.message.length;
605 : : req_data->u.akcipher_req.para.dst_data_len
606 : 0 : = asym_op->rsa.sign.length;
607 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
608 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_AKCIPHER_VERIFY;
609 : : req_data->u.akcipher_req.para.src_data_len
610 : 0 : = asym_op->rsa.sign.length;
611 : : req_data->u.akcipher_req.para.dst_data_len
612 : 0 : = asym_op->rsa.message.length;
613 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
614 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_AKCIPHER_ENCRYPT;
615 : : req_data->u.akcipher_req.para.src_data_len
616 : 0 : = asym_op->rsa.message.length;
617 : : req_data->u.akcipher_req.para.dst_data_len
618 : 0 : = asym_op->rsa.cipher.length;
619 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
620 : 0 : req_data->header.opcode = VIRTIO_CRYPTO_AKCIPHER_DECRYPT;
621 : : req_data->u.akcipher_req.para.src_data_len
622 : 0 : = asym_op->rsa.cipher.length;
623 : : req_data->u.akcipher_req.para.dst_data_len
624 : 0 : = asym_op->rsa.message.length;
625 : : } else {
626 : : return -EINVAL;
627 : : }
628 : :
629 : : break;
630 : 0 : default:
631 : 0 : req_data->header.algo = VIRTIO_CRYPTO_NO_AKCIPHER;
632 : : }
633 : :
634 : : return 0;
635 : : }
636 : :
637 : : static inline int
638 : 0 : virtqueue_crypto_asym_enqueue_xmit_split(
639 : : struct virtqueue *txvq,
640 : : struct rte_crypto_op *cop)
641 : : {
642 : : uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req);
643 : : uint32_t indirect_vring_addr_offset = req_data_len +
644 : : sizeof(struct virtio_crypto_inhdr);
645 : 0 : struct virtio_crypto_session *session =
646 : 0 : CRYPTODEV_GET_ASYM_SESS_PRIV(cop->asym->session);
647 : : struct virtio_crypto_op_cookie *crypto_op_cookie;
648 : : struct rte_crypto_asym_op *asym_op = cop->asym;
649 : : struct virtio_crypto_op_data_req *op_data_req;
650 : : uint64_t indirect_op_data_req_phys_addr;
651 : : struct vring_used_elem *uep;
652 : : struct vring_desc *start_dp;
653 : : struct vq_desc_extra *dxp;
654 : : struct vring_desc *desc;
655 : : uint16_t needed = 1;
656 : : uint16_t num_entry;
657 : : uint16_t head_idx;
658 : : uint16_t idx = 0;
659 : :
660 [ # # ]: 0 : if (unlikely(txvq->vq_free_cnt == 0))
661 : : return -ENOSPC;
662 : : if (unlikely(txvq->vq_free_cnt < needed))
663 : : return -EMSGSIZE;
664 : 0 : head_idx = txvq->vq_desc_head_idx;
665 [ # # ]: 0 : if (unlikely(head_idx >= txvq->vq_nentries))
666 : : return -EFAULT;
667 : :
668 : 0 : dxp = &txvq->vq_descx[head_idx];
669 : :
670 [ # # # # ]: 0 : if (rte_mempool_get(txvq->mpool, &dxp->cookie)) {
671 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("can not get cookie");
672 : 0 : return -EFAULT;
673 : : }
674 : 0 : crypto_op_cookie = dxp->cookie;
675 : : indirect_op_data_req_phys_addr =
676 : : rte_mempool_virt2iova(crypto_op_cookie);
677 : : op_data_req = (struct virtio_crypto_op_data_req *)crypto_op_cookie;
678 [ # # ]: 0 : if (virtqueue_crypto_asym_pkt_header_arrange(cop, op_data_req, session))
679 : : return -EFAULT;
680 : :
681 : : /* status is initialized to VIRTIO_CRYPTO_ERR */
682 : : ((struct virtio_crypto_inhdr *)
683 : 0 : ((uint8_t *)op_data_req + req_data_len))->status =
684 : : VIRTIO_CRYPTO_ERR;
685 : :
686 : : /* point to indirect vring entry */
687 : : desc = (struct vring_desc *)
688 : : ((uint8_t *)op_data_req + indirect_vring_addr_offset);
689 [ # # ]: 0 : for (idx = 0; idx < (NUM_ENTRY_VIRTIO_CRYPTO_OP - 1); idx++)
690 : 0 : desc[idx].next = idx + 1;
691 : 0 : desc[NUM_ENTRY_VIRTIO_CRYPTO_OP - 1].next = VQ_RING_DESC_CHAIN_END;
692 : :
693 : : idx = 0;
694 : :
695 : : /* indirect vring: first part, virtio_crypto_op_data_req */
696 : 0 : desc[idx].addr = indirect_op_data_req_phys_addr;
697 : 0 : desc[idx].len = req_data_len;
698 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
699 : :
700 [ # # ]: 0 : if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
701 : : /* indirect vring: src data */
702 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.message.data);
703 : 0 : desc[idx].len = asym_op->rsa.message.length;
704 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
705 : :
706 : : /* indirect vring: dst data */
707 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.sign.data);
708 : 0 : desc[idx].len = asym_op->rsa.sign.length;
709 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT | VRING_DESC_F_WRITE;
710 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
711 : : /* indirect vring: src data */
712 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.sign.data);
713 : 0 : desc[idx].len = asym_op->rsa.sign.length;
714 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
715 : :
716 : : /* indirect vring: dst data */
717 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.message.data);
718 : 0 : desc[idx].len = asym_op->rsa.message.length;
719 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
720 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
721 : : /* indirect vring: src data */
722 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.message.data);
723 : 0 : desc[idx].len = asym_op->rsa.message.length;
724 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
725 : :
726 : : /* indirect vring: dst data */
727 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.cipher.data);
728 : 0 : desc[idx].len = asym_op->rsa.cipher.length;
729 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT | VRING_DESC_F_WRITE;
730 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
731 : : /* indirect vring: src data */
732 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.cipher.data);
733 : 0 : desc[idx].len = asym_op->rsa.cipher.length;
734 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT;
735 : :
736 : : /* indirect vring: dst data */
737 : 0 : desc[idx].addr = rte_mem_virt2iova(asym_op->rsa.message.data);
738 : 0 : desc[idx].len = asym_op->rsa.message.length;
739 : 0 : desc[idx++].flags = VRING_DESC_F_NEXT | VRING_DESC_F_WRITE;
740 : : } else {
741 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("Invalid asym op");
742 : 0 : return -EINVAL;
743 : : }
744 : :
745 : : /* indirect vring: last part, status returned */
746 : 0 : desc[idx].addr = indirect_op_data_req_phys_addr + req_data_len;
747 : 0 : desc[idx].len = sizeof(struct virtio_crypto_inhdr);
748 : 0 : desc[idx++].flags = VRING_DESC_F_WRITE;
749 : :
750 : : num_entry = idx;
751 : :
752 : : /* save the infos to use when receiving packets */
753 : 0 : dxp->crypto_op = (void *)cop;
754 : 0 : dxp->ndescs = needed;
755 : :
756 : : /* use a single buffer */
757 : 0 : start_dp = txvq->vq_split.ring.desc;
758 : 0 : start_dp[head_idx].addr = indirect_op_data_req_phys_addr +
759 : : indirect_vring_addr_offset;
760 : 0 : start_dp[head_idx].len = num_entry * sizeof(struct vring_desc);
761 : 0 : start_dp[head_idx].flags = VRING_DESC_F_INDIRECT;
762 : :
763 : 0 : idx = start_dp[head_idx].next;
764 : 0 : txvq->vq_desc_head_idx = idx;
765 [ # # ]: 0 : if (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
766 : 0 : txvq->vq_desc_tail_idx = idx;
767 : 0 : txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
768 : :
769 : 0 : uep = &txvq->vq_split.ring.used->ring[head_idx];
770 [ # # ]: 0 : uep->id = head_idx;
771 : : vq_update_avail_ring(txvq, head_idx);
772 : :
773 : 0 : return 0;
774 : : }
775 : :
776 : : static inline int
777 : 0 : virtqueue_crypto_asym_enqueue_xmit_packed(
778 : : struct virtqueue *txvq,
779 : : struct rte_crypto_op *cop)
780 : : {
781 : : uint16_t idx = 0;
782 : : uint16_t num_entry;
783 : : uint16_t needed = 1;
784 : : uint16_t head_idx;
785 : : struct vq_desc_extra *dxp;
786 : : struct vring_packed_desc *start_dp;
787 : : struct vring_packed_desc *desc;
788 : : uint64_t op_data_req_phys_addr;
789 : : uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req);
790 : : struct rte_crypto_asym_op *asym_op = cop->asym;
791 : 0 : struct virtio_crypto_session *session =
792 : 0 : CRYPTODEV_GET_ASYM_SESS_PRIV(cop->asym->session);
793 : : struct virtio_crypto_op_data_req *op_data_req;
794 : : struct virtio_crypto_op_cookie *crypto_op_cookie;
795 : : uint16_t flags = VRING_DESC_F_NEXT;
796 : :
797 [ # # ]: 0 : if (unlikely(txvq->vq_free_cnt == 0))
798 : : return -ENOSPC;
799 : : if (unlikely(txvq->vq_free_cnt < needed))
800 : : return -EMSGSIZE;
801 : 0 : head_idx = txvq->vq_desc_head_idx;
802 [ # # ]: 0 : if (unlikely(head_idx >= txvq->vq_nentries))
803 : : return -EFAULT;
804 : :
805 : 0 : dxp = &txvq->vq_descx[head_idx];
806 : :
807 [ # # # # ]: 0 : if (rte_mempool_get(txvq->mpool, &dxp->cookie)) {
808 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("can not get cookie");
809 : 0 : return -EFAULT;
810 : : }
811 : 0 : crypto_op_cookie = dxp->cookie;
812 : : op_data_req_phys_addr = rte_mempool_virt2iova(crypto_op_cookie);
813 : : op_data_req = (struct virtio_crypto_op_data_req *)crypto_op_cookie;
814 [ # # ]: 0 : if (virtqueue_crypto_asym_pkt_header_arrange(cop, op_data_req, session))
815 : : return -EFAULT;
816 : :
817 : : /* status is initialized to VIRTIO_CRYPTO_ERR */
818 : : ((struct virtio_crypto_inhdr *)
819 : 0 : ((uint8_t *)op_data_req + req_data_len))->status =
820 : : VIRTIO_CRYPTO_ERR;
821 : :
822 : 0 : desc = &txvq->vq_packed.ring.desc[txvq->vq_desc_head_idx];
823 : : needed = 4;
824 : 0 : flags |= txvq->vq_packed.cached_flags;
825 : :
826 : : start_dp = desc;
827 : : idx = 0;
828 : :
829 : : /* packed vring: first part, virtio_crypto_op_data_req */
830 : 0 : desc[idx].addr = op_data_req_phys_addr;
831 : 0 : desc[idx].len = sizeof(struct virtio_crypto_op_data_req);
832 : 0 : desc[idx++].flags = flags;
833 : :
834 [ # # ]: 0 : if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_SIGN) {
835 : : /* packed vring: src data */
836 [ # # ]: 0 : if (asym_op->rsa.message.length > VIRTIO_CRYPTO_MAX_MSG_SIZE)
837 : : return -ENOMEM;
838 [ # # ]: 0 : memcpy(crypto_op_cookie->message, asym_op->rsa.message.data,
839 : : asym_op->rsa.message.length);
840 : 0 : desc[idx].addr = op_data_req_phys_addr +
841 : : offsetof(struct virtio_crypto_op_cookie, message);
842 : 0 : desc[idx].len = asym_op->rsa.message.length;
843 : 0 : desc[idx++].flags = flags;
844 : :
845 : : /* packed vring: dst data */
846 [ # # ]: 0 : if (asym_op->rsa.sign.length > VIRTIO_CRYPTO_MAX_SIGN_SIZE)
847 : : return -ENOMEM;
848 : 0 : desc[idx].addr = op_data_req_phys_addr +
849 : : offsetof(struct virtio_crypto_op_cookie, sign);
850 : 0 : desc[idx].len = asym_op->rsa.sign.length;
851 : 0 : desc[idx++].flags = flags | VRING_DESC_F_WRITE;
852 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_VERIFY) {
853 : : /* packed vring: src data */
854 [ # # ]: 0 : if (asym_op->rsa.sign.length > VIRTIO_CRYPTO_MAX_SIGN_SIZE)
855 : : return -ENOMEM;
856 [ # # ]: 0 : memcpy(crypto_op_cookie->sign, asym_op->rsa.sign.data,
857 : : asym_op->rsa.sign.length);
858 : 0 : desc[idx].addr = op_data_req_phys_addr +
859 : : offsetof(struct virtio_crypto_op_cookie, sign);
860 : 0 : desc[idx].len = asym_op->rsa.sign.length;
861 : 0 : desc[idx++].flags = flags;
862 : :
863 : : /* packed vring: dst data */
864 [ # # ]: 0 : if (asym_op->rsa.message.length > VIRTIO_CRYPTO_MAX_MSG_SIZE)
865 : : return -ENOMEM;
866 : 0 : desc[idx].addr = op_data_req_phys_addr +
867 : : offsetof(struct virtio_crypto_op_cookie, message);
868 : 0 : desc[idx].len = asym_op->rsa.message.length;
869 : 0 : desc[idx++].flags = flags;
870 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_ENCRYPT) {
871 : : /* packed vring: src data */
872 [ # # ]: 0 : if (asym_op->rsa.message.length > VIRTIO_CRYPTO_MAX_MSG_SIZE)
873 : : return -ENOMEM;
874 [ # # ]: 0 : memcpy(crypto_op_cookie->message, asym_op->rsa.message.data,
875 : : asym_op->rsa.message.length);
876 : 0 : desc[idx].addr = op_data_req_phys_addr +
877 : : offsetof(struct virtio_crypto_op_cookie, message);
878 : 0 : desc[idx].len = asym_op->rsa.message.length;
879 : 0 : desc[idx++].flags = flags;
880 : :
881 : : /* packed vring: dst data */
882 [ # # ]: 0 : if (asym_op->rsa.cipher.length > VIRTIO_CRYPTO_MAX_CIPHER_SIZE)
883 : : return -ENOMEM;
884 : 0 : desc[idx].addr = op_data_req_phys_addr +
885 : : offsetof(struct virtio_crypto_op_cookie, cipher);
886 : 0 : desc[idx].len = asym_op->rsa.cipher.length;
887 : 0 : desc[idx++].flags = flags | VRING_DESC_F_WRITE;
888 [ # # ]: 0 : } else if (asym_op->rsa.op_type == RTE_CRYPTO_ASYM_OP_DECRYPT) {
889 : : /* packed vring: src data */
890 [ # # ]: 0 : if (asym_op->rsa.cipher.length > VIRTIO_CRYPTO_MAX_CIPHER_SIZE)
891 : : return -ENOMEM;
892 [ # # ]: 0 : memcpy(crypto_op_cookie->cipher, asym_op->rsa.cipher.data,
893 : : asym_op->rsa.cipher.length);
894 : 0 : desc[idx].addr = op_data_req_phys_addr +
895 : : offsetof(struct virtio_crypto_op_cookie, cipher);
896 : 0 : desc[idx].len = asym_op->rsa.cipher.length;
897 : 0 : desc[idx++].flags = flags;
898 : :
899 : : /* packed vring: dst data */
900 [ # # ]: 0 : if (asym_op->rsa.message.length > VIRTIO_CRYPTO_MAX_MSG_SIZE)
901 : : return -ENOMEM;
902 : 0 : desc[idx].addr = op_data_req_phys_addr +
903 : : offsetof(struct virtio_crypto_op_cookie, message);
904 : 0 : desc[idx].len = asym_op->rsa.message.length;
905 : 0 : desc[idx++].flags = flags | VRING_DESC_F_WRITE;
906 : : } else {
907 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("Invalid asym op");
908 : 0 : return -EINVAL;
909 : : }
910 : :
911 : : /* packed vring: last part, status returned */
912 : 0 : desc[idx].addr = op_data_req_phys_addr + req_data_len;
913 : 0 : desc[idx].len = sizeof(struct virtio_crypto_inhdr);
914 : 0 : desc[idx++].flags = txvq->vq_packed.cached_flags | VRING_DESC_F_WRITE;
915 : :
916 : : num_entry = idx;
917 : 0 : txvq->vq_avail_idx += num_entry;
918 [ # # ]: 0 : if (txvq->vq_avail_idx >= txvq->vq_nentries) {
919 : 0 : txvq->vq_avail_idx -= txvq->vq_nentries;
920 : 0 : txvq->vq_packed.cached_flags ^= VRING_PACKED_DESC_F_AVAIL_USED;
921 : : }
922 : :
923 : : /* save the infos to use when receiving packets */
924 : 0 : dxp->crypto_op = (void *)cop;
925 : 0 : dxp->ndescs = needed;
926 : :
927 : 0 : txvq->vq_desc_head_idx = (txvq->vq_desc_head_idx + idx) & (txvq->vq_nentries - 1);
928 [ # # ]: 0 : if (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
929 : 0 : txvq->vq_desc_tail_idx = idx;
930 : 0 : txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
931 : 0 : virtqueue_store_flags_packed(&start_dp[0],
932 : 0 : start_dp[0].flags | flags,
933 [ # # ]: 0 : txvq->hw->weak_barriers);
934 [ # # ]: 0 : virtio_wmb(txvq->hw->weak_barriers);
935 : : return 0;
936 : : }
937 : :
938 : : static inline int
939 : 0 : virtqueue_crypto_asym_enqueue_xmit(
940 : : struct virtqueue *txvq,
941 : : struct rte_crypto_op *cop)
942 : : {
943 [ # # ]: 0 : if (vtpci_with_packed_queue(txvq->hw))
944 : 0 : return virtqueue_crypto_asym_enqueue_xmit_packed(txvq, cop);
945 : : else
946 : 0 : return virtqueue_crypto_asym_enqueue_xmit_split(txvq, cop);
947 : : }
948 : :
949 : : static int
950 : 0 : virtio_crypto_vring_start(struct virtqueue *vq)
951 : : {
952 : 0 : struct virtio_crypto_hw *hw = vq->hw;
953 : 0 : uint8_t *ring_mem = vq->vq_ring_virt_mem;
954 : :
955 : 0 : PMD_INIT_FUNC_TRACE();
956 : :
957 [ # # ]: 0 : if (ring_mem == NULL) {
958 : 0 : VIRTIO_CRYPTO_INIT_LOG_ERR("virtqueue ring memory is NULL");
959 : 0 : return -EINVAL;
960 : : }
961 : :
962 : : /*
963 : : * Set guest physical address of the virtqueue
964 : : * in VIRTIO_PCI_QUEUE_PFN config register of device
965 : : * to share with the backend
966 : : */
967 [ # # ]: 0 : if (VTPCI_OPS(hw)->setup_queue(hw, vq) < 0) {
968 : 0 : VIRTIO_CRYPTO_INIT_LOG_ERR("setup_queue failed");
969 : 0 : return -EINVAL;
970 : : }
971 : :
972 : : return 0;
973 : : }
974 : :
975 : : void
976 : 0 : virtio_crypto_ctrlq_start(struct rte_cryptodev *dev)
977 : : {
978 : 0 : struct virtio_crypto_hw *hw = dev->data->dev_private;
979 : :
980 [ # # ]: 0 : if (hw->cvq) {
981 : : rte_spinlock_init(&hw->cvq->lock);
982 : 0 : virtio_crypto_vring_start(virtcrypto_cq_to_vq(hw->cvq));
983 [ # # ]: 0 : VIRTQUEUE_DUMP(virtcrypto_cq_to_vq(hw->cvq));
984 : : }
985 : 0 : }
986 : :
987 : : void
988 : 0 : virtio_crypto_dataq_start(struct rte_cryptodev *dev)
989 : : {
990 : : /*
991 : : * Start data vrings
992 : : * - Setup vring structure for data queues
993 : : */
994 : : uint16_t i;
995 : :
996 : 0 : PMD_INIT_FUNC_TRACE();
997 : :
998 : : /* Start data vring. */
999 [ # # ]: 0 : for (i = 0; i < dev->data->nb_queue_pairs; i++) {
1000 : 0 : virtio_crypto_vring_start(dev->data->queue_pairs[i]);
1001 [ # # ]: 0 : VIRTQUEUE_DUMP((struct virtqueue *)dev->data->queue_pairs[i]);
1002 : : }
1003 : 0 : }
1004 : :
1005 : : /* vring size of data queue is 1024 */
1006 : : #define VIRTIO_MBUF_BURST_SZ 1024
1007 : :
1008 : : uint16_t
1009 : 0 : virtio_crypto_pkt_rx_burst(void *tx_queue, struct rte_crypto_op **rx_pkts,
1010 : : uint16_t nb_pkts)
1011 : : {
1012 : : struct virtqueue *txvq = tx_queue;
1013 : : uint16_t nb_used, num, nb_rx;
1014 : :
1015 : : virtio_rmb(0);
1016 : :
1017 [ # # ]: 0 : num = (uint16_t)(likely(nb_pkts <= VIRTIO_MBUF_BURST_SZ)
1018 : : ? nb_pkts : VIRTIO_MBUF_BURST_SZ);
1019 [ # # ]: 0 : if (num == 0)
1020 : : return 0;
1021 : :
1022 [ # # ]: 0 : if (likely(vtpci_with_packed_queue(txvq->hw))) {
1023 : 0 : nb_rx = virtqueue_dequeue_burst_rx_packed(txvq, rx_pkts, num);
1024 : : } else {
1025 : 0 : nb_used = VIRTQUEUE_NUSED(txvq);
1026 [ # # ]: 0 : num = (uint16_t)(likely(num <= nb_used) ? num : nb_used);
1027 : 0 : nb_rx = virtqueue_dequeue_burst_rx(txvq, rx_pkts, num);
1028 : : }
1029 : :
1030 : 0 : VIRTIO_CRYPTO_RX_LOG_DBG("used:%d dequeue:%d", nb_rx, num);
1031 : :
1032 : 0 : return nb_rx;
1033 : : }
1034 : :
1035 : : uint16_t
1036 : 0 : virtio_crypto_pkt_tx_burst(void *tx_queue, struct rte_crypto_op **tx_pkts,
1037 : : uint16_t nb_pkts)
1038 : : {
1039 : : struct virtqueue *txvq;
1040 : : uint16_t nb_tx;
1041 : : int error;
1042 : :
1043 [ # # ]: 0 : if (unlikely(nb_pkts < 1))
1044 : : return nb_pkts;
1045 [ # # ]: 0 : if (unlikely(tx_queue == NULL)) {
1046 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("tx_queue is NULL");
1047 : 0 : return 0;
1048 : : }
1049 : : txvq = tx_queue;
1050 : :
1051 : 0 : VIRTIO_CRYPTO_TX_LOG_DBG("%d packets to xmit", nb_pkts);
1052 : :
1053 [ # # ]: 0 : for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
1054 [ # # ]: 0 : if (tx_pkts[nb_tx]->type == RTE_CRYPTO_OP_TYPE_SYMMETRIC) {
1055 : 0 : struct rte_mbuf *txm = tx_pkts[nb_tx]->sym->m_src;
1056 : : /* nb_segs is always 1 at virtio crypto situation */
1057 : 0 : int need = txm->nb_segs - txvq->vq_free_cnt;
1058 : :
1059 : : /*
1060 : : * Positive value indicates it hasn't enough space in vring
1061 : : * descriptors
1062 : : */
1063 [ # # ]: 0 : if (unlikely(need > 0)) {
1064 : : /*
1065 : : * try it again because the receive process may be
1066 : : * free some space
1067 : : */
1068 : : need = txm->nb_segs - txvq->vq_free_cnt;
1069 : : if (unlikely(need > 0)) {
1070 : 0 : VIRTIO_CRYPTO_TX_LOG_DBG("No free tx "
1071 : : "descriptors to transmit");
1072 : 0 : break;
1073 : : }
1074 : : }
1075 : :
1076 : : /* Enqueue Packet buffers */
1077 : 0 : error = virtqueue_crypto_sym_enqueue_xmit(txvq, tx_pkts[nb_tx]);
1078 [ # # ]: 0 : } else if (tx_pkts[nb_tx]->type == RTE_CRYPTO_OP_TYPE_ASYMMETRIC) {
1079 : : /* Enqueue Packet buffers */
1080 : 0 : error = virtqueue_crypto_asym_enqueue_xmit(txvq, tx_pkts[nb_tx]);
1081 : : } else {
1082 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR("invalid crypto op type %u",
1083 : : tx_pkts[nb_tx]->type);
1084 : 0 : txvq->packets_sent_failed++;
1085 : 0 : continue;
1086 : : }
1087 : :
1088 [ # # ]: 0 : if (unlikely(error)) {
1089 [ # # ]: 0 : if (error == ENOSPC)
1090 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR(
1091 : : "virtqueue_enqueue Free count = 0");
1092 [ # # ]: 0 : else if (error == EMSGSIZE)
1093 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR(
1094 : : "virtqueue_enqueue Free count < 1");
1095 : : else
1096 : 0 : VIRTIO_CRYPTO_TX_LOG_ERR(
1097 : : "virtqueue_enqueue error: %d", error);
1098 : 0 : txvq->packets_sent_failed++;
1099 : 0 : break;
1100 : : }
1101 : :
1102 : 0 : txvq->packets_sent_total++;
1103 : : }
1104 : :
1105 [ # # ]: 0 : if (likely(nb_tx)) {
1106 [ # # ]: 0 : if (vtpci_with_packed_queue(txvq->hw)) {
1107 : : virtqueue_notify(txvq);
1108 : 0 : VIRTIO_CRYPTO_TX_LOG_DBG("Notified backend after xmit");
1109 : 0 : return nb_tx;
1110 : : }
1111 : :
1112 : : vq_update_avail_idx(txvq);
1113 : :
1114 [ # # ]: 0 : if (unlikely(virtqueue_kick_prepare(txvq))) {
1115 : : virtqueue_notify(txvq);
1116 : 0 : VIRTIO_CRYPTO_TX_LOG_DBG("Notified backend after xmit");
1117 : : }
1118 : : }
1119 : :
1120 : : return nb_tx;
1121 : : }
|