Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

vhost: vsock: add weight support

This patch will check the weight and exit the loop if we exceeds the
weight. This is useful for preventing vsock kthread from hogging cpu
which is guest triggerable. The weight can help to avoid starving the
request from on direction while another direction is being processed.

The value of weight is picked from vhost-net.

This addresses CVE-2019-3900.

Cc: Stefan Hajnoczi <stefanha@redhat.com>
Fixes: 433fc58e6bf2 ("VSOCK: Introduce vhost_vsock.ko")
Signed-off-by: Jason Wang <jasowang@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Jason Wang and committed by
Michael S. Tsirkin
e79b431f e2412c07

+10 -6
+10 -6
drivers/vhost/vsock.c
··· 86 86 struct vhost_virtqueue *vq) 87 87 { 88 88 struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX]; 89 + int pkts = 0, total_len = 0; 89 90 bool added = false; 90 91 bool restart_tx = false; 91 92 ··· 98 97 /* Avoid further vmexits, we're already processing the virtqueue */ 99 98 vhost_disable_notify(&vsock->dev, vq); 100 99 101 - for (;;) { 100 + do { 102 101 struct virtio_vsock_pkt *pkt; 103 102 struct iov_iter iov_iter; 104 103 unsigned out, in; ··· 183 182 */ 184 183 virtio_transport_deliver_tap_pkt(pkt); 185 184 185 + total_len += pkt->len; 186 186 virtio_transport_free_pkt(pkt); 187 - } 187 + } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len))); 188 188 if (added) 189 189 vhost_signal(&vsock->dev, vq); 190 190 ··· 360 358 struct vhost_vsock *vsock = container_of(vq->dev, struct vhost_vsock, 361 359 dev); 362 360 struct virtio_vsock_pkt *pkt; 363 - int head; 361 + int head, pkts = 0, total_len = 0; 364 362 unsigned int out, in; 365 363 bool added = false; 366 364 ··· 370 368 goto out; 371 369 372 370 vhost_disable_notify(&vsock->dev, vq); 373 - for (;;) { 371 + do { 374 372 u32 len; 375 373 376 374 if (!vhost_vsock_more_replies(vsock)) { ··· 411 409 else 412 410 virtio_transport_free_pkt(pkt); 413 411 414 - vhost_add_used(vq, head, sizeof(pkt->hdr) + len); 412 + len += sizeof(pkt->hdr); 413 + vhost_add_used(vq, head, len); 414 + total_len += len; 415 415 added = true; 416 - } 416 + } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len))); 417 417 418 418 no_more_replies: 419 419 if (added)