The read index update in vmbus_rxbr_read() was only protected by a
compiler barrier. On a weakly ordered architecture the store of rindex
can become visible to the host before the data copy completes, allowing
the host to reuse and overwrite ring data still being read. Use a
release store for the read index.
On x86 no barrier instruction is added, only a different instruction
schedule; on arm64 the store becomes stlr.
Fixes: 831dba47bd36 ("bus/vmbus: add Hyper-V virtual bus support")
Cc: [email protected]
Signed-off-by: Stephen Hemminger <[email protected]>
Reviewed-by: Long Li <[email protected]>
Reviewed-by: Wei Hu <[email protected]>
---
drivers/bus/vmbus/vmbus_bufring.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/bus/vmbus/vmbus_bufring.c
b/drivers/bus/vmbus/vmbus_bufring.c
index b49725da3e..86dc446786 100644
--- a/drivers/bus/vmbus/vmbus_bufring.c
+++ b/drivers/bus/vmbus/vmbus_bufring.c
@@ -238,10 +238,13 @@ vmbus_rxbr_read(struct vmbus_br *rbr, void *data, size_t
dlen, size_t skip)
*/
rindex = vmbus_br_idxinc(rindex, sizeof(uint64_t), br_dsize);
- /* Update the read index _after_ the channel packet is fetched. */
- rte_compiler_barrier();
-
- vbr->rindex = rindex;
+ /*
+ * Update the read index after the channel packet is fetched.
+ * Release store ensures the host can not observe the new read
+ * index before the data copy is complete.
+ */
+ rte_atomic_store_explicit((volatile uint32_t __rte_atomic
*)&vbr->rindex,
+ rindex, rte_memory_order_release);
return 0;
}
--
2.53.0