]> Git Repo - qemu.git/commitdiff
virtio-crypto: fix virtio_queue_set_notification() race
authorStefan Hajnoczi <[email protected]>
Wed, 16 Nov 2016 20:17:32 +0000 (20:17 +0000)
committerMichael S. Tsirkin <[email protected]>
Fri, 18 Nov 2016 15:14:10 +0000 (17:14 +0200)
We must check for new virtqueue buffers after re-enabling notifications.
This prevents the race condition where the guest added buffers just
after we stopped popping the virtqueue but before we re-enabled
notifications.

I think the virtio-crypto code was based on virtio-net but this crucial
detail was missed.  virtio-net does not have the race condition because
it processes the virtqueue one more time after re-enabling
notifications.

Cc: Gonglei <[email protected]>
Signed-off-by: Stefan Hajnoczi <[email protected]>
Tested-by: Alexey Kardashevskiy <[email protected]>
Reviewed-by: Michael S. Tsirkin <[email protected]>
Signed-off-by: Michael S. Tsirkin <[email protected]>
Reviewed-by: Gonglei <[email protected]>
hw/virtio/virtio-crypto.c

index 32938433b70d99694464905fbb4a1636a9707893..847dc9dafdf42a1f2ede9185ea461ba90fbec341 100644 (file)
@@ -692,8 +692,17 @@ static void virtio_crypto_dataq_bh(void *opaque)
         return;
     }
 
-    virtio_crypto_handle_dataq(vdev, q->dataq);
-    virtio_queue_set_notification(q->dataq, 1);
+    for (;;) {
+        virtio_crypto_handle_dataq(vdev, q->dataq);
+        virtio_queue_set_notification(q->dataq, 1);
+
+        /* Are we done or did the guest add more buffers? */
+        if (virtio_queue_empty(q->dataq)) {
+            break;
+        }
+
+        virtio_queue_set_notification(q->dataq, 0);
+    }
 }
 
 static void
This page took 0.027873 seconds and 4 git commands to generate.