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 <jbeulich@suse.com>
---
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;