summaryrefslogtreecommitdiffstats
path: root/src/arch/x86
diff options
context:
space:
mode:
authorMichael Brown2015-06-30 18:06:58 +0200
committerMichael Brown2015-06-30 18:18:51 +0200
commit211529a7fe97521acdeaf1f785e48ea3ddd26517 (patch)
tree2f1cb9d465700d03b10846d2b88b98b8b1d9cfec /src/arch/x86
parent[gdb] Allow gdbstub to be started on an arbitrary serial port (diff)
downloadipxe-211529a7fe97521acdeaf1f785e48ea3ddd26517.tar.gz
ipxe-211529a7fe97521acdeaf1f785e48ea3ddd26517.tar.xz
ipxe-211529a7fe97521acdeaf1f785e48ea3ddd26517.zip
[xen] Wait for and clear XenStore event before receiving data
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>
Diffstat (limited to 'src/arch/x86')
-rw-r--r--src/arch/x86/include/bits/xen.h19
1 files changed, 19 insertions, 0 deletions
diff --git a/src/arch/x86/include/bits/xen.h b/src/arch/x86/include/bits/xen.h
index 3433cea1f..fc065ea38 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 */