crypto: caam - fix missing dma unmap on error path

If dma mapping for dma_addr_out fails, the descriptor memory is freed
but the previous dma mapping for dma_addr_in remains.
This patch resolves the missing dma unmap and groups resource
allocations at function start.

Cc: <stable@vger.kernel.org> # 3.13+
Signed-off-by: Cristian Stoica <cristian.stoica@freescale.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
Cristian Stoica 2014-10-30 14:40:22 +02:00 committed by Herbert Xu
parent 09adc8789c
commit 738459e3f8
1 changed files with 14 additions and 15 deletions

View File

@ -48,23 +48,29 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
u32 *desc; u32 *desc;
struct split_key_result result; struct split_key_result result;
dma_addr_t dma_addr_in, dma_addr_out; dma_addr_t dma_addr_in, dma_addr_out;
int ret = 0; int ret = -ENOMEM;
desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA); desc = kmalloc(CAAM_CMD_SZ * 6 + CAAM_PTR_SZ * 2, GFP_KERNEL | GFP_DMA);
if (!desc) { if (!desc) {
dev_err(jrdev, "unable to allocate key input memory\n"); dev_err(jrdev, "unable to allocate key input memory\n");
return -ENOMEM; return ret;
} }
init_job_desc(desc, 0);
dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen, dma_addr_in = dma_map_single(jrdev, (void *)key_in, keylen,
DMA_TO_DEVICE); DMA_TO_DEVICE);
if (dma_mapping_error(jrdev, dma_addr_in)) { if (dma_mapping_error(jrdev, dma_addr_in)) {
dev_err(jrdev, "unable to map key input memory\n"); dev_err(jrdev, "unable to map key input memory\n");
kfree(desc); goto out_free;
return -ENOMEM;
} }
dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len,
DMA_FROM_DEVICE);
if (dma_mapping_error(jrdev, dma_addr_out)) {
dev_err(jrdev, "unable to map key output memory\n");
goto out_unmap_in;
}
init_job_desc(desc, 0);
append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG); append_key(desc, dma_addr_in, keylen, CLASS_2 | KEY_DEST_CLASS_REG);
/* Sets MDHA up into an HMAC-INIT */ /* Sets MDHA up into an HMAC-INIT */
@ -81,13 +87,6 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
* FIFO_STORE with the explicit split-key content store * FIFO_STORE with the explicit split-key content store
* (0x26 output type) * (0x26 output type)
*/ */
dma_addr_out = dma_map_single(jrdev, key_out, split_key_pad_len,
DMA_FROM_DEVICE);
if (dma_mapping_error(jrdev, dma_addr_out)) {
dev_err(jrdev, "unable to map key output memory\n");
kfree(desc);
return -ENOMEM;
}
append_fifo_store(desc, dma_addr_out, split_key_len, append_fifo_store(desc, dma_addr_out, split_key_len,
LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK); LDST_CLASS_2_CCB | FIFOST_TYPE_SPLIT_KEK);
@ -115,10 +114,10 @@ int gen_split_key(struct device *jrdev, u8 *key_out, int split_key_len,
dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len, dma_unmap_single(jrdev, dma_addr_out, split_key_pad_len,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
out_unmap_in:
dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE); dma_unmap_single(jrdev, dma_addr_in, keylen, DMA_TO_DEVICE);
out_free:
kfree(desc); kfree(desc);
return ret; return ret;
} }
EXPORT_SYMBOL(gen_split_key); EXPORT_SYMBOL(gen_split_key);