From: Jan Beulich Date: Thu, 6 Jun 2019 14:04:53 +0000 (+0200) Subject: x86/IRQ: bail early from irq_guest_eoi_timer_fn() when nothing is in flight X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~2117 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=a646da4a3d96b7666a3ed99521f1e64dbedf19f9;p=xen.git x86/IRQ: bail early from irq_guest_eoi_timer_fn() when nothing is in flight There's no point entering the loop in the function in this case. Instead there still being something in flight _after_ the loop would be an actual problem: No timer would be running anymore for issuing the EOI eventually, and hence this IRQ (and possibly lower priority ones) would be blocked, perhaps indefinitely. Issue a warning instead and prefer breaking some (presumably misbehaving) guest over stalling perhaps the entire system. Signed-off-by: Jan Beulich Reviewed-by: Roger Pau Monné Reviewed-by: Andrew Cooper --- diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 335c8ffb67..be486a6ce4 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1118,10 +1118,10 @@ static void irq_guest_eoi_timer_fn(void *data) action = (irq_guest_action_t *)desc->action; /* - * Is another instance of this timer already running? Skip everything - * to avoid forcing an EOI early. + * Is no IRQ in flight at all, or another instance of this timer already + * running? Skip everything to avoid forcing an EOI early. */ - if ( timer_is_active(&action->eoi_timer) ) + if ( !action->in_flight || timer_is_active(&action->eoi_timer) ) goto out; if ( action->ack_type != ACKTYPE_NONE ) @@ -1136,8 +1136,13 @@ static void irq_guest_eoi_timer_fn(void *data) } } - if ( action->in_flight != 0 ) - goto out; + if ( action->in_flight ) + { + printk(XENLOG_G_WARNING + "IRQ%u: %d/%d handler(s) still in flight at forced EOI\n", + irq, action->in_flight, action->nr_guests); + ASSERT_UNREACHABLE(); + } switch ( action->ack_type ) {