Patch "virtio: Improve vq->broken access to avoid any compiler optimization" has been added to the 4.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    virtio: Improve vq->broken access to avoid any compiler optimization

to the 4.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     virtio-improve-vq-broken-access-to-avoid-any-compile.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 4ea38b6c0a88f5b30c6ece5c033a54c33cb4f503
Author: Parav Pandit <parav@xxxxxxxxxx>
Date:   Wed Jul 21 17:26:45 2021 +0300

    virtio: Improve vq->broken access to avoid any compiler optimization
    
    [ Upstream commit 60f0779862e4ab943810187752c462e85f5fa371 ]
    
    Currently vq->broken field is read by virtqueue_is_broken() in busy
    loop in one context by virtnet_send_command().
    
    vq->broken is set to true in other process context by
    virtio_break_device(). Reader and writer are accessing it without any
    synchronization. This may lead to a compiler optimization which may
    result to optimize reading vq->broken only once.
    
    Hence, force reading vq->broken on each invocation of
    virtqueue_is_broken() and also force writing it so that such
    update is visible to the readers.
    
    It is a theoretical fix that isn't yet encountered in the field.
    
    Signed-off-by: Parav Pandit <parav@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20210721142648.1525924-2-parav@xxxxxxxxxx
    Signed-off-by: Michael S. Tsirkin <mst@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index 5cad9f41c238..cf7eccfe3469 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1150,7 +1150,7 @@ bool virtqueue_is_broken(struct virtqueue *_vq)
 {
 	struct vring_virtqueue *vq = to_vvq(_vq);
 
-	return vq->broken;
+	return READ_ONCE(vq->broken);
 }
 EXPORT_SYMBOL_GPL(virtqueue_is_broken);
 
@@ -1164,7 +1164,9 @@ void virtio_break_device(struct virtio_device *dev)
 
 	list_for_each_entry(_vq, &dev->vqs, list) {
 		struct vring_virtqueue *vq = to_vvq(_vq);
-		vq->broken = true;
+
+		/* Pairs with READ_ONCE() in virtqueue_is_broken(). */
+		WRITE_ONCE(vq->broken, true);
 	}
 }
 EXPORT_SYMBOL_GPL(virtio_break_device);



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux