s390/zcrypt: provide apfs failure code on type 86 error reply
authorHarald Freudenberger <freude@linux.ibm.com>
Thu, 4 Oct 2018 13:37:49 +0000 (15:37 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 9 Oct 2018 09:21:36 +0000 (11:21 +0200)
The apfs field (AP final status) is set on transport
protocol failures (reply code 0x90) for type 86 replies.
For CCA cprbs this value is copied into the xcrb status
field which gives userspace a hint for the failure reason.
However, for EP11 cprbs there is no such status field
in the xcrb struct. So now regardless of the request
type, if a reply type 86 with transport protocol failure
is seen, the apfs value is printed as part of the debug
message. So the user has a chance to see the apfs value
without using a special build kernel.

Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_error.h

index 26f1cd669e901dc47c1c7e89325eb39109b7d26e..bb7ed341baaf1fe8fcd573de3c4d6f141ced5ce1 100644 (file)
@@ -822,6 +822,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
        trace_s390_zcrypt_req(xcRB, TB_ZSECSENDCPRB);
 
+       xcRB->status = 0;
        ap_init_message(&ap_msg);
        rc = get_cprb_fc(xcRB, &ap_msg, &func_code, &domain);
        if (rc)
@@ -1321,7 +1322,8 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
                                rc = _zcrypt_send_cprb(perms, &xcRB);
                        } while (rc == -EAGAIN);
                if (rc)
-                       ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d\n", rc);
+                       ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDCPRB rc=%d status=0x%x\n",
+                                  rc, xcRB.status);
                if (copy_to_user(uxcRB, &xcRB, sizeof(xcRB)))
                        return -EFAULT;
                return rc;
index 663dbdaa85b3a9676b43ceaa35c86baff16790d1..240b27f3f5f6ad088b436d0eb843982b5d01dad7 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/atomic.h>
 #include "zcrypt_debug.h"
 #include "zcrypt_api.h"
+#include "zcrypt_msgtype6.h"
 
 /**
  * Reply Messages
@@ -112,6 +113,27 @@ static inline int convert_error(struct zcrypt_queue *zq,
                           card, queue, ehdr->reply_code);
                return -EAGAIN;
        case REP82_ERROR_TRANSPORT_FAIL:
+               /* Card or infrastructure failure, disable card */
+               atomic_set(&zcrypt_rescan_req, 1);
+               zq->online = 0;
+               pr_err("Cryptographic device %02x.%04x failed and was set offline\n",
+                      card, queue);
+               /* For type 86 response show the apfs value (failure reason) */
+               if (ehdr->type == TYPE86_RSP_CODE) {
+                       struct {
+                               struct type86_hdr hdr;
+                               struct type86_fmt2_ext fmt2;
+                       } __packed * head = reply->message;
+                       unsigned int apfs = *((u32 *)head->fmt2.apfs);
+
+                       ZCRYPT_DBF(DBF_ERR,
+                                  "device=%02x.%04x reply=0x%02x apfs=0x%x => online=0 rc=EAGAIN\n",
+                                  card, queue, apfs, ehdr->reply_code);
+               } else
+                       ZCRYPT_DBF(DBF_ERR,
+                                  "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n",
+                                  card, queue, ehdr->reply_code);
+               return -EAGAIN;
        case REP82_ERROR_MACHINE_FAILURE:
        //   REP88_ERROR_MODULE_FAILURE         // '10' CEX2A
                /* If a card fails disable it and repeat the request. */