# HG changeset patch
# User Keir Fraser <keir@xxxxxxx>
# Date 1287588992 -3600
# Node ID c7c972f91663a9bfef007a828e91653fe561b2c3
# Parent ac7f64d5577bccc0d87c6c7b28d7845d0279a670
hvmloader: Properly block on xenstore daemon rather than merely yielding.
Signed-off-by: Keir Fraser <keir@xxxxxxx>
---
tools/firmware/hvmloader/util.h | 10 ++++++++++
tools/firmware/hvmloader/xenbus.c | 34 ++++++++++++++++++++++------------
2 files changed, 32 insertions(+), 12 deletions(-)
diff -r ac7f64d5577b -r c7c972f91663 tools/firmware/hvmloader/util.h
--- a/tools/firmware/hvmloader/util.h Wed Oct 20 09:56:36 2010 +0100
+++ b/tools/firmware/hvmloader/util.h Wed Oct 20 16:36:32 2010 +0100
@@ -33,6 +33,16 @@ static inline int test_bit(unsigned int
static inline int test_bit(unsigned int b, void *p)
{
return !!(((uint8_t *)p)[b>>3] & (1u<<(b&7)));
+}
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+ int oldbit;
+ asm volatile (
+ "lock ; btrl %2,%1 ; sbbl %0,%0"
+ : "=r" (oldbit), "=m" (*(volatile long *)addr)
+ : "Ir" (nr), "m" (*(volatile long *)addr) : "memory");
+ return oldbit;
}
/* MSR access */
diff -r ac7f64d5577b -r c7c972f91663 tools/firmware/hvmloader/xenbus.c
--- a/tools/firmware/hvmloader/xenbus.c Wed Oct 20 09:56:36 2010 +0100
+++ b/tools/firmware/hvmloader/xenbus.c Wed Oct 20 16:36:32 2010 +0100
@@ -25,9 +25,9 @@
#include <xen/hvm/params.h>
#include <xen/io/xs_wire.h>
-struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
-evtchn_port_t event; /* Event-channel to dom0 */
-char payload[XENSTORE_PAYLOAD_MAX + 1]; /* Unmarshalling area */
+static struct xenstore_domain_interface *rings; /* Shared ring with dom0 */
+static evtchn_port_t event; /* Event-channel to dom0 */
+static char payload[XENSTORE_PAYLOAD_MAX + 1]; /* Unmarshalling area */
/* Connect our xenbus client to the backend.
* Call once, before any other xenbus actions. */
@@ -69,6 +69,19 @@ void xenbus_shutdown(void)
rings = NULL;
}
+static void ring_wait(void)
+{
+ struct shared_info *shinfo = get_shared_info();
+ struct sched_poll poll;
+
+ memset(&poll, 0, sizeof(poll));
+ set_xen_guest_handle(poll.ports, &event);
+ poll.nr_ports = 1;
+
+ while ( !test_and_clear_bit(event, shinfo->evtchn_pending) )
+ hypercall_sched_op(SCHEDOP_poll, &poll);
+}
+
/* Helper functions: copy data in and out of the ring */
static void ring_write(char *data, uint32_t len)
{
@@ -79,8 +92,9 @@ static void ring_write(char *data, uint3
while ( len )
{
/* Don't overrun the consumer pointer */
- part = (XENSTORE_RING_SIZE - 1) -
- MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons);
+ while ( (part = (XENSTORE_RING_SIZE - 1) -
+ MASK_XENSTORE_IDX(rings->req_prod - rings->req_cons)) == 0 )
+ ring_wait();
/* Don't overrun the end of the ring */
if ( part > (XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod)) )
part = XENSTORE_RING_SIZE - MASK_XENSTORE_IDX(rings->req_prod);
@@ -92,9 +106,6 @@ static void ring_write(char *data, uint3
barrier(); /* = wmb before prod write, rmb before next cons read */
rings->req_prod += part;
len -= part;
-
- if ( len )
- hypercall_sched_op(SCHEDOP_yield, NULL);
}
}
@@ -107,7 +118,9 @@ static void ring_read(char *data, uint32
while ( len )
{
/* Don't overrun the producer pointer */
- part = MASK_XENSTORE_IDX(rings->rsp_prod - rings->rsp_cons);
+ while ( (part = MASK_XENSTORE_IDX(rings->rsp_prod -
+ rings->rsp_cons)) == 0 )
+ 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);
@@ -119,9 +132,6 @@ static void ring_read(char *data, uint32
barrier(); /* = wmb before cons write, rmb before next prod read */
rings->rsp_cons += part;
len -= part;
-
- if ( len )
- hypercall_sched_op(SCHEDOP_yield, NULL);
}
}
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|