Commit 0a1ad60d authored by Jan Beulich's avatar Jan Beulich Committed by Linus Torvalds

[PATCH] x86_64: serialize assign_irq_vector() use of static variables

Since assign_irq_vector() can be called at runtime, its access of static
variables should be protected by a lock.
Signed-off-by: default avatarJan Beulich <jbeulich@novell.com>
Signed-off-by: default avatarAndi Kleen <ak@suse.de>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent a32073bf
...@@ -50,6 +50,7 @@ atomic_t irq_mis_count; ...@@ -50,6 +50,7 @@ atomic_t irq_mis_count;
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock); static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock);
int timer_over_8254 __initdata = 1; int timer_over_8254 __initdata = 1;
...@@ -1161,10 +1162,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; ...@@ -1161,10 +1162,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
int assign_irq_vector(int irq) int assign_irq_vector(int irq)
{ {
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 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: next:
current_vector += 8; current_vector += 8;
if (current_vector == SYSCALL_VECTOR) if (current_vector == SYSCALL_VECTOR)
...@@ -1172,16 +1179,21 @@ int assign_irq_vector(int irq) ...@@ -1172,16 +1179,21 @@ int assign_irq_vector(int irq)
if (current_vector >= FIRST_SYSTEM_VECTOR) { if (current_vector >= FIRST_SYSTEM_VECTOR) {
offset++; offset++;
if (!(offset%8)) if (!(offset%8)) {
spin_unlock(&vector_lock);
return -ENOSPC; return -ENOSPC;
}
current_vector = FIRST_DEVICE_VECTOR + offset; current_vector = FIRST_DEVICE_VECTOR + offset;
} }
vector_irq[current_vector] = irq; vector = current_vector;
vector_irq[vector] = irq;
if (irq != AUTO_ASSIGN) if (irq != AUTO_ASSIGN)
IO_APIC_VECTOR(irq) = current_vector; IO_APIC_VECTOR(irq) = vector;
spin_unlock(&vector_lock);
return current_vector; return vector;
} }
static struct hw_interrupt_type ioapic_level_type; static struct hw_interrupt_type ioapic_level_type;
......
...@@ -56,6 +56,7 @@ int timer_over_8254 __initdata = 0; ...@@ -56,6 +56,7 @@ int timer_over_8254 __initdata = 0;
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
static DEFINE_SPINLOCK(ioapic_lock); static DEFINE_SPINLOCK(ioapic_lock);
static DEFINE_SPINLOCK(vector_lock);
/* /*
* # of IRQ routing registers * # of IRQ routing registers
...@@ -834,10 +835,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 }; ...@@ -834,10 +835,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
int assign_irq_vector(int irq) int assign_irq_vector(int irq)
{ {
static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
int vector;
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: next:
current_vector += 8; current_vector += 8;
if (current_vector == IA32_SYSCALL_VECTOR) if (current_vector == IA32_SYSCALL_VECTOR)
...@@ -849,11 +856,14 @@ int assign_irq_vector(int irq) ...@@ -849,11 +856,14 @@ int assign_irq_vector(int irq)
current_vector = FIRST_DEVICE_VECTOR + offset; current_vector = FIRST_DEVICE_VECTOR + offset;
} }
vector_irq[current_vector] = irq; vector = current_vector;
vector_irq[vector] = irq;
if (irq != AUTO_ASSIGN) if (irq != AUTO_ASSIGN)
IO_APIC_VECTOR(irq) = current_vector; IO_APIC_VECTOR(irq) = vector;
spin_unlock(&vector_lock);
return current_vector; return vector;
} }
extern void (*interrupt[NR_IRQS])(void); extern void (*interrupt[NR_IRQS])(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment