2010-04-08 16:27:14

by Uri Simchoni

[permalink] [raw]
Subject: [PATCHv2 4/10] crypto mv_cesa : Fix situations where the src sglist spans more data than the request asks for

Fix for situations where the source scatterlist spans more data than the
request nbytes

Signed-off-by: Uri Simchoni <[email protected]>
---
diff -upr linux-2.6.32.8_p3/drivers/crypto/mv_cesa.c linux-2.6.32.8_p4/drivers/crypto/mv_cesa.c
--- linux-2.6.32.8_p3/drivers/crypto/mv_cesa.c 2010-03-16 09:06:10.183753278 +0200
+++ linux-2.6.32.8_p4/drivers/crypto/mv_cesa.c 2010-03-16 08:40:09.503257114 +0200
@@ -143,27 +143,45 @@ static int mv_setkey_aes(struct crypto_a
return 0;
}

-static void setup_data_in(struct ablkcipher_request *req)
+static void copy_src_to_buf(struct req_progress *p, char *dbuf, int len)
{
int ret;
- void *buf;
-
- if (!cpg->p.sg_src_left) {
- ret = sg_miter_next(&cpg->p.src_sg_it);
- BUG_ON(!ret);
- cpg->p.sg_src_left = cpg->p.src_sg_it.length;
- cpg->p.src_start = 0;
- }
+ void *sbuf;
+ int copied = 0;

- cpg->p.crypt_len = min(cpg->p.sg_src_left, cpg->max_req_size);
+ while (1) {
+ if (!p->sg_src_left) {
+ ret = sg_miter_next(&p->src_sg_it);
+ BUG_ON(!ret);
+ p->sg_src_left = p->src_sg_it.length;
+ p->src_start = 0;
+ }

- buf = cpg->p.src_sg_it.addr;
- buf += cpg->p.src_start;
+ sbuf = p->src_sg_it.addr + p->src_start;

- memcpy(cpg->sram + SRAM_DATA_IN_START, buf, cpg->p.crypt_len);
+ if (p->sg_src_left <= len - copied) {
+ memcpy(dbuf + copied, sbuf, p->sg_src_left);
+ copied += p->sg_src_left;
+ p->sg_src_left = 0;
+ if (copied >= len)
+ break;
+ } else {
+ int copy_len = len - copied;
+ memcpy(dbuf + copied, sbuf, copy_len);
+ p->src_start += copy_len;
+ p->sg_src_left -= copy_len;
+ break;
+ }
+ }
+}

- cpg->p.sg_src_left -= cpg->p.crypt_len;
- cpg->p.src_start += cpg->p.crypt_len;
+static void setup_data_in(struct ablkcipher_request *req)
+{
+ struct req_progress *p = &cpg->p;
+ p->crypt_len =
+ min((int)req->nbytes - p->total_req_bytes, cpg->max_req_size);
+ copy_src_to_buf(p, cpg->sram + SRAM_DATA_IN_START,
+ p->crypt_len);
}

static void mv_process_current_q(int first_block)
@@ -289,12 +307,16 @@ static void dequeue_complete_req(void)
static int count_sgs(struct scatterlist *sl, unsigned int total_bytes)
{
int i = 0;
+ size_t cur_len;

- do {
- total_bytes -= sl[i].length;
- i++;