aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/arch/x86/include/bits/xen.h19
-rw-r--r--src/interface/xen/xenstore.c4
2 files changed, 23 insertions, 0 deletions
diff --git a/src/arch/x86/include/bits/xen.h b/src/arch/x86/include/bits/xen.h
index 3433cea1..fc065ea3 100644
--- a/src/arch/x86/include/bits/xen.h
+++ b/src/arch/x86/include/bits/xen.h
@@ -161,4 +161,23 @@ xen_hypercall_5 ( struct xen_hypervisor *xen, unsigned int hypercall,
return retval;
}
+/**
+ * Test and clear pending event
+ *
+ * @v xen Xen hypervisor
+ * @v port Event channel port
+ * @ret pending Event was pending
+ */
+static inline __attribute__ (( always_inline )) uint8_t
+xenevent_pending ( struct xen_hypervisor *xen, evtchn_port_t port ) {
+ uint8_t pending;
+
+ __asm__ __volatile__ ( "lock btr %2, %0\n\t"
+ "setc %1\n\t"
+ : "+m" ( xen->shared->evtchn_pending ),
+ "=a" ( pending )
+ : "Ir" ( port ) );
+ return pending;
+}
+
#endif /* _BITS_XEN_H */
diff --git a/src/interface/xen/xenstore.c b/src/interface/xen/xenstore.c
index 731af779..23424a92 100644
--- a/src/interface/xen/xenstore.c
+++ b/src/interface/xen/xenstore.c
@@ -242,6 +242,10 @@ static int xenstore_response ( struct xen_hypervisor *xen, uint32_t req_id,
char *string;
int rc;
+ /* Wait for response to become available */
+ while ( ! xenevent_pending ( xen, xen->store.port ) )
+ cpu_nap();
+
/* Receive message header */
xenstore_recv ( xen, &msg, sizeof ( msg ) );
*len = msg.len;