2014-07-11 12:35:48

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 00/10] CAAM - DMA API fixes

Hi Herbert,

Enabling DMA-API debugging reveals quite a lot of problems in CAAM module.
Patches below fix them - tested on P3041DS QorIQ platform. Please apply.

(I haven't seen any crashes so far, thus patches are based on cryptodev -
not on crypto - and I'm not queueing them to -stable.)

Thanks,
Horia

Horia Geanta (10):
crypto: testmgr - avoid DMA mapping from text, rodata, stack
crypto: caam - set coherent_dma_mask
crypto: caam - fix typo in dma_mapping_error
crypto: caam - fix "failed to check map error" DMA warnings
crypto: caam - fix DMA unmapping error in hash_digest_key
crypto: caam - fix DMA direction mismatch in ahash_done_ctx_dst
crypto: caam - fix DMA direction mismatch in ahash_done_ctx_src
crypto: caam - fix uninitialized S/G table size in ahash_digest
crypto: caam - fix uninitialized edesc->dst_dma field
crypto: caam - fix uninitialized state->buf_dma field

crypto/testmgr.c | 57 +++++++++++++++++---
crypto/testmgr.h | 2 +-
drivers/crypto/caam/caamalg.c | 36 +++++++++++--
drivers/crypto/caam/caamhash.c | 118 ++++++++++++++++++++++++++++++++++-------
drivers/crypto/caam/caamrng.c | 51 ++++++++++++++----
drivers/crypto/caam/ctrl.c | 6 +--
drivers/crypto/caam/jr.c | 6 +--
7 files changed, 228 insertions(+), 48 deletions(-)

--
1.8.3.1


2014-07-11 12:36:03

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 01/10] crypto: testmgr - avoid DMA mapping from text, rodata, stack

With DMA_API_DEBUG set, following warnings are emitted
(tested on CAAM accelerator):
DMA-API: device driver maps memory from kernel text or rodata
DMA-API: device driver maps memory from stack
and the culprits are:
-key in __test_aead and __test_hash
-result in __test_hash

Signed-off-by: Horia Geanta <[email protected]>
---
There was a previous cryptodev-2.6 commit with similar updates:
9bac019dad8098a77cce555d929f678e22111783
("crypto: testmgr - Fix DMA-API warning")

This patch addresses only warnings seen in CAAM module.
In other words, warnings might still be encountered in tcrypt, depending on
crypto accelerator being used.

crypto/testmgr.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------
crypto/testmgr.h | 2 +-
2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0f90612a00b9..2d3aa96babff 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -198,13 +198,20 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
unsigned int i, j, k, temp;
struct scatterlist sg[8];
- char result[64];
+ char *result = NULL;
+ char *key = NULL;
struct ahash_request *req;
struct tcrypt_result tresult;
void *hash_buff;
char *xbuf[XBUFSIZE];
int ret = -ENOMEM;

+ result = kmalloc(64, GFP_KERNEL);
+ if (!result)
+ return ret;
+ key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
+ if (!key)
+ goto out_nobuf;
if (testmgr_alloc_buf(xbuf))
goto out_nobuf;

@@ -239,8 +246,14 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,

if (template[i].ksize) {
crypto_ahash_clear_flags(tfm, ~0);
- ret = crypto_ahash_setkey(tfm, template[i].key,
- template[i].ksize);
+ if (template[i].ksize > MAX_KEYLEN) {
+ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
+ j, algo, template[i].ksize, MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].ksize);
+ ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
if (ret) {
printk(KERN_ERR "alg: hash: setkey failed on "
"test %d for %s: ret=%d\n", j, algo,
@@ -319,8 +332,16 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
}

if (template[i].ksize) {
+ if (template[i].ksize > MAX_KEYLEN) {
+ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
+ j, algo, template[i].ksize,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
crypto_ahash_clear_flags(tfm, ~0);
- ret = crypto_ahash_setkey(tfm, template[i].key,
+ memcpy(key, template[i].key, template[i].ksize);
+ ret = crypto_ahash_setkey(tfm, key,
template[i].ksize);

if (ret) {
@@ -372,6 +393,8 @@ out:
out_noreq:
testmgr_free_buf(xbuf);
out_nobuf:
+ kfree(key);
+ kfree(result);
return ret;
}

@@ -410,7 +433,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
unsigned int i, j, k, n, temp;
int ret = -ENOMEM;
char *q;
- char *key;
+ char *key = NULL;
struct aead_request *req;
struct scatterlist *sg;
struct scatterlist *asg;
@@ -421,7 +444,7 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
void *input;
void *output;
void *assoc;
- char *iv;
+ char *iv = NULL;
char *xbuf[XBUFSIZE];
char *xoutbuf[XBUFSIZE];
char *axbuf[XBUFSIZE];
@@ -429,6 +452,9 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
if (!iv)
return ret;
+ key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
+ if (!key)
+ goto out_noxbuf;
if (testmgr_alloc_buf(xbuf))
goto out_noxbuf;
if (testmgr_alloc_buf(axbuf))
@@ -493,7 +519,14 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);

- key = template[i].key;
+ if (template[i].klen > MAX_KEYLEN) {
+ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+ d, j, algo, template[i].klen,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].klen);

ret = crypto_aead_setkey(tfm, key,
template[i].klen);
@@ -594,7 +627,14 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
if (template[i].wk)
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = template[i].key;
+ if (template[i].klen > MAX_KEYLEN) {
+ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+ d, j, algo, template[i].klen,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].klen);

ret = crypto_aead_setkey(tfm, key, template[i].klen);
if (!ret == template[i].fail) {
@@ -776,6 +816,7 @@ out_nooutbuf:
out_noaxbuf:
testmgr_free_buf(xbuf);
out_noxbuf:
+ kfree(key);
kfree(iv);
return ret;
}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 4bb607189b8d..46df9e88bbf3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -32,7 +32,7 @@
#define MAX_DIGEST_SIZE 64
#define MAX_TAP 8

-#define MAX_KEYLEN 56
+#define MAX_KEYLEN 160
#define MAX_IVLEN 32

struct hash_testvec {
--
1.8.3.1

2014-07-11 12:36:09

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 04/10] crypto: caam - fix "failed to check map error" DMA warnings

Use dma_mapping_error for every dma_map_single / dma_map_page.

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamalg.c | 34 +++++++++++--
drivers/crypto/caam/caamhash.c | 106 ++++++++++++++++++++++++++++++++++-------
drivers/crypto/caam/caamrng.c | 51 ++++++++++++++++----
3 files changed, 163 insertions(+), 28 deletions(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 31f2e10b5102..694df4685920 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -1313,8 +1313,13 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
DMA_FROM_DEVICE, dst_chained);
}

- /* Check if data are contiguous */
iv_dma = dma_map_single(jrdev, req->iv, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Check if data are contiguous */
if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
iv_dma || src_nents || iv_dma + ivsize !=
sg_dma_address(req->src)) {
@@ -1369,6 +1374,10 @@ static struct aead_edesc *aead_edesc_alloc(struct aead_request *req,
}
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }

