aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/desc.h10
-rw-r--r--arch/x86/include/asm/irq.h1
-rw-r--r--arch/x86/kernel/apic.c2
-rw-r--r--arch/x86/kernel/io_apic.c9
-rw-r--r--arch/x86/kernel/irqinit_32.c16
-rw-r--r--arch/x86/kernel/irqinit_64.c13
-rw-r--r--arch/x86/kernel/traps.c12
-rw-r--r--drivers/lguest/interrupts_and_traps.c13
8 files changed, 52 insertions, 24 deletions
diff --git a/arch/x86/include/asm/desc.h b/arch/x86/include/asm/desc.h
index e6b82b17b072..dc27705f5443 100644
--- a/arch/x86/include/asm/desc.h
+++ b/arch/x86/include/asm/desc.h
@@ -320,16 +320,14 @@ static inline void set_intr_gate(unsigned int n, void *addr)
320 _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS); 320 _set_gate(n, GATE_INTERRUPT, addr, 0, 0, __KERNEL_CS);
321} 321}
322 322
323#define SYS_VECTOR_FREE 0
324#define SYS_VECTOR_ALLOCED 1
325
326extern int first_system_vector; 323extern int first_system_vector;
327extern char system_vectors[]; 324/* used_vectors is BITMAP for irq is not managed by percpu vector_irq */
325extern unsigned long used_vectors[];
328 326
329static inline void alloc_system_vector(int vector) 327static inline void alloc_system_vector(int vector)
330{ 328{
331 if (system_vectors[vector] == SYS_VECTOR_FREE) { 329 if (!test_bit(vector, used_vectors)) {
332 system_vectors[vector] = SYS_VECTOR_ALLOCED; 330 set_bit(vector, used_vectors);
333 if (first_system_vector > vector) 331 if (first_system_vector > vector)
334 first_system_vector = vector; 332 first_system_vector = vector;
335 } else 333 } else
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index 8766d30fb746..4bb732e45a85 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -46,5 +46,6 @@ extern void native_init_IRQ(void);
46 46
47/* Interrupt vector management */ 47/* Interrupt vector management */
48extern DECLARE_BITMAP(used_vectors, NR_VECTORS); 48extern DECLARE_BITMAP(used_vectors, NR_VECTORS);
49extern int vector_used_by_percpu_irq(unsigned int vector);
49 50
50#endif /* _ASM_X86_IRQ_H */ 51#endif /* _ASM_X86_IRQ_H */
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index f7a32a3beb2f..b9019271af62 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -118,8 +118,6 @@ EXPORT_SYMBOL_GPL(local_apic_timer_c2_ok);
118 118
119int first_system_vector = 0xfe; 119int first_system_vector = 0xfe;
120 120
121char system_vectors[NR_VECTORS] = { [0 ... NR_VECTORS-1] = SYS_VECTOR_FREE};
122
123/* 121/*
124 * Debug level, exported for io_apic.c 122 * Debug level, exported for io_apic.c
125 */ 123 */
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 908c1d00a5c7..1cbf7c8d46e0 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -1326,13 +1326,10 @@ next:
1326 } 1326 }
1327 if (unlikely(current_vector == vector)) 1327 if (unlikely(current_vector == vector))
1328 continue; 1328 continue;
1329#ifdef CONFIG_X86_64 1329
1330 if (vector == IA32_SYSCALL_VECTOR) 1330 if (test_bit(vector, used_vectors))
1331 goto next;
1332#else
1333 if (vector == SYSCALL_VECTOR)
1334 goto next; 1331 goto next;
1335#endif 1332
1336 for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask) 1333 for_each_cpu_and(new_cpu, tmp_mask, cpu_online_mask)
1337 if (per_cpu(vector_irq, new_cpu)[vector] != -1) 1334 if (per_cpu(vector_irq, new_cpu)[vector] != -1)
1338 goto next; 1335 goto next;
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c
index 6a92f47c52e7..61aa2a1004b5 100644
--- a/arch/x86/kernel/irqinit_32.c
+++ b/arch/x86/kernel/irqinit_32.c
@@ -110,6 +110,18 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
110 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1 110 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
111}; 111};
112 112
113int vector_used_by_percpu_irq(unsigned int vector)
114{
115 int cpu;
116
117 for_each_online_cpu(cpu) {
118 if (per_cpu(vector_irq, cpu)[vector] != -1)
119 return 1;
120 }
121
122 return 0;
123}
124
113/* Overridden in paravirt.c */ 125/* Overridden in paravirt.c */
114void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); 126void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ")));
115 127
@@ -146,10 +158,12 @@ void __init native_init_IRQ(void)
146 alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); 158 alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
147 159
148 /* IPI for single call function */ 160 /* IPI for single call function */
149 set_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, call_function_single_interrupt); 161 alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR,
162 call_function_single_interrupt);
150 163
151 /* Low priority IPI to cleanup after moving an irq */ 164 /* Low priority IPI to cleanup after moving an irq */
152 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 165 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
166 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
153#endif 167#endif
154 168
155#ifdef CONFIG_X86_LOCAL_APIC 169#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/kernel/irqinit_64.c b/arch/x86/kernel/irqinit_64.c
index 40c1e62ec785..1020919efe1c 100644
--- a/arch/x86/kernel/irqinit_64.c
+++ b/arch/x86/kernel/irqinit_64.c
@@ -135,6 +135,18 @@ DEFINE_PER_CPU(vector_irq_t, vector_irq) = {
135 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1 135 [IRQ15_VECTOR + 1 ... NR_VECTORS - 1] = -1
136}; 136};
137 137
138int vector_used_by_percpu_irq(unsigned int vector)
139{
140 int cpu;
141
142 for_each_online_cpu(cpu) {
143 if (per_cpu(vector_irq, cpu)[vector] != -1)
144 return 1;
145 }
146
147 return 0;
148}
149
138void __init init_ISA_irqs(void) 150void __init init_ISA_irqs(void)
139{ 151{
140 int i; 152 int i;
@@ -187,6 +199,7 @@ static void __init smp_intr_init(void)
187 199
188 /* Low priority IPI to cleanup after moving an irq */ 200 /* Low priority IPI to cleanup after moving an irq */
189 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); 201 set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt);
202 set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors);
190#endif 203#endif
191} 204}
192 205
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
index 04d242ab0161..4a6dff39a470 100644
--- a/arch/x86/kernel/traps.c
+++ b/arch/x86/kernel/traps.c
@@ -72,9 +72,6 @@
72 72
73#include "cpu/mcheck/mce.h" 73#include "cpu/mcheck/mce.h"
74 74
75DECLARE_BITMAP(used_vectors, NR_VECTORS);
76EXPORT_SYMBOL_GPL(used_vectors);
77
78asmlinkage int system_call(void); 75asmlinkage int system_call(void);
79 76
80/* Do we ignore FPU interrupts ? */ 77/* Do we ignore FPU interrupts ? */
@@ -89,6 +86,9 @@ gate_desc idt_table[256]
89 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, }; 86 __attribute__((__section__(".data.idt"))) = { { { { 0, 0 } } }, };
90#endif 87#endif
91 88
89DECLARE_BITMAP(used_vectors, NR_VECTORS);
90EXPORT_SYMBOL_GPL(used_vectors);
91
92static int ignore_nmis; 92static int ignore_nmis;
93 93
94static inline void conditional_sti(struct pt_regs *regs) 94static inline void conditional_sti(struct pt_regs *regs)
@@ -949,9 +949,7 @@ dotraplinkage void do_iret_error(struct pt_regs *regs, long error_code)
949 949
950void __init trap_init(void) 950void __init trap_init(void)
951{ 951{
952#ifdef CONFIG_X86_32
953 int i; 952 int i;
954#endif
955 953
956#ifdef CONFIG_EISA 954#ifdef CONFIG_EISA
957 void __iomem *p = early_ioremap(0x0FFFD9, 4); 955 void __iomem *p = early_ioremap(0x0FFFD9, 4);
@@ -1008,11 +1006,15 @@ void __init trap_init(void)
1008 } 1006 }
1009 1007
1010 set_system_trap_gate(SYSCALL_VECTOR, &system_call); 1008 set_system_trap_gate(SYSCALL_VECTOR, &system_call);
1009#endif
1011 1010
1012 /* Reserve all the builtin and the syscall vector: */ 1011 /* Reserve all the builtin and the syscall vector: */
1013 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++) 1012 for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
1014 set_bit(i, used_vectors); 1013 set_bit(i, used_vectors);
1015 1014
1015#ifdef CONFIG_X86_64
1016 set_bit(IA32_SYSCALL_VECTOR, used_vectors);
1017#else
1016 set_bit(SYSCALL_VECTOR, used_vectors); 1018 set_bit(SYSCALL_VECTOR, used_vectors);
1017#endif 1019#endif
1018 /* 1020 /*
diff --git a/drivers/lguest/interrupts_and_traps.c b/drivers/lguest/interrupts_and_traps.c
index a1039068f95c..415fab0125ac 100644
--- a/drivers/lguest/interrupts_and_traps.c
+++ b/drivers/lguest/interrupts_and_traps.c
@@ -222,11 +222,16 @@ bool check_syscall_vector(struct lguest *lg)
222int init_interrupts(void) 222int init_interrupts(void)
223{ 223{
224 /* If they want some strange system call vector, reserve it now */ 224 /* If they want some strange system call vector, reserve it now */
225 if (syscall_vector != SYSCALL_VECTOR 225 if (syscall_vector != SYSCALL_VECTOR) {
226 && test_and_set_bit(syscall_vector, used_vectors)) { 226 if (test_bit(syscall_vector, used_vectors) ||
227 printk("lg: couldn't reserve syscall %u\n", syscall_vector); 227 vector_used_by_percpu_irq(syscall_vector)) {
228 return -EBUSY; 228 printk(KERN_ERR "lg: couldn't reserve syscall %u\n",
229 syscall_vector);
230 return -EBUSY;
231 }
232 set_bit(syscall_vector, used_vectors);
229 } 233 }
234
230 return 0; 235 return 0;
231} 236}
232 237