Skip to content

Commit dfd3bc6

Browse files
committed
crypto: acomp - Add async nondma fallback
Add support for passing non-DMA virtual addresses to async drivers by passing them along to the fallback software algorithm. Signed-off-by: Herbert Xu <[email protected]>
1 parent dfd28c8 commit dfd3bc6

File tree

1 file changed

+41
-28
lines changed

1 file changed

+41
-28
lines changed

crypto/acompress.c

Lines changed: 41 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -152,20 +152,6 @@ struct crypto_acomp *crypto_alloc_acomp_node(const char *alg_name, u32 type,
152152
}
153153
EXPORT_SYMBOL_GPL(crypto_alloc_acomp_node);
154154

155-
static bool acomp_request_has_nondma(struct acomp_req *req)
156-
{
157-
struct acomp_req *r2;
158-
159-
if (acomp_request_isnondma(req))
160-
return true;
161-
162-
list_for_each_entry(r2, &req->base.list, base.list)
163-
if (acomp_request_isnondma(r2))
164-
return true;
165-
166-
return false;
167-
}
168-
169155
static void acomp_save_req(struct acomp_req *req, crypto_completion_t cplt)
170156
{
171157
struct crypto_acomp *tfm = crypto_acomp_reqtfm(req);
@@ -234,6 +220,45 @@ static void acomp_virt_to_sg(struct acomp_req *req)
234220
}
235221
}
236222

223+
static int acomp_do_nondma(struct acomp_req_chain *state,
224+
struct acomp_req *req)
225+
{
226+
u32 keep = CRYPTO_ACOMP_REQ_SRC_VIRT |
227+
CRYPTO_ACOMP_REQ_SRC_NONDMA |
228+
CRYPTO_ACOMP_REQ_DST_VIRT |
229+
CRYPTO_ACOMP_REQ_DST_NONDMA;
230+
ACOMP_REQUEST_ON_STACK(fbreq, crypto_acomp_reqtfm(req));
231+
int err;
232+
233+
acomp_request_set_callback(fbreq, req->base.flags, NULL, NULL);
234+
fbreq->base.flags &= ~keep;
235+
fbreq->base.flags |= req->base.flags & keep;
236+
fbreq->src = req->src;
237+
fbreq->dst = req->dst;
238+
fbreq->slen = req->slen;
239+
fbreq->dlen = req->dlen;
240+
241+
if (state->op == crypto_acomp_reqtfm(req)->compress)
242+
err = crypto_acomp_compress(fbreq);
243+
else
244+
err = crypto_acomp_decompress(fbreq);
245+
246+
req->dlen = fbreq->dlen;
247+
return err;
248+
}
249+
250+
static int acomp_do_one_req(struct acomp_req_chain *state,
251+
struct acomp_req *req)
252+
{
253+
state->cur = req;
254+
255+
if (acomp_request_isnondma(req))
256+
return acomp_do_nondma(state, req);
257+
258+
acomp_virt_to_sg(req);
259+
return state->op(req);
260+
}
261+
237262
static int acomp_reqchain_finish(struct acomp_req_chain *state,
238263
int err, u32 mask)
239264
{
@@ -252,10 +277,8 @@ static int acomp_reqchain_finish(struct acomp_req_chain *state,
252277
req->base.flags &= mask;
253278
req->base.complete = acomp_reqchain_done;
254279
req->base.data = state;
255-
state->cur = req;
256280

257-
acomp_virt_to_sg(req);
258-
err = state->op(req);
281+
err = acomp_do_one_req(state, req);
259282

260283
if (err == -EINPROGRESS) {
261284
if (!list_empty(&state->head))
@@ -308,27 +331,17 @@ static int acomp_do_req_chain(struct acomp_req *req,
308331
(!acomp_request_chained(req) && !acomp_request_isvirt(req)))
309332
return op(req);
310333

311-
/*
312-
* There are no in-kernel users that do this. If and ever
313-
* such users come into being then we could add a fall-back
314-
* path.
315-
*/
316-
if (acomp_request_has_nondma(req))
317-
return -EINVAL;
318-
319334
if (acomp_is_async(tfm)) {
320335
acomp_save_req(req, acomp_reqchain_done);
321336
state = req->base.data;
322337
}
323338

324339
state->op = op;
325-
state->cur = req;
326340
state->src = NULL;
327341
INIT_LIST_HEAD(&state->head);
328342
list_splice_init(&req->base.list, &state->head);
329343

330-
acomp_virt_to_sg(req);
331-
err = op(req);
344+
err = acomp_do_one_req(state, req);
332345
if (err == -EBUSY || err == -EINPROGRESS)
333346
return -EBUSY;
334347

0 commit comments

Comments
 (0)