summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--tools/lguest/lguest.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 07a03452c227..49ed25b5bbb9 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -177,6 +177,7 @@ static struct termios orig_term;
  * in precise order.
  */
 #define wmb() __asm__ __volatile__("" : : : "memory")
+#define rmb() __asm__ __volatile__("" : : : "memory")
 #define mb() __asm__ __volatile__("" : : : "memory")
 
 /* Wrapper for the last available index.  Makes it easier to change. */
@@ -676,6 +677,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
 		errx(1, "Guest moved used index from %u to %u",
 		     last_avail, vq->vring.avail->idx);
 
+	/* 
+	 * Make sure we read the descriptor number *after* we read the ring
+	 * update; don't let the cpu or compiler change the order.
+	 */
+	rmb();
+
 	/*
 	 * Grab the next descriptor number they're advertising, and increment
 	 * the index we've seen.
@@ -695,6 +702,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
 	i = head;
 
 	/*
+	 * We have to read the descriptor after we read the descriptor number,
+	 * but there's a data dependency there so the CPU shouldn't reorder
+	 * that: no rmb() required.
+	 */
+
+	/*
 	 * If this is an indirect entry, then this buffer contains a descriptor
 	 * table which we handle as if it's any normal descriptor chain.
 	 */