aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/i386/kernel/io_apic.c24
-rw-r--r--arch/x86_64/kernel/io_apic.c18
2 files changed, 32 insertions, 10 deletions
diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c
index a62df3e764c5..43ffdd012d26 100644
--- a/arch/i386/kernel/io_apic.c
+++ b/arch/i386/kernel/io_apic.c
@@ -50,6 +50,7 @@ atomic_t irq_mis_count;
50static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; 50static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
51 51
52static DEFINE_SPINLOCK(ioapic_lock); 52static DEFINE_SPINLOCK(ioapic_lock);
53static DEFINE_SPINLOCK(vector_lock);
53 54
54int timer_over_8254 __initdata = 1; 55int timer_over_8254 __initdata = 1;
55 56
@@ -1161,10 +1162,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
1161int assign_irq_vector(int irq) 1162int assign_irq_vector(int irq)
1162{ 1163{
1163 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 1164 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
1165 int vector;
1166
1167 BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
1168
1169 spin_lock(&vector_lock);
1164 1170
1165 BUG_ON(irq >= NR_IRQ_VECTORS); 1171 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
1166 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) 1172 spin_unlock(&vector_lock);
1167 return IO_APIC_VECTOR(irq); 1173 return IO_APIC_VECTOR(irq);
1174 }
1168next: 1175next:
1169 current_vector += 8; 1176 current_vector += 8;
1170 if (current_vector == SYSCALL_VECTOR) 1177 if (current_vector == SYSCALL_VECTOR)
@@ -1172,16 +1179,21 @@ next:
1172 1179
1173 if (current_vector >= FIRST_SYSTEM_VECTOR) { 1180 if (current_vector >= FIRST_SYSTEM_VECTOR) {
1174 offset++; 1181 offset++;
1175 if (!(offset%8)) 1182 if (!(offset%8)) {
1183 spin_unlock(&vector_lock);
1176 return -ENOSPC; 1184 return -ENOSPC;
1185 }
1177 current_vector = FIRST_DEVICE_VECTOR + offset; 1186 current_vector = FIRST_DEVICE_VECTOR + offset;
1178 } 1187 }
1179 1188
1180 vector_irq[current_vector] = irq; 1189 vector = current_vector;
1190 vector_irq[vector] = irq;
1181 if (irq != AUTO_ASSIGN) 1191 if (irq != AUTO_ASSIGN)
1182 IO_APIC_VECTOR(irq) = current_vector; 1192 IO_APIC_VECTOR(irq) = vector;
1193
1194 spin_unlock(&vector_lock);
1183 1195
1184 return current_vector; 1196 return vector;
1185} 1197}
1186 1198
1187static struct hw_interrupt_type ioapic_level_type; 1199static struct hw_interrupt_type ioapic_level_type;
diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c
index 9cc7031b7151..062b10daebac 100644
--- a/arch/x86_64/kernel/io_apic.c
+++ b/arch/x86_64/kernel/io_apic.c
@@ -56,6 +56,7 @@ int timer_over_8254 __initdata = 0;
56static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; 56static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
57 57
58static DEFINE_SPINLOCK(ioapic_lock); 58static DEFINE_SPINLOCK(ioapic_lock);
59static DEFINE_SPINLOCK(vector_lock);
59 60
60/* 61/*
61 * # of IRQ routing registers 62 * # of IRQ routing registers
@@ -834,10 +835,16 @@ u8 irq_vector[NR_IRQ_VECTORS] __read_mostly = { FIRST_DEVICE_VECTOR , 0 };
834int assign_irq_vector(int irq) 835int assign_irq_vector(int irq)
835{ 836{
836 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0; 837 static int current_vector = FIRST_DEVICE_VECTOR, offset = 0;
838 int vector;
837 839
838 BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS); 840 BUG_ON(irq != AUTO_ASSIGN && (unsigned)irq >= NR_IRQ_VECTORS);
839 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) 841
842 spin_lock(&vector_lock);
843
844 if (irq != AUTO_ASSIGN && IO_APIC_VECTOR(irq) > 0) {
845 spin_unlock(&vector_lock);
840 return IO_APIC_VECTOR(irq); 846 return IO_APIC_VECTOR(irq);
847 }
841next: 848next:
842 current_vector += 8; 849 current_vector += 8;
843 if (current_vector == IA32_SYSCALL_VECTOR) 850 if (current_vector == IA32_SYSCALL_VECTOR)
@@ -849,11 +856,14 @@ next:
849 current_vector = FIRST_DEVICE_VECTOR + offset; 856 current_vector = FIRST_DEVICE_VECTOR + offset;
850 } 857 }
851 858
852 vector_irq[current_vector] = irq; 859 vector = current_vector;
860 vector_irq[vector] = irq;
853 if (irq != AUTO_ASSIGN) 861 if (irq != AUTO_ASSIGN)
854 IO_APIC_VECTOR(irq) = current_vector; 862 IO_APIC_VECTOR(irq) = vector;
863
864 spin_unlock(&vector_lock);
855 865
856 return current_vector; 866 return vector;
857} 867}
858 868
859extern void (*interrupt[NR_IRQS])(void); 869extern void (*interrupt[NR_IRQS])(void);