return edesc;
}
@@ -1494,8 +1503,13 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
DMA_FROM_DEVICE, dst_chained);
}

- /* Check if data are contiguous */
iv_dma = dma_map_single(jrdev, greq->giv, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ /* Check if data are contiguous */
if (assoc_nents || sg_dma_address(req->assoc) + req->assoclen !=
iv_dma || src_nents || iv_dma + ivsize != sg_dma_address(req->src))
contig &= ~GIV_SRC_CONTIG;
@@ -1559,6 +1573,10 @@ static struct aead_edesc *aead_giv_edesc_alloc(struct aead_givcrypt_request
}
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }

return edesc;
}
@@ -1650,11 +1668,16 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request
DMA_FROM_DEVICE, dst_chained);
}

+ iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, iv_dma)) {
+ dev_err(jrdev, "unable to map IV\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
/*
* Check if iv can be contiguous with source and destination.
* If so, include it. If not, create scatterlist.
*/
- iv_dma = dma_map_single(jrdev, req->info, ivsize, DMA_TO_DEVICE);
if (!src_nents && iv_dma + ivsize == sg_dma_address(req->src))
iv_contig = true;
else
@@ -1693,6 +1716,11 @@ static struct ablkcipher_edesc *ablkcipher_edesc_alloc(struct ablkcipher_request

edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
edesc->iv_dma = iv_dma;

#ifdef DEBUG
diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 7754df4c3df1..39f7a933c8fa 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -137,13 +137,20 @@ struct caam_hash_state {
/* Common job descriptor seq in/out ptr routines */

/* Map state->caam_ctx, and append seq_out_ptr command that points to it */
-static inline void map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
- struct caam_hash_state *state,
- int ctx_len)
+static inline int map_seq_out_ptr_ctx(u32 *desc, struct device *jrdev,
+ struct caam_hash_state *state,
+ int ctx_len)
{
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx,
ctx_len, DMA_FROM_DEVICE);
+ if (dma_mapping_error(jrdev, state->ctx_dma)) {
+ dev_err(jrdev, "unable to map ctx\n");
+ return -ENOMEM;
+ }
+
append_seq_out_ptr(desc, state->ctx_dma, ctx_len, 0);
+
+ return 0;
}

/* Map req->result, and append seq_out_ptr command that points to it */
@@ -201,14 +208,19 @@ try_buf_map_to_sec4_sg(struct device *jrdev, struct sec4_sg_entry *sec4_sg,
}

/* Map state->caam_ctx, and add it to link table */
-static inline void ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
- struct caam_hash_state *state,
- int ctx_len,
- struct sec4_sg_entry *sec4_sg,
- u32 flag)
+static inline int ctx_map_to_sec4_sg(u32 *desc, struct device *jrdev,
+ struct caam_hash_state *state, int ctx_len,
+ struct sec4_sg_entry *sec4_sg, u32 flag)
{
state->ctx_dma = dma_map_single(jrdev, state->caam_ctx, ctx_len, flag);
+ if (dma_mapping_error(jrdev, state->ctx_dma)) {
+ dev_err(jrdev, "unable to map ctx\n");
+ return -ENOMEM;
+ }
+
dma_to_sec4_sg_one(sec4_sg, state->ctx_dma, ctx_len, 0);
+
+ return 0;
}

/* Common shared descriptor commands */
@@ -809,8 +821,10 @@ static int ahash_update_ctx(struct ahash_request *req)
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;

- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
- edesc->sec4_sg, DMA_BIDIRECTIONAL);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_BIDIRECTIONAL);
+ if (ret)
+ return ret;

state->buf_dma = try_buf_map_to_sec4_sg(jrdev,
edesc->sec4_sg + 1,
@@ -839,6 +853,10 @@ static int ahash_update_ctx(struct ahash_request *req)
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes,
DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len +
to_hash, LDST_SGF);
@@ -914,8 +932,10 @@ static int ahash_final_ctx(struct ahash_request *req)
DESC_JOB_IO_LEN;
edesc->src_nents = 0;

- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg,
- DMA_TO_DEVICE);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_TO_DEVICE);
+ if (ret)
+ return ret;

state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
buf, state->buf_dma, buflen,
@@ -924,12 +944,20 @@ static int ahash_final_ctx(struct ahash_request *req)

edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len + buflen,
LDST_SGF);

edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -992,8 +1020,10 @@ static int ahash_finup_ctx(struct ahash_request *req)
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;

- ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len, edesc->sec4_sg,
- DMA_TO_DEVICE);
+ ret = ctx_map_to_sec4_sg(desc, jrdev, state, ctx->ctx_len,
+ edesc->sec4_sg, DMA_TO_DEVICE);
+ if (ret)
+ return ret;

state->buf_dma = try_buf_map_to_sec4_sg(jrdev, edesc->sec4_sg + 1,
buf, state->buf_dma, buflen,
@@ -1004,12 +1034,20 @@ static int ahash_finup_ctx(struct ahash_request *req)

edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, edesc->sec4_sg_dma, ctx->ctx_len +
buflen + req->nbytes, LDST_SGF);

edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1070,6 +1108,10 @@ static int ahash_digest(struct ahash_request *req)
sg_to_sec4_sg_last(req->src, src_nents, edesc->sec4_sg, 0);
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
src_dma = edesc->sec4_sg_dma;
options = LDST_SGF;
} else {
@@ -1080,6 +1122,10 @@ static int ahash_digest(struct ahash_request *req)

edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1128,11 +1174,19 @@ static int ahash_final_no_ctx(struct ahash_request *req)
init_job_desc_shared(desc, ptr, sh_len, HDR_SHARE_DEFER | HDR_REVERSE);

state->buf_dma = dma_map_single(jrdev, buf, buflen, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, state->buf_dma)) {
+ dev_err(jrdev, "unable to map src\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, state->buf_dma, buflen, 0);

edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }
edesc->src_nents = 0;

#ifdef DEBUG
@@ -1219,10 +1273,16 @@ static int ahash_update_no_ctx(struct ahash_request *req)
edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes,
DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, edesc->sec4_sg_dma, to_hash, LDST_SGF);

- map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ if (ret)
+ return ret;

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1311,12 +1371,20 @@ static int ahash_finup_no_ctx(struct ahash_request *req)

edesc->sec4_sg_dma = dma_map_single(jrdev, edesc->sec4_sg,
sec4_sg_bytes, DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }

append_seq_in_ptr(desc, edesc->sec4_sg_dma, buflen +
req->nbytes, LDST_SGF);

