+diff --git a/xen/drivers/char/ns16550.c b/xen/drivers/char/ns16550.c
+index 5fdfd91..5caf362 100644
+--- a/xen/drivers/char/ns16550.c
++++ b/xen/drivers/char/ns16550.c
+@@ -127,8 +127,9 @@ static void ns16550_interrupt(
+ {
+ struct serial_port *port = dev_id;
+ struct ns16550 *uart = port->uart;
++ int bail = 0;
+
+- while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) )
++ while ( !(ns_read_reg(uart, IIR) & IIR_NOINT) && (bail++ < 0x20))
+ {
+ char lsr = ns_read_reg(uart, LSR);
+ if ( lsr & LSR_THRE )
+@@ -143,11 +144,12 @@ static void ns16550_poll(void *data)
+ struct serial_port *port = data;
+ struct ns16550 *uart = port->uart;
+ struct cpu_user_regs *regs = guest_cpu_user_regs();
++ int bail = 0;
+
+- while ( ns_read_reg(uart, LSR) & LSR_DR )
++ while ( (ns_read_reg(uart, LSR) & LSR_DR ) && (bail++ < 0x20))
+ serial_rx_interrupt(port, regs);
+
+- if ( ns_read_reg(uart, LSR) & LSR_THRE )
++ if ( (ns_read_reg(uart, LSR) & LSR_THRE ) && (bail++ < 0x20))
+ serial_tx_interrupt(port, regs);
+
+ set_timer(&uart->timer, NOW() + MILLISECS(uart->timeout_ms));
diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c
index 3d261ca..88512ae 100644
--- a/xen/drivers/char/serial.c