aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2015-12-03 11:24:00 -0500
committerMichael S. Tsirkin <mst@redhat.com>2015-12-17 03:37:33 -0500
commit74a599f09bec7419b2490039f0fb33bc8581ef7c (patch)
tree79139da3ddbac8589a09ac124440d2dfeb6f1f31
parent9f9499ae8e6415cefc4fe0a96ad0e27864353c89 (diff)
virtio/s390: handle error values in irb
The common I/O layer may pass an error value as the irb in the device's interrupt handler (for classic channel I/O). This won't happen in current virtio-ccw implementations, but it's better to be safe than sorry. Let's just return the error conveyed by the irb and clear any possible pending I/O indications. Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Reviewed-by: Guenther Hutzl <hutzl@linux.vnet.ibm.com> Reviewed-by: Pierre Morel <pmorel@linux.vnet.ibm.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
-rw-r--r--drivers/s390/virtio/virtio_ccw.c62
1 files changed, 37 insertions, 25 deletions
diff --git a/drivers/s390/virtio/virtio_ccw.c b/drivers/s390/virtio/virtio_ccw.c
index b2a1a81e6fc8..1b831598df7c 100644
--- a/drivers/s390/virtio/virtio_ccw.c
+++ b/drivers/s390/virtio/virtio_ccw.c
@@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev,
984 return vq; 984 return vq;
985} 985}
986 986
987static void virtio_ccw_check_activity(struct virtio_ccw_device *vcdev,
988 __u32 activity)
989{
990 if (vcdev->curr_io & activity) {
991 switch (activity) {
992 case VIRTIO_CCW_DOING_READ_FEAT:
993 case VIRTIO_CCW_DOING_WRITE_FEAT:
994 case VIRTIO_CCW_DOING_READ_CONFIG:
995 case VIRTIO_CCW_DOING_WRITE_CONFIG:
996 case VIRTIO_CCW_DOING_WRITE_STATUS:
997 case VIRTIO_CCW_DOING_SET_VQ:
998 case VIRTIO_CCW_DOING_SET_IND:
999 case VIRTIO_CCW_DOING_SET_CONF_IND:
1000 case VIRTIO_CCW_DOING_RESET:
1001 case VIRTIO_CCW_DOING_READ_VQ_CONF:
1002 case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
1003 case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
1004 vcdev->curr_io &= ~activity;
1005 wake_up(&vcdev->wait_q);
1006 break;
1007 default:
1008 /* don't know what to do... */
1009 dev_warn(&vcdev->cdev->dev,
1010 "Suspicious activity '%08x'\n", activity);
1011 WARN_ON(1);
1012 break;
1013 }
1014 }
1015}
1016
987static void virtio_ccw_int_handler(struct ccw_device *cdev, 1017static void virtio_ccw_int_handler(struct ccw_device *cdev,
988 unsigned long intparm, 1018 unsigned long intparm,
989 struct irb *irb) 1019 struct irb *irb)
@@ -995,6 +1025,12 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
995 1025
996 if (!vcdev) 1026 if (!vcdev)
997 return; 1027 return;
1028 if (IS_ERR(irb)) {
1029 vcdev->err = PTR_ERR(irb);
1030 virtio_ccw_check_activity(vcdev, activity);
1031 /* Don't poke around indicators, something's wrong. */
1032 return;
1033 }
998 /* Check if it's a notification from the host. */ 1034 /* Check if it's a notification from the host. */
999 if ((intparm == 0) && 1035 if ((intparm == 0) &&
1000 (scsw_stctl(&irb->scsw) == 1036 (scsw_stctl(&irb->scsw) ==
@@ -1010,31 +1046,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev,
1010 /* Map everything else to -EIO. */ 1046 /* Map everything else to -EIO. */
1011 vcdev->err = -EIO; 1047 vcdev->err = -EIO;
1012 } 1048 }
1013 if (vcdev->curr_io & activity) { 1049 virtio_ccw_check_activity(vcdev, activity);
1014 switch (activity) {
1015 case VIRTIO_CCW_DOING_READ_FEAT:
1016 case VIRTIO_CCW_DOING_WRITE_FEAT:
1017 case VIRTIO_CCW_DOING_READ_CONFIG:
1018 case VIRTIO_CCW_DOING_WRITE_CONFIG:
1019 case VIRTIO_CCW_DOING_WRITE_STATUS:
1020 case VIRTIO_CCW_DOING_SET_VQ:
1021 case VIRTIO_CCW_DOING_SET_IND:
1022 case VIRTIO_CCW_DOING_SET_CONF_IND:
1023 case VIRTIO_CCW_DOING_RESET:
1024 case VIRTIO_CCW_DOING_READ_VQ_CONF:
1025 case VIRTIO_CCW_DOING_SET_IND_ADAPTER:
1026 case VIRTIO_CCW_DOING_SET_VIRTIO_REV:
1027 vcdev->curr_io &= ~activity;
1028 wake_up(&vcdev->wait_q);
1029 break;
1030 default:
1031 /* don't know what to do... */
1032 dev_warn(&cdev->dev, "Suspicious activity '%08x'\n",
1033 activity);
1034 WARN_ON(1);
1035 break;
1036 }
1037 }
1038 for_each_set_bit(i, &vcdev->indicators, 1050 for_each_set_bit(i, &vcdev->indicators,
1039 sizeof(vcdev->indicators) * BITS_PER_BYTE) { 1051 sizeof(vcdev->indicators) * BITS_PER_BYTE) {
1040 /* The bit clear must happen before the vring kick. */ 1052 /* The bit clear must happen before the vring kick. */