]> xenbits.xensource.com Git - xen.git/commitdiff
x86/hvmloader: Don't wait for the producer to fill the ring if
authorAnshul Makkar <anshul.makkar@citrix.com>
Tue, 23 May 2017 14:12:58 +0000 (15:12 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 25 May 2017 08:59:49 +0000 (09:59 +0100)
The condition: if there is a space in the ring then wait for the producer
to fill the ring also evaluates to true even if the ring if full. It
leads to a deadlock where producer is waiting for consumer
to consume the items and consumer is waiting for producer to fill the ring.

Fix for the issue: check if the ring is full and then break from
the loop to consume the items from the ring.
eg. case: prod = 1272, cons = 248.

Signed-off-by: Anshul Makkar <anshul.makkar@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Release-acked-by: Julien Grall <julien.grall@arm.com>
tools/firmware/hvmloader/xenbus.c

index 448157dcb04a3c3114a38cf08854bb497b0a2982..2b89a56fce45c2328c812f9a4a1bde975b914e59 100644 (file)
@@ -141,7 +141,19 @@ static void ring_read(char *data, uint32_t len)
         /* Don't overrun the producer pointer */
         while ( (part = MASK_XENSTORE_IDX(rings->rsp_prod -
                                           rings->rsp_cons)) == 0 )
+        {
+            /*
+             * Don't wait for producer to fill the ring if it is already full.
+             * Condition happens when you write string > 1K into the ring.
+             * eg case prod=1272 cons=248.
+             */
+            if ( rings->rsp_prod - rings->rsp_cons == XENSTORE_RING_SIZE )
+            {
+                part = XENSTORE_RING_SIZE;
+                break;
+            }
             ring_wait();
+        }
         /* Don't overrun the end of the ring */
         if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons)) )
             part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->rsp_cons);