Skip to content

Commit 77c51fc

Browse files
hfreudehcahca
authored andcommitted
s390/zcrypt: introduce retries on in-kernel send CPRB functions
The both functions zcrypt_send_cprb() and zcrypt_send_ep11_cprb() are used to send CPRBs in-kernel from different sources. For example the pkey module may call one of the functions in zcrypt_ep11misc.c to trigger a derive of a protected key from a secure key blob via an existing crypto card. These both functions are then the internal API to send the CPRB and receive the response. All the ioctl functions to send an CPRB down to the addressed crypto card use some kind of retry mechanism. When the first attempt fails with ENODEV, a bus rescan is triggered and a loop with retries is carried out. For the both named internal functions there was never any retry attempt made. This patch now introduces the retry code even for this both internal functions to have effectively same behavior on sending an CPRB from an in-kernel source and sending an CPRB from userspace via ioctl. Signed-off-by: Harald Freudenberger <[email protected]> Reviewed-by: Holger Dengler <[email protected]> Signed-off-by: Heiko Carstens <[email protected]>
1 parent eacf5b3 commit 77c51fc

File tree

1 file changed

+40
-2
lines changed

1 file changed

+40
-2
lines changed

drivers/s390/crypto/zcrypt_api.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,26 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
977977

978978
long zcrypt_send_cprb(struct ica_xcRB *xcrb)
979979
{
980-
return _zcrypt_send_cprb(false, &ap_perms, NULL, xcrb);
980+
struct zcrypt_track tr;
981+
int rc;
982+
983+
memset(&tr, 0, sizeof(tr));
984+
985+
do {
986+
rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
987+
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
988+
989+
/* on ENODEV failure: retry once again after a requested rescan */
990+
if (rc == -ENODEV && zcrypt_process_rescan())
991+
do {
992+
rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
993+
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
994+
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
995+
rc = -EIO;
996+
if (rc)
997+
pr_debug("%s rc=%d\n", __func__, rc);
998+
999+
return rc;
9811000
}
9821001
EXPORT_SYMBOL(zcrypt_send_cprb);
9831002

@@ -1162,7 +1181,26 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
11621181

11631182
long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
11641183
{
1165-
return _zcrypt_send_ep11_cprb(false, &ap_perms, NULL, xcrb);
1184+
struct zcrypt_track tr;
1185+
int rc;
1186+
1187+
memset(&tr, 0, sizeof(tr));
1188+
1189+
do {
1190+
rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
1191+
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
1192+
1193+
/* on ENODEV failure: retry once again after a requested rescan */
1194+
if (rc == -ENODEV && zcrypt_process_rescan())
1195+
do {
1196+
rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
1197+
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
1198+
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
1199+
rc = -EIO;
1200+
if (rc)
1201+
pr_debug("%s rc=%d\n", __func__, rc);
1202+
1203+
return rc;
11661204
}
11671205
EXPORT_SYMBOL(zcrypt_send_ep11_cprb);
11681206

0 commit comments

Comments
 (0)