edesc->dst_dma = map_seq_out_ptr_result(desc, jrdev, req->result,
digestsize);
+ if (dma_mapping_error(jrdev, edesc->dst_dma)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
@@ -1393,6 +1461,10 @@ static int ahash_update_first(struct ahash_request *req)
edesc->sec4_sg,
sec4_sg_bytes,
DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, edesc->sec4_sg_dma)) {
+ dev_err(jrdev, "unable to map S/G table\n");
+ return -ENOMEM;
+ }
src_dma = edesc->sec4_sg_dma;
options = LDST_SGF;
} else {
@@ -1410,7 +1482,9 @@ static int ahash_update_first(struct ahash_request *req)

append_seq_in_ptr(desc, src_dma, to_hash, options);

- map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ ret = map_seq_out_ptr_ctx(desc, jrdev, state, ctx->ctx_len);
+ if (ret)
+ return ret;

#ifdef DEBUG
print_hex_dump(KERN_ERR, "jobdesc@"__stringify(__LINE__)": ",
diff --git a/drivers/crypto/caam/caamrng.c b/drivers/crypto/caam/caamrng.c
index a4afa8a8ef02..ae31e555793c 100644
--- a/drivers/crypto/caam/caamrng.c
+++ b/drivers/crypto/caam/caamrng.c
@@ -185,7 +185,7 @@ static int caam_read(struct hwrng *rng, void *data, size_t max, bool wait)
max - copied_idx, false);
}

-static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx)
+static inline int rng_create_sh_desc(struct caam_rng_ctx *ctx)
{
struct device *jrdev = ctx->jrdev;
u32 *desc = ctx->sh_desc;
@@ -203,13 +203,18 @@ static inline void rng_create_sh_desc(struct caam_rng_ctx *ctx)

ctx->sh_desc_dma = dma_map_single(jrdev, desc, desc_bytes(desc),
DMA_TO_DEVICE);
+ if (dma_mapping_error(jrdev, ctx->sh_desc_dma)) {
+ dev_err(jrdev, "unable to map shared descriptor\n");
+ return -ENOMEM;
+ }
#ifdef DEBUG
print_hex_dump(KERN_ERR, "rng shdesc@: ", DUMP_PREFIX_ADDRESS, 16, 4,
desc, desc_bytes(desc), 1);
#endif
+ return 0;
}

-static inline void rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
+static inline int rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
{
struct device *jrdev = ctx->jrdev;
struct buf_data *bd = &ctx->bufs[buf_id];
@@ -220,12 +225,17 @@ static inline void rng_create_job_desc(struct caam_rng_ctx *ctx, int buf_id)
HDR_REVERSE);

bd->addr = dma_map_single(jrdev, bd->buf, RN_BUF_SIZE, DMA_FROM_DEVICE);
+ if (dma_mapping_error(jrdev, bd->addr)) {
+ dev_err(jrdev, "unable to map dst\n");
+ return -ENOMEM;
+ }

append_seq_out_ptr_intlen(desc, bd->addr, RN_BUF_SIZE, 0);
#ifdef DEBUG
print_hex_dump(KERN_ERR, "rng job desc@: ", DUMP_PREFIX_ADDRESS, 16, 4,
desc, desc_bytes(desc), 1);
#endif
+ return 0;
}

static void caam_cleanup(struct hwrng *rng)
@@ -242,24 +252,44 @@ static void caam_cleanup(struct hwrng *rng)
rng_unmap_ctx(rng_ctx);
}

-static void caam_init_buf(struct caam_rng_ctx *ctx, int buf_id)
+static int caam_init_buf(struct caam_rng_ctx *ctx, int buf_id)
{
struct buf_data *bd = &ctx->bufs[buf_id];
+ int err;
+
+ err = rng_create_job_desc(ctx, buf_id);
+ if (err)
+ return err;

- rng_create_job_desc(ctx, buf_id);
atomic_set(&bd->empty, BUF_EMPTY);
submit_job(ctx, buf_id == ctx->current_buf);
wait_for_completion(&bd->filled);
+
+ return 0;
}

-static void caam_init_rng(struct caam_rng_ctx *ctx, struct device *jrdev)
+static int caam_init_rng(struct caam_rng_ctx *ctx, struct device *jrdev)
{
+ int err;
+
ctx->jrdev = jrdev;
- rng_create_sh_desc(ctx);
+
+ err = rng_create_sh_desc(ctx);
+ if (err)
+ return err;
+
ctx->current_buf = 0;
ctx->cur_buf_idx = 0;
- caam_init_buf(ctx, 0);
- caam_init_buf(ctx, 1);
+
+ err = caam_init_buf(ctx, 0);
+ if (err)
+ return err;
+
+ err = caam_init_buf(ctx, 1);
+ if (err)
+ return err;
+
+ return 0;
}

static struct hwrng caam_rng = {
@@ -282,6 +312,7 @@ static int __init caam_rng_init(void)
struct platform_device *pdev;
struct device *ctrldev;
void *priv;
+ int err;

dev_node = of_find_compatible_node(NULL, NULL, "fsl,sec-v4.0");
if (!dev_node) {
@@ -315,7 +346,9 @@ static int __init caam_rng_init(void)
rng_ctx = kmalloc(sizeof(struct caam_rng_ctx), GFP_DMA);
if (!rng_ctx)
return -ENOMEM;
- caam_init_rng(rng_ctx, dev);
+ err = caam_init_rng(rng_ctx, dev);
+ if (err)
+ return err;

dev_info(dev, "registering rng-caam\n");
return hwrng_register(&caam_rng);
--
1.8.3.1

2014-07-11 12:36:14

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 05/10] crypto: caam - fix DMA unmapping error in hash_digest_key

Key being hashed is unmapped using the digest size instead of
initial length:

caam_jr ffe301000.jr: DMA-API: device driver frees DMA memory with different size [device address=0x000000002eeedac0] [map size=80 bytes] [unmap size=20 bytes]
------------[ cut here ]------------
WARNING: at lib/dma-debug.c:1090
Modules linked in: caamhash(+)
CPU: 0 PID: 1327 Comm: cryptomgr_test Not tainted 3.16.0-rc1 #23
task: eebda5d0 ti: ee26a000 task.ti: ee26a000
NIP: c0288790 LR: c0288790 CTR: c02d7020
REGS: ee26ba30 TRAP: 0700 Not tainted (3.16.0-rc1)
MSR: 00021002 <CE,ME> CR: 44022082 XER: 00000000

GPR00: c0288790 ee26bae0 eebda5d0 0000009f c1de3478 c1de382c 00000000 00021002
GPR08: 00000007 00000000 01660000 0000012f 82022082 00000000 c07a1900 eeda29c0
GPR16: 00000000 c61deea0 000c49a0 00000260 c07e1e10 c0da1180 00029002 c0d9ef08
GPR24: c07a0000 c07a4acc ee26bb38 ee2765c0 00000014 ee130210 00000000 00000014
NIP [c0288790] check_unmap+0x640/0xab0
LR [c0288790] check_unmap+0x640/0xab0
Call Trace:
[ee26bae0] [c0288790] check_unmap+0x640/0xab0 (unreliable)
[ee26bb30] [c0288c78] debug_dma_unmap_page+0x78/0x90
[ee26bbb0] [f929c3d4] ahash_setkey+0x374/0x720 [caamhash]
[ee26bc30] [c022fec8] __test_hash+0x228/0x6c0
[ee26bde0] [c0230388] test_hash+0x28/0xb0
[ee26be00] [c0230458] alg_test_hash+0x48/0xc0
[ee26be20] [c022fa94] alg_test+0x114/0x2e0
[ee26bea0] [c022cd1c] cryptomgr_test+0x4c/0x60
[ee26beb0] [c00497a4] kthread+0xc4/0xe0
[ee26bf40] [c000f2fc] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
41de03e8 83da0020 3c60c06d 83fa0024 3863f520 813b0020 815b0024 80fa0018
811a001c 93c10008 93e1000c 4830cf6d <0fe00000> 3c60c06d 3863f0f4 4830cf5d
---[ end trace db1fae088c75c26c ]---
Mapped at:
[<f929c15c>] ahash_setkey+0xfc/0x720 [caamhash]
[<c022fec8>] __test_hash+0x228/0x6c0
[<c0230388>] test_hash+0x28/0xb0
[<c0230458>] alg_test_hash+0x48/0xc0
[<c022fa94>] alg_test+0x114/0x2e0

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 39f7a933c8fa..9ee4e0478220 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -499,11 +499,11 @@ static int hash_digest_key(struct caam_hash_ctx *ctx, const u8 *key_in,
digestsize, 1);
#endif
}
- *keylen = digestsize;
-
dma_unmap_single(jrdev, src_dma, *keylen, DMA_TO_DEVICE);
dma_unmap_single(jrdev, dst_dma, digestsize, DMA_FROM_DEVICE);

