Commit 7a76d89232f20411f32e7a79ccc1e2f95e9f826b
Exists in
master
and in
7 other branches
Merge git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6: crypto: talitos - sparse fix crypto: talitos - Stop leaking memory in error path crypto: talitos - Fix GFP flag usage crypto: talitos - Preempt overflow interrupts crypto: talitos - Correct dst != src case handling crypto: talitos - Remove calls to of_node_put
Showing 1 changed file Side-by-side Diff
drivers/crypto/talitos.c
... | ... | @@ -99,6 +99,9 @@ |
99 | 99 | /* next channel to be assigned next incoming descriptor */ |
100 | 100 | atomic_t last_chan; |
101 | 101 | |
102 | + /* per-channel number of requests pending in channel h/w fifo */ | |
103 | + atomic_t *submit_count; | |
104 | + | |
102 | 105 | /* per-channel request fifo */ |
103 | 106 | struct talitos_request **fifo; |
104 | 107 | |
105 | 108 | |
... | ... | @@ -263,15 +266,15 @@ |
263 | 266 | |
264 | 267 | spin_lock_irqsave(&priv->head_lock[ch], flags); |
265 | 268 | |
266 | - head = priv->head[ch]; | |
267 | - request = &priv->fifo[ch][head]; | |
268 | - | |
269 | - if (request->desc) { | |
270 | - /* request queue is full */ | |
269 | + if (!atomic_inc_not_zero(&priv->submit_count[ch])) { | |
270 | + /* h/w fifo is full */ | |
271 | 271 | spin_unlock_irqrestore(&priv->head_lock[ch], flags); |
272 | 272 | return -EAGAIN; |
273 | 273 | } |
274 | 274 | |
275 | + head = priv->head[ch]; | |
276 | + request = &priv->fifo[ch][head]; | |
277 | + | |
275 | 278 | /* map descriptor and save caller data */ |
276 | 279 | request->dma_desc = dma_map_single(dev, desc, sizeof(*desc), |
277 | 280 | DMA_BIDIRECTIONAL); |
... | ... | @@ -335,6 +338,9 @@ |
335 | 338 | priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1); |
336 | 339 | |
337 | 340 | spin_unlock_irqrestore(&priv->tail_lock[ch], flags); |
341 | + | |
342 | + atomic_dec(&priv->submit_count[ch]); | |
343 | + | |
338 | 344 | saved_req.callback(dev, saved_req.desc, saved_req.context, |
339 | 345 | status); |
340 | 346 | /* channel may resume processing in single desc error case */ |
... | ... | @@ -842,7 +848,7 @@ |
842 | 848 | |
843 | 849 | /* adjust (decrease) last one (or two) entry's len to cryptlen */ |
844 | 850 | link_tbl_ptr--; |
845 | - while (link_tbl_ptr->len <= (-cryptlen)) { | |
851 | + while (be16_to_cpu(link_tbl_ptr->len) <= (-cryptlen)) { | |
846 | 852 | /* Empty this entry, and move to previous one */ |
847 | 853 | cryptlen += be16_to_cpu(link_tbl_ptr->len); |
848 | 854 | link_tbl_ptr->len = 0; |
... | ... | @@ -874,7 +880,7 @@ |
874 | 880 | unsigned int cryptlen = areq->cryptlen; |
875 | 881 | unsigned int authsize = ctx->authsize; |
876 | 882 | unsigned int ivsize; |
877 | - int sg_count; | |
883 | + int sg_count, ret; | |
878 | 884 | |
879 | 885 | /* hmac key */ |
880 | 886 | map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key, |
... | ... | @@ -978,7 +984,12 @@ |
978 | 984 | map_single_talitos_ptr(dev, &desc->ptr[6], ivsize, ctx->iv, 0, |
979 | 985 | DMA_FROM_DEVICE); |
980 | 986 | |
981 | - return talitos_submit(dev, desc, callback, areq); | |
987 | + ret = talitos_submit(dev, desc, callback, areq); | |
988 | + if (ret != -EINPROGRESS) { | |
989 | + ipsec_esp_unmap(dev, edesc, areq); | |
990 | + kfree(edesc); | |
991 | + } | |
992 | + return ret; | |
982 | 993 | } |
983 | 994 | |
984 | 995 | |
... | ... | @@ -1009,6 +1020,8 @@ |
1009 | 1020 | struct talitos_ctx *ctx = crypto_aead_ctx(authenc); |
1010 | 1021 | struct ipsec_esp_edesc *edesc; |
1011 | 1022 | int src_nents, dst_nents, alloc_len, dma_len; |
1023 | + gfp_t flags = areq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : | |
1024 | + GFP_ATOMIC; | |
1012 | 1025 | |
1013 | 1026 | if (areq->cryptlen + ctx->authsize > TALITOS_MAX_DATA_LEN) { |
1014 | 1027 | dev_err(ctx->dev, "cryptlen exceeds h/w max limit\n"); |
... | ... | @@ -1022,7 +1035,7 @@ |
1022 | 1035 | dst_nents = src_nents; |
1023 | 1036 | } else { |
1024 | 1037 | dst_nents = sg_count(areq->dst, areq->cryptlen + ctx->authsize); |
1025 | - dst_nents = (dst_nents == 1) ? 0 : src_nents; | |
1038 | + dst_nents = (dst_nents == 1) ? 0 : dst_nents; | |
1026 | 1039 | } |
1027 | 1040 | |
1028 | 1041 | /* |
... | ... | @@ -1040,7 +1053,7 @@ |
1040 | 1053 | alloc_len += icv_stashing ? ctx->authsize : 0; |
1041 | 1054 | } |
1042 | 1055 | |
1043 | - edesc = kmalloc(alloc_len, GFP_DMA); | |
1056 | + edesc = kmalloc(alloc_len, GFP_DMA | flags); | |
1044 | 1057 | if (!edesc) { |
1045 | 1058 | dev_err(ctx->dev, "could not allocate edescriptor\n"); |
1046 | 1059 | return ERR_PTR(-ENOMEM); |
... | ... | @@ -1337,6 +1350,7 @@ |
1337 | 1350 | if (hw_supports(dev, DESC_HDR_SEL0_RNG)) |
1338 | 1351 | talitos_unregister_rng(dev); |
1339 | 1352 | |
1353 | + kfree(priv->submit_count); | |
1340 | 1354 | kfree(priv->tail); |
1341 | 1355 | kfree(priv->head); |
1342 | 1356 | |
... | ... | @@ -1466,9 +1480,6 @@ |
1466 | 1480 | goto err_out; |
1467 | 1481 | } |
1468 | 1482 | |
1469 | - of_node_put(np); | |
1470 | - np = NULL; | |
1471 | - | |
1472 | 1483 | priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, |
1473 | 1484 | GFP_KERNEL); |
1474 | 1485 | priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels, |
... | ... | @@ -1504,6 +1515,16 @@ |
1504 | 1515 | } |
1505 | 1516 | } |
1506 | 1517 | |
1518 | + priv->submit_count = kmalloc(sizeof(atomic_t) * priv->num_channels, | |
1519 | + GFP_KERNEL); | |
1520 | + if (!priv->submit_count) { | |
1521 | + dev_err(dev, "failed to allocate fifo submit count space\n"); | |
1522 | + err = -ENOMEM; | |
1523 | + goto err_out; | |
1524 | + } | |
1525 | + for (i = 0; i < priv->num_channels; i++) | |
1526 | + atomic_set(&priv->submit_count[i], -priv->chfifo_len); | |
1527 | + | |
1507 | 1528 | priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); |
1508 | 1529 | priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL); |
1509 | 1530 | if (!priv->head || !priv->tail) { |
... | ... | @@ -1559,8 +1580,6 @@ |
1559 | 1580 | |
1560 | 1581 | err_out: |
1561 | 1582 | talitos_remove(ofdev); |
1562 | - if (np) | |
1563 | - of_node_put(np); | |
1564 | 1583 | |
1565 | 1584 | return err; |
1566 | 1585 | } |