diff options
author | Yinghai Lu <yinghai@kernel.org> | 2008-12-19 18:23:44 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-12-23 16:37:28 -0500 |
commit | b77b881f21b29aa7efa668fde69ee3dc0372ae3f (patch) | |
tree | a4039161e9bcab3e9c2fd2e2aa70fee16103857b | |
parent | a7883dece6ef82097e6bdf19c1d0a20351e06056 (diff) |
x86: fix lguest used_vectors breakage, -v2
Impact: fix lguest, clean up
32-bit lguest used used_vectors to record vectors, but that model of
allocating vectors changed and got broken, after we changed vector
allocation to a per_cpu array.
Try enable that for 64bit, and the array is used for all vectors that
are not managed by vector_irq per_cpu array.
Also kill system_vectors[], that is now a duplication of the
used_vectors bitmap.
[ merged in cpus4096 due to io_apic.c cpumask changes. ]
[ -v2, fix build failure ]
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r-- | arch/x86/include/asm/desc.h | 10 | ||||
-rw-r--r-- | arch/x86/include/asm/irq.h | 1 | ||||
-rw-r--r-- | arch/x86/kernel/apic.c | 2 | ||||
-rw-r--r-- | arch/x86/kernel/io_apic.c | 9 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_32.c | 16 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit_64.c | 13 | ||||
-rw-r--r-- | arch/x86/kernel/traps.c | 12 | ||||
-rw-r--r-- | drivers/lguest/interrupts_and_traps.c | 13 |
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 | |||
326 | extern int first_system_vector; | 323 | extern int first_system_vector; |
327 | extern char system_vectors[]; | 324 | /* used_vectors is BITMAP for irq is not managed by percpu vector_irq */ |
325 | extern unsigned long used_vectors[]; | ||
328 | 326 | ||
329 | static inline void alloc_system_vector(int vector) | 327 | static 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 */ |
48 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); | 48 | extern DECLARE_BITMAP(used_vectors, NR_VECTORS); |
49 | extern 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 | ||
119 | int first_system_vector = 0xfe; | 119 | int first_system_vector = 0xfe; |
120 | 120 | ||
121 | char 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 | ||
113 | int 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 */ |
114 | void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); | 126 | void 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 | ||
138 | int 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 | |||
138 | void __init init_ISA_irqs(void) | 150 | void __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 | ||
75 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | ||
76 | EXPORT_SYMBOL_GPL(used_vectors); | ||
77 | |||
78 | asmlinkage int system_call(void); | 75 | asmlinkage 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 | ||
89 | DECLARE_BITMAP(used_vectors, NR_VECTORS); | ||
90 | EXPORT_SYMBOL_GPL(used_vectors); | ||
91 | |||
92 | static int ignore_nmis; | 92 | static int ignore_nmis; |
93 | 93 | ||
94 | static inline void conditional_sti(struct pt_regs *regs) | 94 | static 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 | ||
950 | void __init trap_init(void) | 950 | void __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) | |||
222 | int init_interrupts(void) | 222 | int 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 | ||