crypto: hifn_795x - Don't copy src sg list
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: Evgeniy Polyakov <zbr@ioremap.net> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
This commit is contained in:
committed by
Herbert Xu
parent
75741a0340
commit
3416158680
@ -1378,32 +1378,40 @@ static int hifn_setup_dma(struct hifn_device *dev, struct hifn_context *ctx,
|
|||||||
unsigned int soff, doff;
|
unsigned int soff, doff;
|
||||||
unsigned int n, len;
|
unsigned int n, len;
|
||||||
|
|
||||||
|
n = nbytes;
|
||||||
|
while (n) {
|
||||||
|
spage = sg_page(src);
|
||||||
|
soff = src->offset;
|
||||||
|
len = min(src->length, n);
|
||||||
|
|
||||||
|
dprintk("%s: spage: %p, soffset: %u, nbytes: %u, "
|
||||||
|
"priv: %p, ctx: %p.\n",
|
||||||
|
dev->name, spage, soff, nbytes, priv, ctx);
|
||||||
|
hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
|
||||||
|
|
||||||
|
src++;
|
||||||
|
n -= len;
|
||||||
|
}
|
||||||
|
|
||||||
t = &ctx->walk.cache[0];
|
t = &ctx->walk.cache[0];
|
||||||
n = nbytes;
|
n = nbytes;
|
||||||
while (n) {
|
while (n) {
|
||||||
if (t->length) {
|
if (t->length) {
|
||||||
spage = dpage = sg_page(t);
|
dpage = sg_page(t);
|
||||||
soff = doff = 0;
|
doff = 0;
|
||||||
len = t->length;
|
len = t->length;
|
||||||
} else {
|
} else {
|
||||||
spage = sg_page(src);
|
|
||||||
soff = src->offset;
|
|
||||||
|
|
||||||
dpage = sg_page(dst);
|
dpage = sg_page(dst);
|
||||||
doff = dst->offset;
|
doff = dst->offset;
|
||||||
|
|
||||||
len = dst->length;
|
len = dst->length;
|
||||||
}
|
}
|
||||||
len = min(len, n);
|
len = min(len, n);
|
||||||
|
|
||||||
dprintk("%s: spage: %p, soffset: %u, dpage: %p, doffset: %u, "
|
dprintk("%s: dpage: %p, doffset: %u, nbytes: %u, "
|
||||||
"nbytes: %u, priv: %p, ctx: %p.\n",
|
"priv: %p, ctx: %p.\n",
|
||||||
dev->name, spage, soff, dpage, doff, nbytes, priv, ctx);
|
dev->name, dpage, doff, nbytes, priv, ctx);
|
||||||
|
|
||||||
hifn_setup_src_desc(dev, spage, soff, len, n - len == 0);
|
|
||||||
hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
|
hifn_setup_dst_desc(dev, dpage, doff, len, n - len == 0);
|
||||||
|
|
||||||
src++;
|
|
||||||
dst++;
|
dst++;
|
||||||
t++;
|
t++;
|
||||||
n -= len;
|
n -= len;
|
||||||
@ -1454,32 +1462,26 @@ static void ablkcipher_walk_exit(struct ablkcipher_walk *w)
|
|||||||
w->num = 0;
|
w->num = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist *src,
|
static int ablkcipher_add(unsigned int *drestp, struct scatterlist *dst,
|
||||||
unsigned int size, unsigned int *nbytesp)
|
unsigned int size, unsigned int *nbytesp)
|
||||||
{
|
{
|
||||||
unsigned int copy, drest = *drestp, nbytes = *nbytesp;
|
unsigned int copy, drest = *drestp, nbytes = *nbytesp;
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
void *saddr;
|
|
||||||
|
|
||||||
if (drest < size || size > nbytes)
|
if (drest < size || size > nbytes)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
while (size) {
|
while (size) {
|
||||||
copy = min(drest, min(size, src->length));
|
copy = min(drest, min(size, dst->length));
|
||||||
|
|
||||||
saddr = kmap_atomic(sg_page(src), KM_SOFTIRQ1);
|
|
||||||
memcpy(daddr, saddr + src->offset, copy);
|
|
||||||
kunmap_atomic(saddr, KM_SOFTIRQ1);
|
|
||||||
|
|
||||||
size -= copy;
|
size -= copy;
|
||||||
drest -= copy;
|
drest -= copy;
|
||||||
nbytes -= copy;
|
nbytes -= copy;
|
||||||
daddr += copy;
|
|
||||||
|
|
||||||
dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n",
|
dprintk("%s: copy: %u, size: %u, drest: %u, nbytes: %u.\n",
|
||||||
__func__, copy, size, drest, nbytes);
|
__func__, copy, size, drest, nbytes);
|
||||||
|
|
||||||
src++;
|
dst++;
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1492,8 +1494,7 @@ static int ablkcipher_add(void *daddr, unsigned int *drestp, struct scatterlist
|
|||||||
static int ablkcipher_walk(struct ablkcipher_request *req,
|
static int ablkcipher_walk(struct ablkcipher_request *req,
|
||||||
struct ablkcipher_walk *w)
|
struct ablkcipher_walk *w)
|
||||||
{
|
{
|
||||||
struct scatterlist *src, *dst, *t;
|
struct scatterlist *dst, *t;
|
||||||
void *daddr;
|
|
||||||
unsigned int nbytes = req->nbytes, offset, copy, diff;
|
unsigned int nbytes = req->nbytes, offset, copy, diff;
|
||||||
int idx, tidx, err;
|
int idx, tidx, err;
|
||||||
|
|
||||||
@ -1503,26 +1504,22 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
|
|||||||
if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED))
|
if (idx >= w->num && (w->flags & ASYNC_FLAGS_MISALIGNED))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
src = &req->src[idx];
|
|
||||||
dst = &req->dst[idx];
|
dst = &req->dst[idx];
|
||||||
|
|
||||||
dprintk("\n%s: slen: %u, dlen: %u, soff: %u, doff: %u, offset: %u, "
|
dprintk("\n%s: dlen: %u, doff: %u, offset: %u, nbytes: %u.\n",
|
||||||
"nbytes: %u.\n",
|
__func__, dst->length, dst->offset, offset, nbytes);
|
||||||
__func__, src->length, dst->length, src->offset,
|
|
||||||
dst->offset, offset, nbytes);
|
|
||||||
|
|
||||||
if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
|
if (!IS_ALIGNED(dst->offset, HIFN_D_DST_DALIGN) ||
|
||||||
!IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
|
!IS_ALIGNED(dst->length, HIFN_D_DST_DALIGN) ||
|
||||||
offset) {
|
offset) {
|
||||||
unsigned slen = min(src->length - offset, nbytes);
|
unsigned slen = min(dst->length - offset, nbytes);
|
||||||
unsigned dlen = PAGE_SIZE;
|
unsigned dlen = PAGE_SIZE;
|
||||||
|
|
||||||
t = &w->cache[idx];
|
t = &w->cache[idx];
|
||||||
|
|
||||||
daddr = kmap_atomic(sg_page(t), KM_SOFTIRQ0);
|
err = ablkcipher_add(&dlen, dst, slen, &nbytes);
|
||||||
err = ablkcipher_add(daddr, &dlen, src, slen, &nbytes);
|
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_out_unmap;
|
return err;
|
||||||
|
|
||||||
idx += err;
|
idx += err;
|
||||||
|
|
||||||
@ -1558,21 +1555,19 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
|
|||||||
} else {
|
} else {
|
||||||
copy += diff + nbytes;
|
copy += diff + nbytes;
|
||||||
|
|
||||||
src = &req->src[idx];
|
dst = &req->dst[idx];
|
||||||
|
|
||||||
err = ablkcipher_add(daddr + slen, &dlen, src, nbytes, &nbytes);
|
err = ablkcipher_add(&dlen, dst, nbytes, &nbytes);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_out_unmap;
|
return err;
|
||||||
|
|
||||||
idx += err;
|
idx += err;
|
||||||
}
|
}
|
||||||
|
|
||||||
t->length = copy;
|
t->length = copy;
|
||||||
t->offset = offset;
|
t->offset = offset;
|
||||||
|
|
||||||
kunmap_atomic(daddr, KM_SOFTIRQ0);
|
|
||||||
} else {
|
} else {
|
||||||
nbytes -= min(src->length, nbytes);
|
nbytes -= min(dst->length, nbytes);
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1580,10 +1575,6 @@ static int ablkcipher_walk(struct ablkcipher_request *req,
|
|||||||
}
|
}
|
||||||
|
|
||||||
return tidx;
|
return tidx;
|
||||||
|
|
||||||
err_out_unmap:
|
|
||||||
kunmap_atomic(daddr, KM_SOFTIRQ0);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hifn_setup_session(struct ablkcipher_request *req)
|
static int hifn_setup_session(struct ablkcipher_request *req)
|
||||||
|
Reference in New Issue
Block a user