Like tell_host(), stats_handle_request() ignores the return value of
virtqueue_add_outbuf() and kicks the queue regardless. The same "we
should always be able to add one buffer to an empty queue" assumption
does not hold once the virtqueue has been broken (e.g. on device
shutdown), where the add fails with -EIO. Unlike tell_host() it does
not wait_event() afterwards so it cannot hang, but it still kicks a
queue with nothing queued.

Warn and bail out on failure, mirroring tell_host() and
virtballoon_free_page_report().

Suggested-by: David Hildenbrand <[email protected]>
Signed-off-by: Denis V. Lunev <[email protected]>
---
 drivers/virtio/virtio_balloon.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/virtio/virtio_balloon.c b/drivers/virtio/virtio_balloon.c
index 0866a8781f0b..454bbb77331d 100644
--- a/drivers/virtio/virtio_balloon.c
+++ b/drivers/virtio/virtio_balloon.c
@@ -445,6 +445,7 @@ static void stats_handle_request(struct virtio_balloon *vb)
        struct virtqueue *vq;
        struct scatterlist sg;
        unsigned int len, num_stats;
+       int err;
 
        num_stats = update_balloon_stats(vb);
 
@@ -452,7 +453,9 @@ static void stats_handle_request(struct virtio_balloon *vb)
        if (!virtqueue_get_buf(vq, &len))
                return;
        sg_init_one(&sg, vb->stats, sizeof(vb->stats[0]) * num_stats);
-       virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+       err = virtqueue_add_outbuf(vq, &sg, 1, vb, GFP_KERNEL);
+       if (WARN_ON_ONCE(err))
+               return;
        virtqueue_kick(vq);
 }
 
-- 
2.53.0


Reply via email to