s390/zcrypt: use explicit return code for flushed requests
If a AP device is removed while messages are still pending, the requests
are cancelled by calling the message receive function with an error pointer
for the reply. The message type receive handler recognize this and create
a fake hardware error TYPE82_RSP_CODE / REP82_ERROR_MACHINE_FAILURE.
The message with the hardware error then causes a printk and a return
code of -EAGAIN.
Replace the intricate scheme with an explicit return code for this sitation
and avoid the error message.
Reviewd-by: Ingo Tuchscherer <ingo.tuchscherer@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index ba1f806..7224bf7 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -1027,12 +1027,14 @@
list_for_each_entry_safe(ap_msg, next, &ap_dev->pendingq, list) {
list_del_init(&ap_msg->list);
ap_dev->pendingq_count--;
- ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->rc = -EAGAIN;
+ ap_msg->receive(ap_dev, ap_msg, NULL);
}
list_for_each_entry_safe(ap_msg, next, &ap_dev->requestq, list) {
list_del_init(&ap_msg->list);
ap_dev->requestq_count--;
- ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->rc = -EAGAIN;
+ ap_msg->receive(ap_dev, ap_msg, NULL);
}
}
@@ -1690,10 +1692,12 @@
return -EBUSY;
case AP_RESPONSE_REQ_FAC_NOT_INST:
case AP_RESPONSE_MESSAGE_TOO_BIG:
- ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-EINVAL));
+ ap_msg->rc = -EINVAL;
+ ap_msg->receive(ap_dev, ap_msg, NULL);
return -EINVAL;
default: /* Device is gone. */
- ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->rc = -ENODEV;
+ ap_msg->receive(ap_dev, ap_msg, NULL);
return -ENODEV;
}
} else {
@@ -1726,7 +1730,8 @@
if (rc == -ENODEV)
ap_dev->unregistered = 1;
} else {
- ap_msg->receive(ap_dev, ap_msg, ERR_PTR(-ENODEV));
+ ap_msg->rc = -ENODEV;
+ ap_msg->receive(ap_dev, ap_msg, NULL);
rc = -ENODEV;
}
spin_unlock_bh(&ap_dev->lock);
diff --git a/drivers/s390/crypto/ap_bus.h b/drivers/s390/crypto/ap_bus.h
index 83cc9e4..af9b705 100644
--- a/drivers/s390/crypto/ap_bus.h
+++ b/drivers/s390/crypto/ap_bus.h
@@ -187,6 +187,7 @@
unsigned long long psmid; /* Message id. */
void *message; /* Pointer to message buffer. */
size_t length; /* Message length. */
+ int rc; /* Return code for this message */
void *private; /* ap driver private pointer. */
unsigned int special:1; /* Used for special commands. */
@@ -219,6 +220,7 @@
{
ap_msg->psmid = 0;
ap_msg->length = 0;
+ ap_msg->rc = 0;
ap_msg->special = 0;
ap_msg->receive = NULL;
}
diff --git a/drivers/s390/crypto/zcrypt_msgtype50.c b/drivers/s390/crypto/zcrypt_msgtype50.c
index 6c9af13..71ceee9 100644
--- a/drivers/s390/crypto/zcrypt_msgtype50.c
+++ b/drivers/s390/crypto/zcrypt_msgtype50.c
@@ -395,10 +395,8 @@
int length;
/* Copy the reply message to the request message buffer. */
- if (IS_ERR(reply)) {
- memcpy(msg->message, &error_reply, sizeof(error_reply));
- goto out;
- }
+ if (!reply)
+ goto out; /* ap_msg->rc indicates the error */
t80h = reply->message;
if (t80h->type == TYPE80_RSP_CODE) {
if (ap_dev->device_type == AP_DEVICE_TYPE_CEX2A)
@@ -449,10 +447,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, mex->outputdata,
- mex->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, mex->outputdata,
+ mex->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -493,10 +493,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, crt->outputdata,
- crt->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, crt->outputdata,
+ crt->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
diff --git a/drivers/s390/crypto/zcrypt_msgtype6.c b/drivers/s390/crypto/zcrypt_msgtype6.c
index 46b324c..7476221 100644
--- a/drivers/s390/crypto/zcrypt_msgtype6.c
+++ b/drivers/s390/crypto/zcrypt_msgtype6.c
@@ -829,10 +829,8 @@
int length;
/* Copy the reply message to the request message buffer. */
- if (IS_ERR(reply)) {
- memcpy(msg->message, &error_reply, sizeof(error_reply));
- goto out;
- }
+ if (!reply)
+ goto out; /* ap_msg->rc indicates the error */
t86r = reply->message;
if (t86r->hdr.type == TYPE86_RSP_CODE &&
t86r->cprbx.cprb_ver_id == 0x02) {
@@ -880,10 +878,8 @@
int length;
/* Copy the reply message to the request message buffer. */
- if (IS_ERR(reply)) {
- memcpy(msg->message, &error_reply, sizeof(error_reply));
- goto out;
- }
+ if (!reply)
+ goto out; /* ap_msg->rc indicates the error */
t86r = reply->message;
if (t86r->hdr.type == TYPE86_RSP_CODE &&
t86r->cprbx.cprb_ver_id == 0x04) {
@@ -935,10 +931,13 @@
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&resp_type.work);
- if (rc == 0)
- rc = convert_response_ica(zdev, &ap_msg, mex->outputdata,
- mex->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response_ica(zdev, &ap_msg,
+ mex->outputdata,
+ mex->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -976,10 +975,13 @@
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&resp_type.work);
- if (rc == 0)
- rc = convert_response_ica(zdev, &ap_msg, crt->outputdata,
- crt->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response_ica(zdev, &ap_msg,
+ crt->outputdata,
+ crt->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -1017,9 +1019,11 @@
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&resp_type.work);
- if (rc == 0)
- rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response_xcrb(zdev, &ap_msg, xcRB);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -1057,9 +1061,12 @@
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&resp_type.work);
- if (rc == 0)
- rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
- else /* Signal pending. */
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response_ep11_xcrb(zdev, &ap_msg, xcrb);
+ } else
+ /* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -1096,9 +1103,11 @@
init_completion(&resp_type.work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&resp_type.work);
- if (rc == 0)
- rc = convert_response_rng(zdev, &ap_msg, buffer);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response_rng(zdev, &ap_msg, buffer);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
kfree(ap_msg.message);
diff --git a/drivers/s390/crypto/zcrypt_pcica.c b/drivers/s390/crypto/zcrypt_pcica.c
index 2f22020..6af9c9f 100644
--- a/drivers/s390/crypto/zcrypt_pcica.c
+++ b/drivers/s390/crypto/zcrypt_pcica.c
@@ -258,10 +258,8 @@
int length;
/* Copy the reply message to the request message buffer. */
- if (IS_ERR(reply)) {
- memcpy(msg->message, &error_reply, sizeof(error_reply));
- goto out;
- }
+ if (!reply)
+ goto out; /* ap_msg->rc indicates the error */
t84h = reply->message;
if (t84h->code == TYPE84_RSP_CODE) {
length = min(PCICA_MAX_RESPONSE_SIZE, (int) t84h->len);
@@ -302,10 +300,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, mex->outputdata,
- mex->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, mex->outputdata,
+ mex->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -341,10 +341,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, crt->outputdata,
- crt->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, crt->outputdata,
+ crt->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
diff --git a/drivers/s390/crypto/zcrypt_pcicc.c b/drivers/s390/crypto/zcrypt_pcicc.c
index 9f18876..4cf2115 100644
--- a/drivers/s390/crypto/zcrypt_pcicc.c
+++ b/drivers/s390/crypto/zcrypt_pcicc.c
@@ -461,10 +461,8 @@
int length;
/* Copy the reply message to the request message buffer. */
- if (IS_ERR(reply)) {
- memcpy(msg->message, &error_reply, sizeof(error_reply));
- goto out;
- }
+ if (!reply)
+ goto out; /* ap_msg->rc indicates the error */
t86r = reply->message;
if (t86r->hdr.type == TYPE86_RSP_CODE &&
t86r->cprb.cprb_ver_id == 0x01) {
@@ -508,10 +506,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, mex->outputdata,
- mex->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, mex->outputdata,
+ mex->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free:
@@ -548,10 +548,12 @@
init_completion(&work);
ap_queue_message(zdev->ap_dev, &ap_msg);
rc = wait_for_completion_interruptible(&work);
- if (rc == 0)
- rc = convert_response(zdev, &ap_msg, crt->outputdata,
- crt->outputdatalength);
- else
+ if (rc == 0) {
+ rc = ap_msg.rc;
+ if (rc == 0)
+ rc = convert_response(zdev, &ap_msg, crt->outputdata,
+ crt->outputdatalength);
+ } else
/* Signal pending. */
ap_cancel_message(zdev->ap_dev, &ap_msg);
out_free: