}
if ( desc->arch.vector <= 0 || desc->arch.vector > LAST_DYNAMIC_VECTOR ||
- (desc->arch.vector >= FIRST_LEGACY_VECTOR &&
- desc->arch.vector <= LAST_LEGACY_VECTOR) )
+ desc->handler->enable == enable_8259A_irq )
{
int vector = desc->arch.vector;
if ( nr_irqs == 0 )
nr_irqs = cpu_has_apic ?
- max(16U + num_present_cpus() * NR_DYNAMIC_VECTORS,
+ max(0U + num_present_cpus() * NR_DYNAMIC_VECTORS,
8 * nr_irqs_gsi) :
nr_irqs_gsi;
else if ( nr_irqs < 16 )
int irq_to_vector(int irq)
{
int vector = IRQ_VECTOR_UNASSIGNED;
+ const struct irq_desc *desc;
BUG_ON(irq >= nr_irqs || irq < 0);
+ desc = irq_to_desc(irq);
if (IO_APIC_IRQ(irq))
{
- vector = irq_to_desc(irq)->arch.vector;
- if (vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR)
+ vector = desc->arch.vector;
+ /*
+ * Both parts of the condition are needed here during early boot, as
+ * at that time IRQ0 in particular may still have the 8259A chip set,
+ * but has already got its special IRQ0_VECTOR.
+ */
+ if ( desc->handler->enable == enable_8259A_irq &&
+ vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
vector = 0;
}
else if (MSI_IRQ(irq))
- vector = irq_to_desc(irq)->arch.vector;
+ vector = desc->arch.vector;
else
vector = LEGACY_VECTOR(irq);
&& test_bit(vector, irq_used_vectors) )
goto next;
+ if ( cpumask_test_cpu(0, vec_mask) &&
+ vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
+ goto next;
+
for_each_cpu(new_cpu, vec_mask)
if (per_cpu(vector_irq, new_cpu)[vector] >= 0)
goto next;
{
unsigned vector, me;
+ /* This interrupt should not nest inside others. */
+ BUILD_BUG_ON(APIC_PRIO_CLASS(IRQ_MOVE_CLEANUP_VECTOR) !=
+ APIC_PRIO_CLASS(FIRST_DYNAMIC_VECTOR));
+
ack_APIC_irq();
me = smp_processor_id();
if ((int)irq < 0)
continue;
- if ( vector >= FIRST_LEGACY_VECTOR && vector <= LAST_LEGACY_VECTOR )
- continue;
-
desc = irq_to_desc(irq);
if (!desc)
continue;
spin_lock(&desc->lock);
+
+ if (desc->handler->enable == enable_8259A_irq)
+ goto unlock;
+
if (!desc->arch.move_cleanup_count)
goto unlock;
kind = "";
if ( !(vector >= FIRST_LEGACY_VECTOR &&
vector <= LAST_LEGACY_VECTOR &&
+ !smp_processor_id() &&
bogus_8259A_irq(vector - FIRST_LEGACY_VECTOR)) )
{
printk("CPU%u: No irq handler for vector %02x (IRQ %d%s)\n",
/* Only available in x2APIC mode */
#define APIC_SELF_IPI 0x3F0
+/* Applicable to vectors, TPR, and PPR. */
+#define APIC_PRIO_CLASS(v) ((v) & 0xF0)
+
#define APIC_BASE __fix_to_virt(FIX_APIC_BASE)
/* It's only used in x2APIC mode of an x2APIC unit. */
#define IRQ0_VECTOR 0xf0
/* Legacy PIC uses vectors 0x20-0x2f. */
-#define FIRST_LEGACY_VECTOR 0x20
+#define FIRST_LEGACY_VECTOR FIRST_DYNAMIC_VECTOR
#define LAST_LEGACY_VECTOR (FIRST_LEGACY_VECTOR + 0xf)
#define HYPERCALL_VECTOR 0x82
#define LEGACY_SYSCALL_VECTOR 0x80
-/* Dynamically-allocated vectors available to any driver. */
-#define FIRST_DYNAMIC_VECTOR (LAST_LEGACY_VECTOR + 1)
+/*
+ * Dynamically-allocated vectors available to any driver. Note that the
+ * legacy vector range is a sub-range of this one, re-used on CPUs not
+ * sharing vectors with CPU 0.
+ */
+#define FIRST_DYNAMIC_VECTOR 0x20
#define LAST_DYNAMIC_VECTOR 0xef
#define NR_DYNAMIC_VECTORS (LAST_DYNAMIC_VECTOR - FIRST_DYNAMIC_VECTOR + 1)
-#define IRQ_MOVE_CLEANUP_VECTOR FIRST_DYNAMIC_VECTOR
+/* There's no IRQ2 at the PIC. */
+#define IRQ_MOVE_CLEANUP_VECTOR (FIRST_LEGACY_VECTOR + 2)
#define NR_VECTORS 256
-#define FIRST_IRQ_VECTOR FIRST_LEGACY_VECTOR
+#define FIRST_IRQ_VECTOR FIRST_DYNAMIC_VECTOR
#define LAST_IRQ_VECTOR LAST_HIPRIORITY_VECTOR
#endif /* _ASM_IRQ_VECTORS_H */