Pull virtio fix from Michael Tsirkin: "This includes a single fix for virtio ccw error handling" * tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost: virtio/s390: handle error values in irb
Unified · Split
| @@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev, · 983 unmodified lines | |||
| 984 | return vq; | 984 | return vq; |
| 985 | } | 985 | } |
| 986 | 986 | ||
| 987 | static 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 | |||
| 987 | static void virtio_ccw_int_handler(struct ccw_device *cdev, | 1017 | static 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, · 5 unmodified lines | |||
| 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, · 9 unmodified lines | |||
| 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. */ |