Skip to content

Commit

Permalink
[xen] Wait for and clear XenStore event before receiving data
Browse files Browse the repository at this point in the history
Older, out-of-tree Xen kernel modules (such as those provided with
SuSE Linux Enterprise Server 11) do not clear the leftover "event
pending" bit when opening an event channel.  Consequently, no event is
ever delivered to indicate that there is information in the XenStore
ring buffer, and the system hangs shortly after loading the
xen-platform-pci kernel module.

Work around this problem by always waiting for the XenStore event
channel to be signalled, and clearing the event before processing the
received data.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed Jun 30, 2015
1 parent a0f60d2 commit 211529a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
19 changes: 19 additions & 0 deletions src/arch/x86/include/bits/xen.h
Expand Up @@ -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 */
4 changes: 4 additions & 0 deletions src/interface/xen/xenstore.c
Expand Up @@ -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;
Expand Down

0 comments on commit 211529a

Please sign in to comment.