+ *keylen = digestsize;
+
kfree(desc);

return ret;
--
1.8.3.1

2014-07-11 12:36:14

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 02/10] crypto: caam - set coherent_dma_mask

Replace dma_set_mask with dma_set_mask_and_coherent, since both
streaming and coherent DMA mappings are being used.

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/ctrl.c | 6 +++---
drivers/crypto/caam/jr.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c
index c6e9d3b2d502..cedb56500b61 100644
--- a/drivers/crypto/caam/ctrl.c
+++ b/drivers/crypto/caam/ctrl.c
@@ -453,11 +453,11 @@ static int caam_probe(struct platform_device *pdev)

if (sizeof(dma_addr_t) == sizeof(u64))
if (of_device_is_compatible(nprop, "fsl,sec-v5.0"))
- dma_set_mask(dev, DMA_BIT_MASK(40));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(40));
else
- dma_set_mask(dev, DMA_BIT_MASK(36));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(36));
else
- dma_set_mask(dev, DMA_BIT_MASK(32));
+ dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));

/*
* Detect and enable JobRs
diff --git a/drivers/crypto/caam/jr.c b/drivers/crypto/caam/jr.c
index 1d80bd3636c5..50cd1b9af2ba 100644
--- a/drivers/crypto/caam/jr.c
+++ b/drivers/crypto/caam/jr.c
@@ -476,11 +476,11 @@ static int caam_jr_probe(struct platform_device *pdev)

if (sizeof(dma_addr_t) == sizeof(u64))
if (of_device_is_compatible(nprop, "fsl,sec-v5.0-job-ring"))
- dma_set_mask(jrdev, DMA_BIT_MASK(40));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(40));
else
- dma_set_mask(jrdev, DMA_BIT_MASK(36));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(36));
else
- dma_set_mask(jrdev, DMA_BIT_MASK(32));
+ dma_set_mask_and_coherent(jrdev, DMA_BIT_MASK(32));

/* Identify the interrupt */
jrpriv->irq = irq_of_parse_and_map(nprop, 0);
--
1.8.3.1

2014-07-11 12:36:19

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 07/10] crypto: caam - fix DMA direction mismatch in ahash_done_ctx_src

caam_jr ffe301000.jr: DMA-API: device driver frees DMA memory with different direction [device address=0x0000000006271dac] [size=28 bytes] [mapped with DMA_TO_DEVICE] [unmapped with DMA_FROM_DEVICE]
------------[ cut here ]------------
WARNING: at lib/dma-debug.c:1131
Modules linked in: caamhash(+) [last unloaded: caamhash]
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.16.0-rc1 #23
task: c0789380 ti: effd2000 task.ti: c07d6000
NIP: c02885cc LR: c02885cc CTR: c02d7020
REGS: effd3d50 TRAP: 0700 Tainted: G W (3.16.0-rc1)
MSR: 00021002 <CE,ME> CR: 44048082 XER: 00000000

GPR00: c02885cc effd3e00 c0789380 000000c6 c1de3478 c1de382c 00000000 00021002
GPR08: 00000007 00000000 01660000 0000012f 84048082 00000000 00000018 c07db080
GPR16: 00000006 00000100 0000002c c62517a0 c07e1e10 c0da1180 00029002 c0d95f88
GPR24: c07a0000 c07a4acc effd3e58 ee322bc0 0000001c ee130210 00000000 c0d95f80
NIP [c02885cc] check_unmap+0x47c/0xab0
LR [c02885cc] check_unmap+0x47c/0xab0
Call Trace:
[effd3e00] [c02885cc] check_unmap+0x47c/0xab0 (unreliable)
[effd3e50] [c0288c78] debug_dma_unmap_page+0x78/0x90
[effd3ed0] [f9624d84] ahash_done_ctx_src+0xa4/0x200 [caamhash]
[effd3f00] [c0429640] caam_jr_dequeue+0x1c0/0x280
[effd3f50] [c002c94c] tasklet_action+0xcc/0x1a0
[effd3f80] [c002cb30] __do_softirq+0x110/0x220
[effd3fe0] [c002cf34] irq_exit+0xa4/0xe0
[effd3ff0] [c000d834] call_do_irq+0x24/0x3c
[c07d7d50] [c000489c] do_IRQ+0x8c/0x110
[c07d7d70] [c000f86c] ret_from_except+0x0/0x18
--- Exception: 501 at _raw_spin_unlock_irq+0x30/0x50
LR = _raw_spin_unlock_irq+0x2c/0x50
[c07d7e40] [c0053084] finish_task_switch+0x74/0x130
[c07d7e60] [c058f278] __schedule+0x238/0x620
[c07d7f70] [c058fb50] schedule_preempt_disabled+0x10/0x20
[c07d7f80] [c00686a0] cpu_startup_entry+0x100/0x1b0
[c07d7fb0] [c074793c] start_kernel+0x338/0x34c
[c07d7ff0] [c00003d8] set_ivor+0x140/0x17c
Instruction dump:
7d495214 7d294214 806a0010 80c90010 811a001c 813a0020 815a0024 90610008
3c60c06d 90c1000c 3863f764 4830d131 <0fe00000> 3c60c06d 3863f0f4 4830d121
---[ end trace db1fae088c75c280 ]---
Mapped at:
[<f96251bc>] ahash_final_ctx+0x14c/0x7b0 [caamhash]
[<c022ff4c>] __test_hash+0x2ac/0x6c0
[<c0230388>] test_hash+0x28/0xb0
[<c02304a4>] alg_test_hash+0x94/0xc0
[<c022fa94>] alg_test+0x114/0x2e0

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 4bb6ff46e339..e94dd4518cfb 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -718,7 +718,7 @@ static void ahash_done_ctx_src(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);

- ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_FROM_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, digestsize, DMA_TO_DEVICE);
kfree(edesc);

#ifdef DEBUG
--
1.8.3.1

2014-07-11 12:36:18

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 03/10] crypto: caam - fix typo in dma_mapping_error

dma_mapping_error checks for an incorrect DMA address:
s/ctx->sh_desc_enc_dma/ctx->sh_desc_dec_dma

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamalg.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c
index 64c606d9e821..31f2e10b5102 100644
--- a/drivers/crypto/caam/caamalg.c
+++ b/drivers/crypto/caam/caamalg.c
@@ -786,7 +786,7 @@ static int ablkcipher_setkey(struct crypto_ablkcipher *ablkcipher,
ctx->sh_desc_dec_dma = dma_map_single(jrdev, desc,
desc_bytes(desc),
DMA_TO_DEVICE);
- if (dma_mapping_error(jrdev, ctx->sh_desc_enc_dma)) {
+ if (dma_mapping_error(jrdev, ctx->sh_desc_dec_dma)) {
dev_err(jrdev, "unable to map shared descriptor\n");
return -ENOMEM;
}
--
1.8.3.1

2014-07-11 12:36:17

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 06/10] crypto: caam - fix DMA direction mismatch in ahash_done_ctx_dst

caam_jr ffe301000.jr: DMA-API: device driver frees DMA memory with different direction [device address=0x00000000062ad1ac] [size=28 bytes] [mapped with DMA_FROM_DEVICE] [unmapped with DMA_TO_DEVICE]
------------[ cut here ]------------
WARNING: at lib/dma-debug.c:1131
Modules linked in: caamhash(+) [last unloaded: caamhash]
CPU: 0 PID: 0 Comm: swapper/0 Tainted: G W 3.16.0-rc1 #23
task: c0789380 ti: effd2000 task.ti: c07d6000
NIP: c02885cc LR: c02885cc CTR: c02d7020
REGS: effd3d50 TRAP: 0700 Tainted: G W (3.16.0-rc1)
MSR: 00021002 <CE,ME> CR: 44048082 XER: 00000000

GPR00: c02885cc effd3e00 c0789380 000000c6 c1de3478 c1de382c 00000000 00021002
GPR08: 00000007 00000000 01660000 0000012f 84048082 00000000 00000018 c07db080
GPR16: 00000006 00000100 0000002c eee567e0 c07e1e10 c0da1180 00029002 c0d96708
GPR24: c07a0000 c07a4acc effd3e58 ee29b140 0000001c ee130210 00000000 c0d96700
NIP [c02885cc] check_unmap+0x47c/0xab0
LR [c02885cc] check_unmap+0x47c/0xab0
Call Trace:
[effd3e00] [c02885cc] check_unmap+0x47c/0xab0 (unreliable)
[effd3e50] [c0288c78] debug_dma_unmap_page+0x78/0x90
[effd3ed0] [f9350974] ahash_done_ctx_dst+0xa4/0x200 [caamhash]
[effd3f00] [c0429640] caam_jr_dequeue+0x1c0/0x280
[effd3f50] [c002c94c] tasklet_action+0xcc/0x1a0
[effd3f80] [c002cb30] __do_softirq+0x110/0x220
[effd3fe0] [c002cf34] irq_exit+0xa4/0xe0
[effd3ff0] [c000d834] call_do_irq+0x24/0x3c
[c07d7d50] [c000489c] do_IRQ+0x8c/0x110
[c07d7d70] [c000f86c] ret_from_except+0x0/0x18
--- Exception: 501 at _raw_spin_unlock_irq+0x30/0x50
LR = _raw_spin_unlock_irq+0x2c/0x50
[c07d7e40] [c0053084] finish_task_switch+0x74/0x130
[c07d7e60] [c058f278] __schedule+0x238/0x620
[c07d7f70] [c058fb50] schedule_preempt_disabled+0x10/0x20
[c07d7f80] [c00686a0] cpu_startup_entry+0x100/0x1b0
[c07d7fb0] [c074793c] start_kernel+0x338/0x34c
[c07d7ff0] [c00003d8] set_ivor+0x140/0x17c
Instruction dump:
7d495214 7d294214 806a0010 80c90010 811a001c 813a0020 815a0024 90610008
3c60c06d 90c1000c 3863f764 4830d131 <0fe00000> 3c60c06d 3863f0f4 4830d121
---[ end trace db1fae088c75c270 ]---
Mapped at:
[<f9352454>] ahash_update_first+0x5b4/0xba0 [caamhash]
[<c022ff28>] __test_hash+0x288/0x6c0
[<c0230388>] test_hash+0x28/0xb0
[<c02304a4>] alg_test_hash+0x94/0xc0
[<c022fa94>] alg_test+0x114/0x2e0

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 9ee4e0478220..4bb6ff46e339 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -753,7 +753,7 @@ static void ahash_done_ctx_dst(struct device *jrdev, u32 *desc, u32 err,
if (err)
caam_jr_strstatus(jrdev, err);

- ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_TO_DEVICE);
+ ahash_unmap_ctx(jrdev, edesc, req, ctx->ctx_len, DMA_FROM_DEVICE);
kfree(edesc);

#ifdef DEBUG
--
1.8.3.1

2014-07-11 12:36:21

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 08/10] crypto: caam - fix uninitialized S/G table size in ahash_digest

Not initializing edesc->sec4_sg_bytes correctly causes ahash_done
callback to free unallocated DMA memory:

caam_jr ffe301000.jr: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x300900000000b44d] [size=46158 bytes]
WARNING: at lib/dma-debug.c:1080
Modules linked in: caamhash(+) [last unloaded: caamhash]
CPU: 0 PID: 1358 Comm: cryptomgr_test Tainted: G W 3.16.0-rc1 #23
task: eed04250 ti: effd2000 task.ti: c6046000
NIP: c02889fc LR: c02889fc CTR: c02d7020
REGS: effd3d50 TRAP: 0700 Tainted: G W (3.16.0-rc1)
MSR: 00029002 <CE,EE,ME> CR: 44048082 XER: 00000000

