Since assign_irq_vector() can be called at runtime, its access of static
variables should be protected by a lock.
Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
+static DEFINE_SPINLOCK(vector_lock);
int timer_over_8254 __initdata = 1;
int timer_over_8254 __initdata = 1;
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
+ int vector;
+
+ BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
+
+ spin_lock(&vector_lock);
- BUG_ON(irq >= NR_IRQ_VECTORS);
- if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
+ if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+ spin_unlock(&vector_lock);
return IO_APIC_VECTOR(irq);
return IO_APIC_VECTOR(irq);
next:
current_vector += 8;
if (current_vector == SYSCALL_VECTOR)
next:
current_vector += 8;
if (current_vector == SYSCALL_VECTOR)
if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset++;
if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset++;
+ if (!(offset%8)) {
+ spin_unlock(&vector_lock);
current_vector = FIRST_DEVICE_VECTOR + offset;
}
current_vector = FIRST_DEVICE_VECTOR + offset;
}
- vector_irq[current_vector] = irq;
+ vector = current_vector;
+ vector_irq[vector] = irq;
- IO_APIC_VECTOR(irq) = current_vector;
+ IO_APIC_VECTOR(irq) = vector;
+
+ spin_unlock(&vector_lock);
}
static struct hw_interrupt_type ioapic_level_type;
}
static struct hw_interrupt_type ioapic_level_type;
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock);
+static DEFINE_SPINLOCK(vector_lock);
/*
* # of IRQ routing registers
/*
* # of IRQ routing registers
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
int assign_irq_vector(int irq)
{
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
- if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0)
+
+ spin_lock(&vector_lock);
+
+ if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
+ spin_unlock(&vector_lock);
return IO_APIC_VECTOR(irq);
return IO_APIC_VECTOR(irq);
next:
current_vector += 8;
if (current_vector == IA32_SYSCALL_VECTOR)
next:
current_vector += 8;
if (current_vector == IA32_SYSCALL_VECTOR)
current_vector = FIRST_DEVICE_VECTOR + offset;
}
current_vector = FIRST_DEVICE_VECTOR + offset;
}
- vector_irq[current_vector] = irq;
+ vector = current_vector;
+ vector_irq[vector] = irq;
- IO_APIC_VECTOR(irq) = current_vector;
+ IO_APIC_VECTOR(irq) = vector;
+
+ spin_unlock(&vector_lock);
}
extern void (*interrupt[NR_IRQS])(void);
}
extern void (*interrupt[NR_IRQS])(void);