[PATCH v6 5/9] s390/crypto: Fix handling of EBUSY in PAES when req is pushed to crypto engine
Harald Freudenberger <[email protected]>
| Newsgroups | org.kernel.vger.linux-s390 |
|---|---|
| Message-ID | <[email protected]> |
When a request is transferred to the engine via
crypto_transfer_skcipher_request_to_engine() there are two return
codes signaling a successful transfer: EINPROGRESS and EBUSY. However
the correct handling of EBUSY was missing and has been added as a
return code indicating a successful transfer to the crypto engine.
Fixes: 6cd87cb5ef6c ("s390/crypto: Rework protected key AES for true asynch support")
Signed-off-by: Harald Freudenberger <[email protected]>
Reviewed-by: Holger Dengler <[email protected]>
Cc: [email protected] # 6.16+
---
arch/s390/crypto/paes_s390.c | 36 ++++++++++++++++++++++++------------
1 file changed, 24 insertions(+), 12 deletions(-)
diff --git a/arch/s390/crypto/paes_s390.c b/arch/s390/crypto/paes_s390.c
index 03446bfac37f..2048327c1ffe 100644
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -463,6 +463,7 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm);
+ bool cleanup = true;
int rc;
/*
@@ -494,15 +495,17 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS && walk->nbytes)
+ if (cleanup && walk->nbytes)
skcipher_walk_done(walk, rc);
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc);
return rc;
@@ -732,6 +735,7 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm);
+ bool cleanup = true;
int rc;
/*
@@ -763,15 +767,17 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS && walk->nbytes)
+ if (cleanup && walk->nbytes)
skcipher_walk_done(walk, rc);
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc);
return rc;
@@ -1059,6 +1065,7 @@ static int ctr_paes_crypt(struct skcipher_request *req)
struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm);
+ bool cleanup = true;
int rc;
/*
@@ -1089,15 +1096,17 @@ static int ctr_paes_crypt(struct skcipher_request *req)
if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS && walk->nbytes)
+ if (cleanup && walk->nbytes)
skcipher_walk_done(walk, rc);
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc);
return rc;
@@ -1498,6 +1507,7 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
struct s390_pxts_ctx *ctx = crypto_skcipher_ctx(tfm);
struct skcipher_walk *walk = &req_ctx->walk;
bool tested = crypto_skcipher_tested(tfm);
+ bool cleanup = true;
int rc;
/*
@@ -1529,15 +1539,17 @@ static inline int xts_paes_crypt(struct skcipher_request *req, unsigned long mod
if (rc == 0 || rc == -EKEYEXPIRED) {
atomic_inc(&ctx->via_engine_ctr);
rc = crypto_transfer_skcipher_request_to_engine(paes_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS && walk->nbytes)
+ if (cleanup && walk->nbytes)
skcipher_walk_done(walk, rc);
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(&req_ctx->param, sizeof(req_ctx->param));
pr_debug("rc=%d\n", rc);
return rc;
--
2.43.0