GPR00: c02889fc effd3e00 eed04250 00000091 c1de3478 c1de382c 00000000 00029002
GPR08: 00000007 00000000 01660000 00000000 22048082 00000000 00000018 c07db080
GPR16: 00000006 00000100 0000002c ee2497e0 c07e1e10 c0da1180 00029002 c0d912c8
GPR24: 00000014 ee2497c0 effd3e58 00000000 c078ad4c ee130210 30090000 0000b44d
NIP [c02889fc] check_unmap+0x8ac/0xab0
LR [c02889fc] check_unmap+0x8ac/0xab0
Call Trace:
[effd3e00] [c02889fc] check_unmap+0x8ac/0xab0 (unreliable)
[effd3e50] [c0288c78] debug_dma_unmap_page+0x78/0x90
[effd3ed0] [f9404fec] ahash_done+0x11c/0x190 [caamhash]
[effd3f00] [c0429640] caam_jr_dequeue+0x1c0/0x280
[effd3f50] [c002c94c] tasklet_action+0xcc/0x1a0
[effd3f80] [c002cb30] __do_softirq+0x110/0x220
[effd3fe0] [c002cf34] irq_exit+0xa4/0xe0
[effd3ff0] [c000d834] call_do_irq+0x24/0x3c
[c6047ae0] [c000489c] do_IRQ+0x8c/0x110
[c6047b00] [c000f86c] ret_from_except+0x0/0x18
--- Exception: 501 at _raw_spin_unlock_irq+0x30/0x50
LR = _raw_spin_unlock_irq+0x2c/0x50
[c6047bd0] [c0590158] wait_for_common+0xb8/0x170
[c6047c10] [c059024c] wait_for_completion_interruptible+0x1c/0x40
[c6047c20] [c022fc78] do_one_async_hash_op.isra.2.part.3+0x18/0x40
[c6047c30] [c022ff98] __test_hash+0x2f8/0x6c0
[c6047de0] [c0230388] test_hash+0x28/0xb0
[c6047e00] [c0230458] alg_test_hash+0x48/0xc0
[c6047e20] [c022fa94] alg_test+0x114/0x2e0
[c6047ea0] [c022cd1c] cryptomgr_test+0x4c/0x60
[c6047eb0] [c00497a4] kthread+0xc4/0xe0
[c6047f40] [c000f2fc] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
41de01c8 80a9002c 2f850000 40fe0008 80a90008 80fa0018 3c60c06d 811a001c
3863f4a4 813a0020 815a0024 4830cd01 <0fe00000> 81340048 2f890000 40feff48

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index e94dd4518cfb..126d80c23571 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -1097,6 +1097,7 @@ static int ahash_digest(struct ahash_request *req)
}
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
+ edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->src_nents = src_nents;
edesc->chained = chained;

--
1.8.3.1

2014-07-11 12:36:22

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 09/10] crypto: caam - fix uninitialized edesc->dst_dma field

dst_dma not being properly initialized causes ahash_done_ctx_dst
to try to free unallocated DMA memory:

caam_jr ffe301000.jr: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x0000000006513340] [size=28 bytes]
WARNING: at lib/dma-debug.c:1080
Modules linked in: caamhash(+) [last unloaded: caamhash]
CPU: 0 PID: 1373 Comm: cryptomgr_test Tainted: G W 3.16.0-rc1 #23
task: ee23e350 ti: effd2000 task.ti: ee1f6000
NIP: c02889fc LR: c02889fc CTR: c02d7020
REGS: effd3d50 TRAP: 0700 Tainted: G W (3.16.0-rc1)
MSR: 00029002 <CE,EE,ME> CR: 44048082 XER: 00000000

