Patch "Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer" has been added to the 4.14-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

    Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer

to the 4.14-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:
     drivers-hv-vmbus-prevent-load-re-ordering-when-readi.patch
and it can be found in the queue-4.14 subdirectory.

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



commit a5303a5a6eef0e777d89f4a93a85b02a000269d1
Author: Michael Kelley <mikelley@xxxxxxxxxxxxx>
Date:   Sun Mar 27 08:25:10 2022 -0700

    Drivers: hv: vmbus: Prevent load re-ordering when reading ring buffer
    
    [ Upstream commit b6cae15b5710c8097aad26a2e5e752c323ee5348 ]
    
    When reading a packet from a host-to-guest ring buffer, there is no
    memory barrier between reading the write index (to see if there is
    a packet to read) and reading the contents of the packet. The Hyper-V
    host uses store-release when updating the write index to ensure that
    writes of the packet data are completed first. On the guest side,
    the processor can reorder and read the packet data before the write
    index, and sometimes get stale packet data. Getting such stale packet
    data has been observed in a reproducible case in a VM on ARM64.
    
    Fix this by using virt_load_acquire() to read the write index,
    ensuring that reads of the packet data cannot be reordered
    before it. Preventing such reordering is logically correct, and
    with this change, getting stale data can no longer be reproduced.
    
    Signed-off-by: Michael Kelley <mikelley@xxxxxxxxxxxxx>
    Reviewed-by: Andrea Parri (Microsoft) <parri.andrea@xxxxxxxxx>
    Link: https://lore.kernel.org/r/1648394710-33480-1-git-send-email-mikelley@xxxxxxxxxxxxx
    Signed-off-by: Wei Liu <wei.liu@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/hv/ring_buffer.c b/drivers/hv/ring_buffer.c
index 74c1dfb8183b..6b08e9d9b382 100644
--- a/drivers/hv/ring_buffer.c
+++ b/drivers/hv/ring_buffer.c
@@ -340,7 +340,16 @@ int hv_ringbuffer_read(struct vmbus_channel *channel,
 static u32 hv_pkt_iter_avail(const struct hv_ring_buffer_info *rbi)
 {
 	u32 priv_read_loc = rbi->priv_read_index;
-	u32 write_loc = READ_ONCE(rbi->ring_buffer->write_index);
+	u32 write_loc;
+
+	/*
+	 * The Hyper-V host writes the packet data, then uses
+	 * store_release() to update the write_index.  Use load_acquire()
+	 * here to prevent loads of the packet data from being re-ordered
+	 * before the read of the write_index and potentially getting
+	 * stale data.
+	 */
+	write_loc = virt_load_acquire(&rbi->ring_buffer->write_index);
 
 	if (write_loc >= priv_read_loc)
 		return write_loc - priv_read_loc;



[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