Skip to content

Commit 2c1808e

Browse files
committed
crypto: scomp - Add chaining and virtual address support
Add chaining and virtual address support to all scomp algorithms. Signed-off-by: Herbert Xu <[email protected]>
1 parent 7cf97a1 commit 2c1808e

File tree

1 file changed

+64
-30
lines changed

1 file changed

+64
-30
lines changed

crypto/scompress.c

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,9 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
178178
unsigned int dlen = req->dlen;
179179
struct page *spage, *dpage;
180180
unsigned int soff, doff;
181-
void *src, *dst;
182181
unsigned int n;
182+
const u8 *src;
183+
u8 *dst;
183184
int ret;
184185

185186
if (!req->src || !slen)
@@ -188,37 +189,47 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
188189
if (!req->dst || !dlen)
189190
return -EINVAL;
190191

191-
soff = req->src->offset;
192-
spage = nth_page(sg_page(req->src), soff / PAGE_SIZE);
193-
soff = offset_in_page(soff);
194-
195-
n = slen / PAGE_SIZE;
196-
n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE;
197-
if (slen <= req->src->length && (!PageHighMem(nth_page(spage, n)) ||
198-
size_add(soff, slen) <= PAGE_SIZE))
199-
src = kmap_local_page(spage) + soff;
200-
else
201-
src = scratch->src;
202-
203-
doff = req->dst->offset;
204-
dpage = nth_page(sg_page(req->dst), doff / PAGE_SIZE);
205-
doff = offset_in_page(doff);
192+
if (acomp_request_src_isvirt(req))
193+
src = req->svirt;
194+
else {
195+
soff = req->src->offset;
196+
spage = nth_page(sg_page(req->src), soff / PAGE_SIZE);
197+
soff = offset_in_page(soff);
198+
199+
n = slen / PAGE_SIZE;
200+
n += (offset_in_page(slen) + soff - 1) / PAGE_SIZE;
201+
if (slen <= req->src->length &&
202+
(!PageHighMem(nth_page(spage, n)) ||
203+
size_add(soff, slen) <= PAGE_SIZE))
204+
src = kmap_local_page(spage) + soff;
205+
else
206+
src = scratch->src;
207+
}
206208

207-
n = dlen / PAGE_SIZE;
208-
n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE;
209-
if (dlen <= req->dst->length && (!PageHighMem(nth_page(dpage, n)) ||
210-
size_add(doff, dlen) <= PAGE_SIZE))
211-
dst = kmap_local_page(dpage) + doff;
209+
if (acomp_request_dst_isvirt(req))
210+
dst = req->dvirt;
212211
else {
213-
if (dlen > SCOMP_SCRATCH_SIZE)
214-
dlen = SCOMP_SCRATCH_SIZE;
215-
dst = scratch->dst;
212+
doff = req->dst->offset;
213+
dpage = nth_page(sg_page(req->dst), doff / PAGE_SIZE);
214+
doff = offset_in_page(doff);
215+
216+
n = dlen / PAGE_SIZE;
217+
n += (offset_in_page(dlen) + doff - 1) / PAGE_SIZE;
218+
if (dlen <= req->dst->length &&
219+
(!PageHighMem(nth_page(dpage, n)) ||
220+
size_add(doff, dlen) <= PAGE_SIZE))
221+
dst = kmap_local_page(dpage) + doff;
222+
else {
223+
if (dlen > SCOMP_SCRATCH_SIZE)
224+
dlen = SCOMP_SCRATCH_SIZE;
225+
dst = scratch->dst;
226+
}
216227
}
217228

218229
spin_lock_bh(&scratch->lock);
219230

220231
if (src == scratch->src)
221-
memcpy_from_sglist(src, req->src, 0, slen);
232+
memcpy_from_sglist(scratch->src, req->src, 0, slen);
222233

223234
stream = raw_cpu_ptr(crypto_scomp_alg(scomp)->stream);
224235
spin_lock(&stream->lock);
@@ -237,7 +248,7 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
237248

238249
req->dlen = dlen;
239250

240-
if (dst != scratch->dst) {
251+
if (!acomp_request_dst_isvirt(req) && dst != scratch->dst) {
241252
kunmap_local(dst);
242253
dlen += doff;
243254
for (;;) {
@@ -248,20 +259,34 @@ static int scomp_acomp_comp_decomp(struct acomp_req *req, int dir)
248259
dpage = nth_page(dpage, 1);
249260
}
250261
}
251-
if (src != scratch->src)
262+
if (!acomp_request_src_isvirt(req) && src != scratch->src)
252263
kunmap_local(src);
253264

254265
return ret;
255266
}
256267

268+
static int scomp_acomp_chain(struct acomp_req *req, int dir)
269+
{
270+
struct acomp_req *r2;
271+
int err;
272+
273+
err = scomp_acomp_comp_decomp(req, dir);
274+
req->base.err = err;
275+
276+
list_for_each_entry(r2, &req->base.list, base.list)
277+
r2->base.err = scomp_acomp_comp_decomp(r2, dir);
278+
279+
return err;
280+
}
281+
257282
static int scomp_acomp_compress(struct acomp_req *req)
258283
{
259-
return scomp_acomp_comp_decomp(req, 1);
284+
return scomp_acomp_chain(req, 1);
260285
}
261286

262287
static int scomp_acomp_decompress(struct acomp_req *req)
263288
{
264-
return scomp_acomp_comp_decomp(req, 0);
289+
return scomp_acomp_chain(req, 0);
265290
}
266291

267292
static void crypto_exit_scomp_ops_async(struct crypto_tfm *tfm)
@@ -322,12 +347,21 @@ static const struct crypto_type crypto_scomp_type = {
322347
.tfmsize = offsetof(struct crypto_scomp, base),
323348
};
324349

325-
int crypto_register_scomp(struct scomp_alg *alg)
350+
static void scomp_prepare_alg(struct scomp_alg *alg)
326351
{
327352
struct crypto_alg *base = &alg->calg.base;
328353

329354
comp_prepare_alg(&alg->calg);
330355

356+
base->cra_flags |= CRYPTO_ALG_REQ_CHAIN;
357+
}
358+
359+
int crypto_register_scomp(struct scomp_alg *alg)
360+
{
361+
struct crypto_alg *base = &alg->calg.base;
362+
363+
scomp_prepare_alg(alg);
364+
331365
base->cra_type = &crypto_scomp_type;
332366
base->cra_flags |= CRYPTO_ALG_TYPE_SCOMPRESS;
333367

0 commit comments

Comments
 (0)