s390/zcrypt: Handle ep11 cprb return code
authorHarald Freudenberger <freude@linux.ibm.com>
Mon, 25 Mar 2024 08:59:19 +0000 (09:59 +0100)
committerAlexander Gordeev <agordeev@linux.ibm.com>
Wed, 1 May 2024 09:52:54 +0000 (11:52 +0200)
An EP11 reply cprb contains a field ret_code which may
hold an error code different than the error code stored
in the payload of the cprb. As of now all the EP11 misc
functions do not evaluate this field but focus on the
error code in the payload.

Before checking the payload error, first the cprb error
field should be evaluated which is introduced with this
patch.

If the return code value 0x000c0003 is seen, this
indicates a busy situation which is reflected by
-EBUSY in the zcrpyt_ep11misc.c low level function.
A higher level caller should consider to retry after
waiting a dedicated duration (say 1 second).

Fixes: ed6776c96c60 ("s390/crypto: remove retry loop with sleep from PAES pkey invocation")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Ingo Franzki <ifranzki@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Signed-off-by: Alexander Gordeev <agordeev@linux.ibm.com>
drivers/s390/crypto/zcrypt_ep11misc.c

index a1b55fd..9bcf8fc 100644 (file)
@@ -563,6 +563,22 @@ static int check_reply_pl(const u8 *pl, const char *func)
        return 0;
 }
 
+/* Check ep11 reply cprb, return 0 or suggested errno value. */
+static int check_reply_cprb(const struct ep11_cprb *rep, const char *func)
+{
+       /* check ep11 reply return code field */
+       if (rep->ret_code) {
+               ZCRYPT_DBF_ERR("%s ep11 reply ret_code=0x%08x\n", __func__,
+                              rep->ret_code);
+               if (rep->ret_code == 0x000c0003)
+                       return -EBUSY;
+               else
+                       return -EIO;
+       }
+
+       return 0;
+}
+
 /*
  * Helper function which does an ep11 query with given query type.
  */
@@ -627,6 +643,12 @@ static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -877,6 +899,12 @@ static int _ep11_genaeskey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1028,6 +1056,12 @@ static int ep11_cryptsingle(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1185,6 +1219,12 @@ static int _ep11_unwrapkey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;
@@ -1339,6 +1379,12 @@ static int _ep11_wrapkey(u16 card, u16 domain,
                goto out;
        }
 
+       /* check ep11 reply cprb */
+       rc = check_reply_cprb(rep, __func__);
+       if (rc)
+               goto out;
+
+       /* check payload */
        rc = check_reply_pl((u8 *)rep_pl, __func__);
        if (rc)
                goto out;