Skip to content

Commit 820573e

Browse files
committed
crypto: ghash-ce - Fix cryptd reordering
This patch fixes an old bug where requests can be reordered because some are processed by cryptd while others are processed directly in softirq context. The fix is to always postpone to cryptd if there are currently requests outstanding from the same tfm. This patch also removes the redundant use of cryptd in the async init function as init never touches the FPU. Signed-off-by: Herbert Xu <[email protected]>
1 parent 7271b33 commit 820573e

File tree

1 file changed

+17
-23
lines changed

1 file changed

+17
-23
lines changed

arch/arm/crypto/ghash-ce-glue.c

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -154,30 +154,23 @@ static int ghash_async_init(struct ahash_request *req)
154154
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
155155
struct ahash_request *cryptd_req = ahash_request_ctx(req);
156156
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
157+
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
158+
struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
157159

158-
if (!may_use_simd()) {
159-
memcpy(cryptd_req, req, sizeof(*req));
160-
ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
161-
return crypto_ahash_init(cryptd_req);
162-
} else {
163-
struct shash_desc *desc = cryptd_shash_desc(cryptd_req);
164-
struct crypto_shash *child = cryptd_ahash_child(cryptd_tfm);
165-
166-
desc->tfm = child;
167-
desc->flags = req->base.flags;
168-
return crypto_shash_init(desc);
169-
}
160+
desc->tfm = child;
161+
desc->flags = req->base.flags;
162+
return crypto_shash_init(desc);
170163
}
171164

172165
static int ghash_async_update(struct ahash_request *req)
173166
{
174167
struct ahash_request *cryptd_req = ahash_request_ctx(req);
168+
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
169+
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
170+
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
175171

176-
if (!may_use_simd()) {
177-
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
178-
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
179-
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
180-
172+
if (!may_use_simd() ||
173+
(in_atomic() && cryptd_ahash_queued(cryptd_tfm))) {
181174
memcpy(cryptd_req, req, sizeof(*req));
182175
ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
183176
return crypto_ahash_update(cryptd_req);
@@ -190,12 +183,12 @@ static int ghash_async_update(struct ahash_request *req)
190183
static int ghash_async_final(struct ahash_request *req)
191184
{
192185
struct ahash_request *cryptd_req = ahash_request_ctx(req);
186+
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
187+
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
188+
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
193189

194-
if (!may_use_simd()) {
195-
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
196-
struct ghash_async_ctx *ctx = crypto_ahash_ctx(tfm);
197-
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
198-
190+
if (!may_use_simd() ||
191+
(in_atomic() && cryptd_ahash_queued(cryptd_tfm))) {
199192
memcpy(cryptd_req, req, sizeof(*req));
200193
ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
201194
return crypto_ahash_final(cryptd_req);
@@ -212,7 +205,8 @@ static int ghash_async_digest(struct ahash_request *req)
212205
struct ahash_request *cryptd_req = ahash_request_ctx(req);
213206
struct cryptd_ahash *cryptd_tfm = ctx->cryptd_tfm;
214207

215-
if (!may_use_simd()) {
208+
if (!may_use_simd() ||
209+
(in_atomic() && cryptd_ahash_queued(cryptd_tfm))) {
216210
memcpy(cryptd_req, req, sizeof(*req));
217211
ahash_request_set_tfm(cryptd_req, &cryptd_tfm->base);
218212
return crypto_ahash_digest(cryptd_req);

0 commit comments

Comments
 (0)