Skip to content

Commit

Permalink
s390/zcrypt: introduce retries on in-kernel send CPRB functions
Browse files Browse the repository at this point in the history
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 <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
  • Loading branch information
hfreude authored and hcahca committed Mar 7, 2024
1 parent eacf5b3 commit 77c51fc
Showing 1 changed file with 40 additions and 2 deletions.
42 changes: 40 additions & 2 deletions drivers/s390/crypto/zcrypt_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,26 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,

long zcrypt_send_cprb(struct ica_xcRB *xcrb)
{
return _zcrypt_send_cprb(false, &ap_perms, NULL, xcrb);
struct zcrypt_track tr;
int rc;

memset(&tr, 0, sizeof(tr));

do {
rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);

/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
rc = _zcrypt_send_cprb(false, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
pr_debug("%s rc=%d\n", __func__, rc);

return rc;
}
EXPORT_SYMBOL(zcrypt_send_cprb);

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

long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
{
return _zcrypt_send_ep11_cprb(false, &ap_perms, NULL, xcrb);
struct zcrypt_track tr;
int rc;

memset(&tr, 0, sizeof(tr));

do {
rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);

/* on ENODEV failure: retry once again after a requested rescan */
if (rc == -ENODEV && zcrypt_process_rescan())
do {
rc = _zcrypt_send_ep11_cprb(false, &ap_perms, &tr, xcrb);
} while (rc == -EAGAIN && ++tr.again_counter < TRACK_AGAIN_MAX);
if (rc == -EAGAIN && tr.again_counter >= TRACK_AGAIN_MAX)
rc = -EIO;
if (rc)
pr_debug("%s rc=%d\n", __func__, rc);

return rc;
}
EXPORT_SYMBOL(zcrypt_send_ep11_cprb);

Expand Down

0 comments on commit 77c51fc

Please sign in to comment.