]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
vhost: scsi: add weight support
authorJason Wang <jasowang@redhat.com>
Fri, 17 May 2019 04:29:52 +0000 (00:29 -0400)
committerBen Hutchings <ben@decadent.org.uk>
Tue, 13 Aug 2019 11:39:24 +0000 (12:39 +0100)
commit c1ea02f15ab5efb3e93fc3144d895410bf79fcf2 upstream.

This patch will check the weight and exit the loop if we exceeds the
weight. This is useful for preventing scsi kthread from hogging cpu
which is guest triggerable.

This addresses CVE-2019-3900.

Cc: Paolo Bonzini <pbonzini@redhat.com>
Cc: Stefan Hajnoczi <stefanha@redhat.com>
Fixes: 057cbf49a1f0 ("tcm_vhost: Initial merge for vhost level target fabric driver")
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
[bwh: Backported to 3.16:
 - Drop changes in vhost_scsi_ctl_handle_vq()
 - Adjust context]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
drivers/vhost/scsi.c

index fc2febfe8e4fcf0548a4b3788162f98cd93b9e46..498de4bfcd60ee9931f083197097425c392c7b6e 100644 (file)
@@ -998,7 +998,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
        u64 tag;
        u32 exp_data_len, data_first, data_num, data_direction, prot_first;
        unsigned out, in, i;
-       int head, ret, data_niov, prot_niov, prot_bytes;
+       int head, ret, data_niov, prot_niov, prot_bytes, c = 0;
        size_t req_size;
        u16 lun;
        u8 *target, *lunp, task_attr;
@@ -1016,7 +1016,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
 
        vhost_disable_notify(&vs->dev, vq);
 
-       for (;;) {
+       do {
                head = vhost_get_vq_desc(vq, vq->iov,
                                        ARRAY_SIZE(vq->iov), &out, &in,
                                        NULL, NULL);
@@ -1219,7 +1219,7 @@ vhost_scsi_handle_vq(struct vhost_scsi *vs, struct vhost_virtqueue *vq)
                 */
                INIT_WORK(&cmd->work, tcm_vhost_submission_work);
                queue_work(tcm_vhost_workqueue, &cmd->work);
-       }
+       } while (likely(!vhost_exceeds_weight(vq, ++c, 0)));
 
        mutex_unlock(&vq->mutex);
        return;