GPR00: c02889fc effd3e00 ee23e350 0000008e c1de3478 c1de382c 00000000 00029002
GPR08: 00000007 00000000 01660000 00000000 24048082 00000000 00000018 c07db080
GPR16: 00000006 00000100 0000002c eeb4a7e0 c07e1e10 c0da1180 00029002 c0d9b3c8
GPR24: eeb4a7c0 00000000 effd3e58 00000000 c078ad4c ee130210 00000000 06513340
NIP [c02889fc] check_unmap+0x8ac/0xab0
LR [c02889fc] check_unmap+0x8ac/0xab0
Call Trace:
[effd3e00] [c02889fc] check_unmap+0x8ac/0xab0 (unreliable)
[effd3e50] [c0288c78] debug_dma_unmap_page+0x78/0x90
[effd3ed0] [f94b89ec] ahash_done_ctx_dst+0x11c/0x200 [caamhash]
[effd3f00] [c0429640] caam_jr_dequeue+0x1c0/0x280
[effd3f50] [c002c94c] tasklet_action+0xcc/0x1a0
[effd3f80] [c002cb30] __do_softirq+0x110/0x220
[effd3fe0] [c002cf34] irq_exit+0xa4/0xe0
[effd3ff0] [c000d834] call_do_irq+0x24/0x3c
[ee1f7ae0] [c000489c] do_IRQ+0x8c/0x110
[ee1f7b00] [c000f86c] ret_from_except+0x0/0x18
--- Exception: 501 at _raw_spin_unlock_irq+0x30/0x50
LR = _raw_spin_unlock_irq+0x2c/0x50
[ee1f7bd0] [c0590158] wait_for_common+0xb8/0x170
[ee1f7c10] [c059024c] wait_for_completion_interruptible+0x1c/0x40
[ee1f7c20] [c022fc78] do_one_async_hash_op.isra.2.part.3+0x18/0x40
[ee1f7c30] [c022ffb8] __test_hash+0x318/0x6c0
[ee1f7de0] [c0230388] test_hash+0x28/0xb0
[ee1f7e00] [c02304a4] alg_test_hash+0x94/0xc0
[ee1f7e20] [c022fa94] alg_test+0x114/0x2e0
[ee1f7ea0] [c022cd1c] cryptomgr_test+0x4c/0x60
[ee1f7eb0] [c00497a4] kthread+0xc4/0xe0
[ee1f7f40] [c000f2fc] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
41de01c8 80a9002c 2f850000 40fe0008 80a90008 80fa0018 3c60c06d 811a001c
3863f4a4 813a0020 815a0024 4830cd01 <0fe00000> 81340048 2f890000 40feff48

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 126d80c23571..44be5ad38ad7 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -1255,6 +1255,7 @@ static int ahash_update_no_ctx(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
+ edesc->dst_dma = 0;

state->buf_dma = buf_map_to_sec4_sg(jrdev, edesc->sec4_sg,
buf, *buflen);
@@ -1454,6 +1455,7 @@ static int ahash_update_first(struct ahash_request *req)
edesc->sec4_sg_bytes = sec4_sg_bytes;
edesc->sec4_sg = (void *)edesc + sizeof(struct ahash_edesc) +
DESC_JOB_IO_LEN;
+ edesc->dst_dma = 0;

if (src_nents) {
sg_to_sec4_sg_last(req->src, src_nents,
--
1.8.3.1

2014-07-11 12:36:27

by Horia Geantă

[permalink] [raw]
Subject: [PATCH 10/10] crypto: caam - fix uninitialized state->buf_dma field

state->buf_dma not being initialized can cause try_buf_map_to_sec4_sg
to try to free unallocated DMA memory:

caam_jr ffe301000.jr: DMA-API: device driver tries to free DMA memory it has not allocated [device address=0x000000002eb15068] [size=0 bytes]
WARNING: at lib/dma-debug.c:1080
Modules linked in: caamhash(+) [last unloaded: caamhash]
CPU: 0 PID: 1387 Comm: cryptomgr_test Tainted: G W 3.16.0-rc1 #23
task: eed24e90 ti: eebd0000 task.ti: eebd0000
NIP: c02889fc LR: c02889fc CTR: c02d7020
REGS: eebd1a50 TRAP: 0700 Tainted: G W (3.16.0-rc1)
MSR: 00029002 <CE,EE,ME> CR: 44042082 XER: 00000000

GPR00: c02889fc eebd1b00 eed24e90 0000008d c1de3478 c1de382c 00000000 00029002
GPR08: 00000007 00000000 01660000 00000000 24042082 00000000 c07a1900 eeda2a40
GPR16: 005d62a0 c078ad4c 00000000 eeb15068 c07e1e10 c0da1180 00029002 c0d97408
GPR24: c62497a0 00000014 eebd1b58 00000000 c078ad4c ee130210 00000000 2eb15068
NIP [c02889fc] check_unmap+0x8ac/0xab0
LR [c02889fc] check_unmap+0x8ac/0xab0
Call Trace:
[eebd1b00] [c02889fc] check_unmap+0x8ac/0xab0 (unreliable)
--- Exception: 0 at (null)
LR = (null)
[eebd1b50] [c0288c78] debug_dma_unmap_page+0x78/0x90 (unreliable)
[eebd1bd0] [f956f738] ahash_final_ctx+0x6d8/0x7b0 [caamhash]
[eebd1c30] [c022ff4c] __test_hash+0x2ac/0x6c0
[eebd1de0] [c0230388] test_hash+0x28/0xb0
[eebd1e00] [c02304a4] alg_test_hash+0x94/0xc0
[eebd1e20] [c022fa94] alg_test+0x114/0x2e0
[eebd1ea0] [c022cd1c] cryptomgr_test+0x4c/0x60
[eebd1eb0] [c00497a4] kthread+0xc4/0xe0
[eebd1f40] [c000f2fc] ret_from_kernel_thread+0x5c/0x64
Instruction dump:
41de01c8 80a9002c 2f850000 40fe0008 80a90008 80fa0018 3c60c06d 811a001c
3863f4a4 813a0020 815a0024 4830cd01 <0fe00000> 81340048 2f890000 40feff48

Signed-off-by: Horia Geanta <[email protected]>
---
drivers/crypto/caam/caamhash.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c
index 44be5ad38ad7..b464d03ebf40 100644
--- a/drivers/crypto/caam/caamhash.c
+++ b/drivers/crypto/caam/caamhash.c
@@ -1536,6 +1536,7 @@ static int ahash_init(struct ahash_request *req)
state->final = ahash_final_no_ctx;

state->current_buf = 0;
+ state->buf_dma = 0;

return 0;
}
--
1.8.3.1

2014-07-18 23:24:46

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH 00/10] CAAM - DMA API fixes

On Fri, 11 Jul 2014 15:34:45 +0300
Horia Geanta <[email protected]> wrote:

Hi Horia,

> Enabling DMA-API debugging reveals quite a lot of problems in CAAM module.
> Patches below fix them - tested on P3041DS QorIQ platform. Please apply.

In an attempt to try and test these patches on a t4240qds, I get:

caam ffe300000.crypto: failed to acquire DECO 0

even on the existing cryptodev master. Any ideas?

Kim

2014-07-19 00:07:30

by Horia Geantă

[permalink] [raw]
Subject: Re: [PATCH 00/10] CAAM - DMA API fixes

On 7/19/2014 2:04 AM, Kim Phillips wrote:
> On Fri, 11 Jul 2014 15:34:45 +0300
> Horia Geanta <[email protected]> wrote:
>
> Hi Horia,
>
>> Enabling DMA-API debugging reveals quite a lot of problems in CAAM module.
>> Patches below fix them - tested on P3041DS QorIQ platform. Please apply.
>
> In an attempt to try and test these patches on a t4240qds, I get:
>
> caam ffe300000.crypto: failed to acquire DECO 0
>
> even on the existing cryptodev master. Any ideas?

Could you revert commit
17157c90a8abf9323ee2a3daac7ad9f696642dda
("crypto: caam - Configuration for platforms with virtualization enabled
in CAAM")
and let me know whether things improve?

Thanks,
Horia

2014-07-22 22:42:20

by Kim Phillips

[permalink] [raw]
Subject: Re: [PATCH 01/10] crypto: testmgr - avoid DMA mapping from text, rodata, stack

On Fri, 11 Jul 2014 15:34:46 +0300
Horia Geanta <[email protected]> wrote:

> +++ b/crypto/testmgr.c
> @@ -198,13 +198,20 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
> const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
> unsigned int i, j, k, temp;
> struct scatterlist sg[8];
> - char result[64];
> + char *result = NULL;
> + char *key = NULL;

these needn't be initialized, here and elsewhere.

> struct ahash_request *req;
> struct tcrypt_result tresult;
> void *hash_buff;
> char *xbuf[XBUFSIZE];
> int ret = -ENOMEM;
>
> + result = kmalloc(64, GFP_KERNEL);

s/64/MAX_DIGEST_SIZE

> +++ b/crypto/testmgr.h
> @@ -32,7 +32,7 @@
> #define MAX_DIGEST_SIZE 64
> #define MAX_TAP 8
>
> -#define MAX_KEYLEN 56
> +#define MAX_KEYLEN 160
> #define MAX_IVLEN 32

this change could use a blurb in the commit message.

Other than that, this series gets my:

Acked-by: Kim Phillips <[email protected]>

Thanks!

Kim

2014-07-23 08:50:02

by Horia Geantă

[permalink] [raw]
Subject: Re: [PATCH 01/10] crypto: testmgr - avoid DMA mapping from text, rodata, stack

On 7/23/2014 1:37 AM, Kim Phillips wrote:
> On Fri, 11 Jul 2014 15:34:46 +0300
> Horia Geanta <[email protected]> wrote:
>
>> +++ b/crypto/testmgr.c
>> @@ -198,13 +198,20 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
>> const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
>> unsigned int i, j, k, temp;
>> struct scatterlist sg[8];
>> - char result[64];
>> + char *result = NULL;
>> + char *key = NULL;
>
> these needn't be initialized, here and elsewhere.

I was under the impression that this is needed for kfree on some exit
paths, but indeed it's not the case.

>
>> struct ahash_request *req;
>> struct tcrypt_result tresult;
>> void *hash_buff;
>> char *xbuf[XBUFSIZE];
>> int ret = -ENOMEM;
>>
>> + result = kmalloc(64, GFP_KERNEL);
>
> s/64/MAX_DIGEST_SIZE
>
>> +++ b/crypto/testmgr.h
>> @@ -32,7 +32,7 @@
>> #define MAX_DIGEST_SIZE 64
>> #define MAX_TAP 8
>>
>> -#define MAX_KEYLEN 56
>> +#define MAX_KEYLEN 160
>> #define MAX_IVLEN 32
>
> this change could use a blurb in the commit message.

I'll send a v2 only for current patch, if Herbert is ok with this.

>
> Other than that, this series gets my:
>
> Acked-by: Kim Phillips <[email protected]>
>
> Thanks!

Thanks for reviewing, testing.

Horia

2014-07-23 09:00:39

by Horia Geantă

[permalink] [raw]
Subject: [PATCH v2 01/10] crypto: testmgr - avoid DMA mapping from text, rodata, stack

With DMA_API_DEBUG set, following warnings are emitted
(tested on CAAM accelerator):
DMA-API: device driver maps memory from kernel text or rodata
DMA-API: device driver maps memory from stack
and the culprits are:
-key in __test_aead and __test_hash
-result in __test_hash

MAX_KEYLEN is changed to accommodate maximum key length from
existing test vectors in crypto/testmgr.h (131 bytes) and rounded.

Signed-off-by: Horia Geanta <[email protected]>
---
v2: Addressed Kim's comments.

crypto/testmgr.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------
crypto/testmgr.h | 2 +-
2 files changed, 50 insertions(+), 9 deletions(-)

diff --git a/crypto/testmgr.c b/crypto/testmgr.c
index 0f90612a00b9..81818b9a1b83 100644
--- a/crypto/testmgr.c
+++ b/crypto/testmgr.c
@@ -198,13 +198,20 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
const char *algo = crypto_tfm_alg_driver_name(crypto_ahash_tfm(tfm));
unsigned int i, j, k, temp;
struct scatterlist sg[8];
- char result[64];
+ char *result;
+ char *key;
struct ahash_request *req;
struct tcrypt_result tresult;
void *hash_buff;
char *xbuf[XBUFSIZE];
int ret = -ENOMEM;

+ result = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL);
+ if (!result)
+ return ret;
+ key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
+ if (!key)
+ goto out_nobuf;
if (testmgr_alloc_buf(xbuf))
goto out_nobuf;

@@ -229,7 +236,7 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
goto out;

j++;
- memset(result, 0, 64);
+ memset(result, 0, MAX_DIGEST_SIZE);

hash_buff = xbuf[0];
hash_buff += align_offset;
@@ -239,8 +246,14 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,

if (template[i].ksize) {
crypto_ahash_clear_flags(tfm, ~0);
- ret = crypto_ahash_setkey(tfm, template[i].key,
- template[i].ksize);
+ if (template[i].ksize > MAX_KEYLEN) {
+ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
+ j, algo, template[i].ksize, MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].ksize);
+ ret = crypto_ahash_setkey(tfm, key, template[i].ksize);
if (ret) {
printk(KERN_ERR "alg: hash: setkey failed on "
"test %d for %s: ret=%d\n", j, algo,
@@ -300,7 +313,7 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,

if (template[i].np) {
j++;
- memset(result, 0, 64);
+ memset(result, 0, MAX_DIGEST_SIZE);

temp = 0;
sg_init_table(sg, template[i].np);
@@ -319,8 +332,16 @@ static int __test_hash(struct crypto_ahash *tfm, struct hash_testvec *template,
}

if (template[i].ksize) {
+ if (template[i].ksize > MAX_KEYLEN) {
+ pr_err("alg: hash: setkey failed on test %d for %s: key size %d > %d\n",
+ j, algo, template[i].ksize,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
crypto_ahash_clear_flags(tfm, ~0);
- ret = crypto_ahash_setkey(tfm, template[i].key,
+ memcpy(key, template[i].key, template[i].ksize);
+ ret = crypto_ahash_setkey(tfm, key,
template[i].ksize);

if (ret) {
@@ -372,6 +393,8 @@ out:
out_noreq:
testmgr_free_buf(xbuf);
out_nobuf:
+ kfree(key);
+ kfree(result);
return ret;
}

@@ -429,6 +452,9 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
iv = kzalloc(MAX_IVLEN, GFP_KERNEL);
if (!iv)
return ret;
+ key = kmalloc(MAX_KEYLEN, GFP_KERNEL);
+ if (!key)
+ goto out_noxbuf;
if (testmgr_alloc_buf(xbuf))
goto out_noxbuf;
if (testmgr_alloc_buf(axbuf))
@@ -493,7 +519,14 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);

- key = template[i].key;
+ if (template[i].klen > MAX_KEYLEN) {
+ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+ d, j, algo, template[i].klen,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].klen);

ret = crypto_aead_setkey(tfm, key,
template[i].klen);
@@ -594,7 +627,14 @@ static int __test_aead(struct crypto_aead *tfm, int enc,
if (template[i].wk)
crypto_aead_set_flags(
tfm, CRYPTO_TFM_REQ_WEAK_KEY);
- key = template[i].key;
+ if (template[i].klen > MAX_KEYLEN) {
+ pr_err("alg: aead%s: setkey failed on test %d for %s: key size %d > %d\n",
+ d, j, algo, template[i].klen,
+ MAX_KEYLEN);
+ ret = -EINVAL;
+ goto out;
+ }
+ memcpy(key, template[i].key, template[i].klen);

ret = crypto_aead_setkey(tfm, key, template[i].klen);
if (!ret == template[i].fail) {
@@ -776,6 +816,7 @@ out_nooutbuf:
out_noaxbuf:
testmgr_free_buf(xbuf);
out_noxbuf:
+ kfree(key);
kfree(iv);
return ret;
}
diff --git a/crypto/testmgr.h b/crypto/testmgr.h
index 4bb607189b8d..46df9e88bbf3 100644
--- a/crypto/testmgr.h
+++ b/crypto/testmgr.h
@@ -32,7 +32,7 @@
#define MAX_DIGEST_SIZE 64
#define MAX_TAP 8

-#define MAX_KEYLEN 56
+#define MAX_KEYLEN 160
#define MAX_IVLEN 32

struct hash_testvec {
--
1.8.3.1

2014-07-23 13:35:54

by Herbert Xu

[permalink] [raw]
Subject: Re: [PATCH v2 01/10] crypto: testmgr - avoid DMA mapping from text, rodata, stack

On Wed, Jul 23, 2014 at 11:59:38AM +0300, Horia Geanta wrote:
> With DMA_API_DEBUG set, following warnings are emitted
> (tested on CAAM accelerator):
> DMA-API: device driver maps memory from kernel text or rodata
> DMA-API: device driver maps memory from stack
> and the culprits are:
> -key in __test_aead and __test_hash
> -result in __test_hash
>
> MAX_KEYLEN is changed to accommodate maximum key length from
> existing test vectors in crypto/testmgr.h (131 bytes) and rounded.
>
> Signed-off-by: Horia Geanta <[email protected]>
> ---
> v2: Addressed Kim's comments.

All applied. Thanks.
--
Email: Herbert Xu <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt