aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJason Wang <jasowang@redhat.com>2019-05-17 00:29:51 -0400
committerMichael S. Tsirkin <mst@redhat.com>2019-05-27 11:08:23 -0400
commite79b431fb901ba1106670bcc80b9b617b25def7d (patch)
treee23a1637f25ac3f5c980cf225baaee363fb2d23c
parente2412c07f8f3040593dfb88207865a3cd58680c0 (diff)
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>
-rw-r--r--drivers/vhost/vsock.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 47c6d4d43c70..814bed72d793 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -86,6 +86,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
86 struct vhost_virtqueue *vq) 86 struct vhost_virtqueue *vq)
87{ 87{
88 struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX]; 88 struct vhost_virtqueue *tx_vq = &vsock->vqs[VSOCK_VQ_TX];
89 int pkts = 0, total_len = 0;
89 bool added = false; 90 bool added = false;
90 bool restart_tx = false; 91 bool restart_tx = false;
91 92
@@ -97,7 +98,7 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
97 /* Avoid further vmexits, we're already processing the virtqueue */ 98 /* Avoid further vmexits, we're already processing the virtqueue */
98 vhost_disable_notify(&vsock->dev, vq); 99 vhost_disable_notify(&vsock->dev, vq);
99 100
100 for (;;) { 101 do {
101 struct virtio_vsock_pkt *pkt; 102 struct virtio_vsock_pkt *pkt;
102 struct iov_iter iov_iter; 103 struct iov_iter iov_iter;
103 unsigned out, in; 104 unsigned out, in;
@@ -182,8 +183,9 @@ vhost_transport_do_send_pkt(struct vhost_vsock *vsock,
182 */ 183 */
183 virtio_transport_deliver_tap_pkt(pkt); 184 virtio_transport_deliver_tap_pkt(pkt);
184 185
186 total_len += pkt->len;
185 virtio_transport_free_pkt(pkt); 187 virtio_transport_free_pkt(pkt);
186 } 188 } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len)));
187 if (added) 189 if (added)
188 vhost_signal(&vsock->dev, vq); 190 vhost_signal(&vsock->dev, vq);
189 191
@@ -358,7 +360,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
358 struct vhost_vsock *vsock = container_of(vq->dev, struct vhost_vsock, 360 struct vhost_vsock *vsock = container_of(vq->dev, struct vhost_vsock,
359 dev); 361 dev);
360 struct virtio_vsock_pkt *pkt; 362 struct virtio_vsock_pkt *pkt;
361 int head; 363 int head, pkts = 0, total_len = 0;
362 unsigned int out, in; 364 unsigned int out, in;
363 bool added = false; 365 bool added = false;
364 366
@@ -368,7 +370,7 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
368 goto out; 370 goto out;
369 371
370 vhost_disable_notify(&vsock->dev, vq); 372 vhost_disable_notify(&vsock->dev, vq);
371 for (;;) { 373 do {
372 u32 len; 374 u32 len;
373 375
374 if (!vhost_vsock_more_replies(vsock)) { 376 if (!vhost_vsock_more_replies(vsock)) {
@@ -409,9 +411,11 @@ static void vhost_vsock_handle_tx_kick(struct vhost_work *work)
409 else 411 else
410 virtio_transport_free_pkt(pkt); 412 virtio_transport_free_pkt(pkt);
411 413
412 vhost_add_used(vq, head, sizeof(pkt->hdr) + len); 414 len += sizeof(pkt->hdr);
415 vhost_add_used(vq, head, len);
416 total_len += len;
413 added = true; 417 added = true;
414 } 418 } while(likely(!vhost_exceeds_weight(vq, ++pkts, total_len)));
415 419
416no_more_replies: 420no_more_replies:
417 if (added) 421 if (added)