diff options
| -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 | ||
