Index: uspace/drv/nic/virtio-net/virtio-net.c
===================================================================
--- uspace/drv/nic/virtio-net/virtio-net.c	(revision ea6840d4abf1c2f1960ec7dcd4e1a01dc9d57c6c)
+++ uspace/drv/nic/virtio-net/virtio-net.c	(revision 417aaafbf1316f52c0f58d96f2801dea614c03ad)
@@ -155,7 +155,10 @@
     uint16_t *head)
 {
+	virtq_t *q = &vdev->queues[num];
+	fibril_mutex_lock(&q->lock);
 	uint16_t descno = *head;
 	if (descno != (uint16_t) -1U)
 		*head = virtio_virtq_desc_get_next(vdev, num, descno);
+	fibril_mutex_unlock(&q->lock);
 	return descno;
 }
@@ -171,7 +174,10 @@
     uint16_t *head, uint16_t descno)
 {
+	virtq_t *q = &vdev->queues[num];
+	fibril_mutex_lock(&q->lock);
 	virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT,
 	    *head);
 	*head = descno;
+	fibril_mutex_unlock(&q->lock);
 }
 
Index: uspace/lib/virtio/virtio-pci.h
===================================================================
--- uspace/lib/virtio/virtio-pci.h	(revision ea6840d4abf1c2f1960ec7dcd4e1a01dc9d57c6c)
+++ uspace/lib/virtio/virtio-pci.h	(revision 417aaafbf1316f52c0f58d96f2801dea614c03ad)
@@ -36,4 +36,5 @@
 #include <pci_dev_iface.h>
 #include <ddi.h>
+#include <fibril_synch.h>
 
 #define VIRTIO_PCI_CAP_CAP_LEN(c)	((c) + 2)
@@ -131,4 +132,7 @@
 	size_t size;
 
+	/** Mutex protecting access to this virtqueue */
+	fibril_mutex_t lock;
+
 	/**
 	 * Size of the queue which determines the number of descriptors and
Index: uspace/lib/virtio/virtio.c
===================================================================
--- uspace/lib/virtio/virtio.c	(revision ea6840d4abf1c2f1960ec7dcd4e1a01dc9d57c6c)
+++ uspace/lib/virtio/virtio.c	(revision 417aaafbf1316f52c0f58d96f2801dea614c03ad)
@@ -63,4 +63,5 @@
 	virtq_t *q = &vdev->queues[num];
 
+	fibril_mutex_lock(&q->lock);
 	uint16_t idx = pio_read_le16(&q->avail->idx);
 	pio_write_le16(&q->avail->ring[idx % q->queue_size], descno);
@@ -69,4 +70,5 @@
 	write_barrier();
 	pio_write_le16(q->notify, num);
+	fibril_mutex_unlock(&q->lock);
 }
 
@@ -76,7 +78,10 @@
 	virtq_t *q = &vdev->queues[num];
 
+	fibril_mutex_lock(&q->lock);
 	uint16_t last_idx = q->used_last_idx % q->queue_size;
-	if (last_idx == (pio_read_le16(&q->used->idx) % q->queue_size))
+	if (last_idx == (pio_read_le16(&q->used->idx) % q->queue_size)) {
+		fibril_mutex_unlock(&q->lock);
 		return false;
+	}
 
 	*descno = (uint16_t) pio_read_le32(&q->used->ring[last_idx].id);
@@ -84,4 +89,5 @@
 
 	q->used_last_idx++;
+	fibril_mutex_unlock(&q->lock);
 
 	return true;
@@ -132,4 +138,6 @@
 	}
 
+	fibril_mutex_initialize(&q->lock);
+
 	q->size = mem_size;
 	q->queue_size = size;
