diff options
| author | Stefan Hajnoczi | 2016-11-16 21:17:32 +0100 |
|---|---|---|
| committer | Michael S. Tsirkin | 2016-11-18 16:14:10 +0100 |
| commit | 600f5ce356b44d8fa5a611ff6b034eb95ecf04e7 (patch) | |
| tree | 194fa4413e7dded3bc187ff5a9e1ae7e31822182 /hw/virtio | |
| parent | docs: add PCIe devices placement guidelines (diff) | |
| download | qemu-600f5ce356b44d8fa5a611ff6b034eb95ecf04e7.tar.gz qemu-600f5ce356b44d8fa5a611ff6b034eb95ecf04e7.tar.xz qemu-600f5ce356b44d8fa5a611ff6b034eb95ecf04e7.zip | |
virtio-crypto: fix virtio_queue_set_notification() race
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 <arei.gonglei@huawei.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Tested-by: Alexey Kardashevskiy <aik@ozlabs.ru>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Gonglei <arei.gonglei@huawei.com>
Diffstat (limited to 'hw/virtio')
| -rw-r--r-- | hw/virtio/virtio-crypto.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index 32938433b7..847dc9dafd 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -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 |
