| .. | .. |
|---|
| 1 | 1 | /* SPDX-License-Identifier: GPL-2.0+ */ |
|---|
| 2 | 2 | /* |
|---|
| 3 | | - * zcrypt 2.1.0 |
|---|
| 4 | | - * |
|---|
| 5 | 3 | * Copyright IBM Corp. 2001, 2006 |
|---|
| 6 | 4 | * Author(s): Robert Burroughs |
|---|
| 7 | 5 | * Eric Rossman (edrossma@us.ibm.com) |
|---|
| .. | .. |
|---|
| 16 | 14 | #include <linux/atomic.h> |
|---|
| 17 | 15 | #include "zcrypt_debug.h" |
|---|
| 18 | 16 | #include "zcrypt_api.h" |
|---|
| 17 | +#include "zcrypt_msgtype6.h" |
|---|
| 19 | 18 | |
|---|
| 20 | 19 | /** |
|---|
| 21 | 20 | * Reply Messages |
|---|
| .. | .. |
|---|
| 53 | 52 | #define REP82_ERROR_INVALID_COMMAND 0x30 |
|---|
| 54 | 53 | #define REP82_ERROR_MALFORMED_MSG 0x40 |
|---|
| 55 | 54 | #define REP82_ERROR_INVALID_SPECIAL_CMD 0x41 |
|---|
| 56 | | -#define REP82_ERROR_INVALID_DOMAIN_PRECHECK 0x42 |
|---|
| 57 | 55 | #define REP82_ERROR_RESERVED_FIELDO 0x50 /* old value */ |
|---|
| 58 | 56 | #define REP82_ERROR_WORD_ALIGNMENT 0x60 |
|---|
| 59 | 57 | #define REP82_ERROR_MESSAGE_LENGTH 0x80 |
|---|
| .. | .. |
|---|
| 68 | 66 | #define REP82_ERROR_ZERO_BUFFER_LEN 0xB0 |
|---|
| 69 | 67 | |
|---|
| 70 | 68 | #define REP88_ERROR_MODULE_FAILURE 0x10 |
|---|
| 71 | | - |
|---|
| 72 | 69 | #define REP88_ERROR_MESSAGE_TYPE 0x20 |
|---|
| 73 | 70 | #define REP88_ERROR_MESSAGE_MALFORMD 0x22 |
|---|
| 74 | 71 | #define REP88_ERROR_MESSAGE_LENGTH 0x23 |
|---|
| .. | .. |
|---|
| 81 | 78 | static inline int convert_error(struct zcrypt_queue *zq, |
|---|
| 82 | 79 | struct ap_message *reply) |
|---|
| 83 | 80 | { |
|---|
| 84 | | - struct error_hdr *ehdr = reply->message; |
|---|
| 81 | + struct error_hdr *ehdr = reply->msg; |
|---|
| 85 | 82 | int card = AP_QID_CARD(zq->queue->qid); |
|---|
| 86 | 83 | int queue = AP_QID_QUEUE(zq->queue->qid); |
|---|
| 87 | 84 | |
|---|
| 88 | 85 | switch (ehdr->reply_code) { |
|---|
| 89 | | - case REP82_ERROR_OPERAND_INVALID: |
|---|
| 90 | | - case REP82_ERROR_OPERAND_SIZE: |
|---|
| 91 | | - case REP82_ERROR_EVEN_MOD_IN_OPND: |
|---|
| 92 | | - case REP88_ERROR_MESSAGE_MALFORMD: |
|---|
| 93 | | - case REP82_ERROR_INVALID_DOMAIN_PRECHECK: |
|---|
| 94 | | - case REP82_ERROR_INVALID_DOMAIN_PENDING: |
|---|
| 95 | | - case REP82_ERROR_INVALID_SPECIAL_CMD: |
|---|
| 96 | | - case REP82_ERROR_FILTERED_BY_HYPERVISOR: |
|---|
| 97 | | - // REP88_ERROR_INVALID_KEY // '82' CEX2A |
|---|
| 98 | | - // REP88_ERROR_OPERAND // '84' CEX2A |
|---|
| 99 | | - // REP88_ERROR_OPERAND_EVEN_MOD // '85' CEX2A |
|---|
| 100 | | - /* Invalid input data. */ |
|---|
| 86 | + case REP82_ERROR_INVALID_MSG_LEN: /* 0x23 */ |
|---|
| 87 | + case REP82_ERROR_RESERVD_FIELD: /* 0x24 */ |
|---|
| 88 | + case REP82_ERROR_FORMAT_FIELD: /* 0x29 */ |
|---|
| 89 | + case REP82_ERROR_MALFORMED_MSG: /* 0x40 */ |
|---|
| 90 | + case REP82_ERROR_INVALID_SPECIAL_CMD: /* 0x41 */ |
|---|
| 91 | + case REP82_ERROR_MESSAGE_LENGTH: /* 0x80 */ |
|---|
| 92 | + case REP82_ERROR_OPERAND_INVALID: /* 0x82 */ |
|---|
| 93 | + case REP82_ERROR_OPERAND_SIZE: /* 0x84 */ |
|---|
| 94 | + case REP82_ERROR_EVEN_MOD_IN_OPND: /* 0x85 */ |
|---|
| 95 | + case REP82_ERROR_INVALID_DOMAIN_PENDING: /* 0x8A */ |
|---|
| 96 | + case REP82_ERROR_FILTERED_BY_HYPERVISOR: /* 0x8B */ |
|---|
| 97 | + case REP82_ERROR_PACKET_TRUNCATED: /* 0xA0 */ |
|---|
| 98 | + case REP88_ERROR_MESSAGE_MALFORMD: /* 0x22 */ |
|---|
| 99 | + case REP88_ERROR_KEY_TYPE: /* 0x34 */ |
|---|
| 100 | + /* RY indicates malformed request */ |
|---|
| 101 | 101 | ZCRYPT_DBF(DBF_WARN, |
|---|
| 102 | | - "device=%02x.%04x reply=0x%02x => rc=EINVAL\n", |
|---|
| 102 | + "dev=%02x.%04x RY=0x%02x => rc=EINVAL\n", |
|---|
| 103 | 103 | card, queue, ehdr->reply_code); |
|---|
| 104 | 104 | return -EINVAL; |
|---|
| 105 | | - case REP82_ERROR_MESSAGE_TYPE: |
|---|
| 106 | | - // REP88_ERROR_MESSAGE_TYPE // '20' CEX2A |
|---|
| 105 | + case REP82_ERROR_MACHINE_FAILURE: /* 0x10 */ |
|---|
| 106 | + case REP82_ERROR_MESSAGE_TYPE: /* 0x20 */ |
|---|
| 107 | + case REP82_ERROR_TRANSPORT_FAIL: /* 0x90 */ |
|---|
| 107 | 108 | /* |
|---|
| 108 | | - * To sent a message of the wrong type is a bug in the |
|---|
| 109 | | - * device driver. Send error msg, disable the device |
|---|
| 110 | | - * and then repeat the request. |
|---|
| 109 | + * Msg to wrong type or card/infrastructure failure. |
|---|
| 110 | + * Trigger rescan of the ap bus, trigger retry request. |
|---|
| 111 | 111 | */ |
|---|
| 112 | 112 | atomic_set(&zcrypt_rescan_req, 1); |
|---|
| 113 | | - zq->online = 0; |
|---|
| 114 | | - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", |
|---|
| 115 | | - card, queue); |
|---|
| 116 | | - ZCRYPT_DBF(DBF_ERR, |
|---|
| 117 | | - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", |
|---|
| 118 | | - card, queue, ehdr->reply_code); |
|---|
| 119 | | - return -EAGAIN; |
|---|
| 120 | | - case REP82_ERROR_TRANSPORT_FAIL: |
|---|
| 121 | | - case REP82_ERROR_MACHINE_FAILURE: |
|---|
| 122 | | - // REP88_ERROR_MODULE_FAILURE // '10' CEX2A |
|---|
| 123 | | - /* If a card fails disable it and repeat the request. */ |
|---|
| 124 | | - atomic_set(&zcrypt_rescan_req, 1); |
|---|
| 125 | | - zq->online = 0; |
|---|
| 126 | | - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", |
|---|
| 127 | | - card, queue); |
|---|
| 128 | | - ZCRYPT_DBF(DBF_ERR, |
|---|
| 129 | | - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", |
|---|
| 130 | | - card, queue, ehdr->reply_code); |
|---|
| 113 | + /* For type 86 response show the apfs value (failure reason) */ |
|---|
| 114 | + if (ehdr->reply_code == REP82_ERROR_TRANSPORT_FAIL && |
|---|
| 115 | + ehdr->type == TYPE86_RSP_CODE) { |
|---|
| 116 | + struct { |
|---|
| 117 | + struct type86_hdr hdr; |
|---|
| 118 | + struct type86_fmt2_ext fmt2; |
|---|
| 119 | + } __packed * head = reply->msg; |
|---|
| 120 | + unsigned int apfs = *((u32 *)head->fmt2.apfs); |
|---|
| 121 | + |
|---|
| 122 | + ZCRYPT_DBF(DBF_WARN, |
|---|
| 123 | + "dev=%02x.%04x RY=0x%02x apfs=0x%x => bus rescan, rc=EAGAIN\n", |
|---|
| 124 | + card, queue, ehdr->reply_code, apfs); |
|---|
| 125 | + } else |
|---|
| 126 | + ZCRYPT_DBF(DBF_WARN, |
|---|
| 127 | + "dev=%02x.%04x RY=0x%02x => bus rescan, rc=EAGAIN\n", |
|---|
| 128 | + card, queue, ehdr->reply_code); |
|---|
| 131 | 129 | return -EAGAIN; |
|---|
| 132 | 130 | default: |
|---|
| 133 | | - zq->online = 0; |
|---|
| 134 | | - pr_err("Cryptographic device %02x.%04x failed and was set offline\n", |
|---|
| 135 | | - card, queue); |
|---|
| 136 | | - ZCRYPT_DBF(DBF_ERR, |
|---|
| 137 | | - "device=%02x.%04x reply=0x%02x => online=0 rc=EAGAIN\n", |
|---|
| 131 | + /* Assume request is valid and a retry will be worth it */ |
|---|
| 132 | + ZCRYPT_DBF(DBF_WARN, |
|---|
| 133 | + "dev=%02x.%04x RY=0x%02x => rc=EAGAIN\n", |
|---|
| 138 | 134 | card, queue, ehdr->reply_code); |
|---|
| 139 | | - return -EAGAIN; /* repeat the request on a different device. */ |
|---|
| 135 | + return -EAGAIN; |
|---|
| 140 | 136 | } |
|---|
| 141 | 137 | } |
|---|
| 142 | 138 | |
|---|