From: Jan Beulich Date: Mon, 22 Jul 2019 09:44:50 +0000 (+0200) Subject: x86/IRQ: target online CPUs when binding guest IRQ X-Git-Tag: archive/raspbian/4.14.0+80-gd101b417b7-1+rpi1^2~63^2~1884 X-Git-Url: https://dgit.raspbian.org/?a=commitdiff_plain;h=0d7fd5f2b8ede776a8a395c1fd0427139ffa3219;p=xen.git x86/IRQ: target online CPUs when binding guest IRQ fixup_irqs() skips interrupts without action. Hence such interrupts can retain affinity to just offline CPUs. With "noirqbalance" in effect, pirq_guest_bind() so far would have left them alone, resulting in a non- working interrupt. Signed-off-by: Jan Beulich Reviewed-by: Roger Pau Monné Acked-by: Andrew Cooper --- diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 10a83efc8e..732ddd4efd 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1695,9 +1695,27 @@ int pirq_guest_bind(struct vcpu *v, struct pirq *pirq, int will_share) desc->status |= IRQ_GUEST; - /* Attempt to bind the interrupt target to the correct CPU. */ - if ( !opt_noirqbalance && (desc->handler->set_affinity != NULL) ) - desc->handler->set_affinity(desc, cpumask_of(v->processor)); + /* + * Attempt to bind the interrupt target to the correct (or at least + * some online) CPU. + */ + if ( desc->handler->set_affinity ) + { + const cpumask_t *affinity = NULL; + + if ( !opt_noirqbalance ) + affinity = cpumask_of(v->processor); + else if ( !cpumask_intersects(desc->affinity, &cpu_online_map) ) + { + cpumask_setall(desc->affinity); + affinity = &cpumask_all; + } + else if ( !cpumask_intersects(desc->arch.cpu_mask, + &cpu_online_map) ) + affinity = desc->affinity; + if ( affinity ) + desc->handler->set_affinity(desc, affinity); + } desc->status &= ~IRQ_DISABLED; desc->handler->startup(desc);