History

Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost

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

Linus Torvalds committed 10 years ago

Commit ea828132 parents de37937 74a599f1 file · +37 −25Browse files

Unified · Split

drivers/s390/virtio/virtio_ccw.c+37−25
@@ -984,6 +984,36 @@ static struct virtqueue *virtio_ccw_vq_by_ind(struct virtio_ccw_device *vcdev, · 983 unmodified lines
984984 return vq;
985985 }
986986
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+
9871017 static void virtio_ccw_int_handler(struct ccw_device *cdev,
9881018 unsigned long intparm,
9891019 struct irb *irb)
@@ -995,6 +1025,12 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev, · 5 unmodified lines
9951025
9961026 if (!vcdev)
9971027 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+ }
9981034 /* Check if it's a notification from the host. */
9991035 if ((intparm == 0) &&
10001036 (scsw_stctl(&irb->scsw) ==
@@ -1010,31 +1046,7 @@ static void virtio_ccw_int_handler(struct ccw_device *cdev, · 9 unmodified lines
10101046 /* Map everything else to -EIO. */
10111047 vcdev->err = -EIO;
10121048 }
1013− if (vcdev->curr_io & 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− }
1049+ virtio_ccw_check_activity(vcdev, activity);
10381050 for_each_set_bit(i, &vcdev->indicators,
10391051 sizeof(vcdev->indicators) * BITS_PER_BYTE) {
10401052 /* The bit clear must happen before the vring kick. */