No IRQ balancing is supposed to be happening on the broadcast IRQs. The only entity responsible for fiddling with the CPU affinities is set_channel_irq_affinity(). They shouldn't even be fiddled with when offlining a CPU: A CPU going down can't at the same time be idle. Some properties (->arch.cpu_mask in particular) may transiently reference an offline CPU, but that'll be adjusted as soon as a channel goes into active use again.
Along with adjusting fixup_irqs() (in a more general way, i.e. covering all vectors which are marked in use globally), also adjust section placement of used_vectors. Signed-off-by: Jan Beulich <[email protected]> --- v4: New. --- a/xen/arch/x86/hpet.c +++ b/xen/arch/x86/hpet.c @@ -294,22 +294,6 @@ static int hpet_msi_write(struct hpet_ev #define hpet_msi_shutdown hpet_msi_mask -static void cf_check hpet_msi_set_affinity( - struct irq_desc *desc, const cpumask_t *mask) -{ - struct hpet_event_channel *ch = desc->action->dev_id; - struct msi_msg msg = ch->msi.msg; - - /* This really is only for dump_irqs(). */ - cpumask_copy(desc->arch.cpu_mask, mask); - - msg.dest32 = cpu_mask_to_apicid(mask); - msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK; - msg.address_lo |= MSI_ADDR_DEST_ID(msg.dest32); - if ( msg.dest32 != ch->msi.msg.dest32 ) - hpet_msi_write(ch, &msg); -} - /* * IRQ Chip for MSI HPET Devices, */ @@ -321,7 +305,6 @@ static hw_irq_controller hpet_msi_type = .disable = hpet_msi_mask, .ack = irq_actor_none, .end = end_nonmaskable_irq, - .set_affinity = hpet_msi_set_affinity, }; static int __hpet_setup_msi_irq(struct irq_desc *desc) --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -51,7 +51,7 @@ static vmask_t global_used_vector_map; struct irq_desc __read_mostly *irq_desc = NULL; -static DECLARE_BITMAP(used_vectors, X86_IDT_VECTORS); +static DECLARE_BITMAP(used_vectors, X86_IDT_VECTORS) __ro_after_init; static DEFINE_SPINLOCK(vector_lock); @@ -2630,13 +2630,17 @@ void fixup_irqs(void) spin_lock(&desc->lock); vector = irq_to_vector(irq); - if ( vector >= FIRST_HIPRIORITY_VECTOR && - vector <= LAST_HIPRIORITY_VECTOR && - desc->handler == &no_irq_type ) + if ( (vector >= FIRST_HIPRIORITY_VECTOR && + vector <= LAST_HIPRIORITY_VECTOR && + desc->handler == &no_irq_type) || + test_bit(vector, used_vectors) ) { /* * This can in particular happen when parking secondary threads * during boot and when the serial console wants to use a PCI IRQ. + * + * Globally used vectors (like the HPET broadcast IRQ ones), need + * to be left alone in any event. */ spin_unlock(&desc->lock); continue;
