diff options
| -rw-r--r-- | arch/x86/kernel/irqinit_32.c | 61 |
1 files changed, 33 insertions, 28 deletions
diff --git a/arch/x86/kernel/irqinit_32.c b/arch/x86/kernel/irqinit_32.c index c5cb769db7b0..df0aad5a0624 100644 --- a/arch/x86/kernel/irqinit_32.c +++ b/arch/x86/kernel/irqinit_32.c | |||
| @@ -121,6 +121,38 @@ static void __init init_ISA_irqs(void) | |||
| 121 | /* Overridden in paravirt.c */ | 121 | /* Overridden in paravirt.c */ |
| 122 | void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); | 122 | void init_IRQ(void) __attribute__((weak, alias("native_init_IRQ"))); |
| 123 | 123 | ||
| 124 | static void __init smp_intr_init(void) | ||
| 125 | { | ||
| 126 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP) | ||
| 127 | /* | ||
| 128 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper | ||
| 129 | * IPI, driven by wakeup. | ||
| 130 | */ | ||
| 131 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | ||
| 132 | |||
| 133 | /* IPIs for invalidation */ | ||
| 134 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); | ||
| 135 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); | ||
| 136 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); | ||
| 137 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); | ||
| 138 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); | ||
| 139 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); | ||
| 140 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); | ||
| 141 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); | ||
| 142 | |||
| 143 | /* IPI for generic function call */ | ||
| 144 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | ||
| 145 | |||
| 146 | /* IPI for single call function */ | ||
| 147 | alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, | ||
| 148 | call_function_single_interrupt); | ||
| 149 | |||
| 150 | /* Low priority IPI to cleanup after moving an irq */ | ||
| 151 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); | ||
| 152 | set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); | ||
| 153 | #endif | ||
| 154 | } | ||
| 155 | |||
| 124 | /** | 156 | /** |
| 125 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors | 157 | * x86_quirk_pre_intr_init - initialisation prior to setting up interrupt vectors |
| 126 | * | 158 | * |
| @@ -158,34 +190,7 @@ void __init native_init_IRQ(void) | |||
| 158 | } | 190 | } |
| 159 | 191 | ||
| 160 | 192 | ||
| 161 | #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_SMP) | 193 | smp_intr_init(); |
| 162 | /* | ||
| 163 | * The reschedule interrupt is a CPU-to-CPU reschedule-helper | ||
| 164 | * IPI, driven by wakeup. | ||
| 165 | */ | ||
| 166 | alloc_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt); | ||
| 167 | |||
| 168 | /* IPIs for invalidation */ | ||
| 169 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+0, invalidate_interrupt0); | ||
| 170 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+1, invalidate_interrupt1); | ||
| 171 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+2, invalidate_interrupt2); | ||
| 172 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+3, invalidate_interrupt3); | ||
| 173 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+4, invalidate_interrupt4); | ||
| 174 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+5, invalidate_interrupt5); | ||
| 175 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+6, invalidate_interrupt6); | ||
| 176 | alloc_intr_gate(INVALIDATE_TLB_VECTOR_START+7, invalidate_interrupt7); | ||
| 177 | |||
| 178 | /* IPI for generic function call */ | ||
| 179 | alloc_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt); | ||
| 180 | |||
| 181 | /* IPI for single call function */ | ||
| 182 | alloc_intr_gate(CALL_FUNCTION_SINGLE_VECTOR, | ||
| 183 | call_function_single_interrupt); | ||
| 184 | |||
| 185 | /* Low priority IPI to cleanup after moving an irq */ | ||
| 186 | set_intr_gate(IRQ_MOVE_CLEANUP_VECTOR, irq_move_cleanup_interrupt); | ||
| 187 | set_bit(IRQ_MOVE_CLEANUP_VECTOR, used_vectors); | ||
| 188 | #endif | ||
| 189 | 194 | ||
| 190 | #ifdef CONFIG_X86_LOCAL_APIC | 195 | #ifdef CONFIG_X86_LOCAL_APIC |
| 191 | /* self generated IPI for local APIC timer */ | 196 | /* self generated IPI for local APIC timer */ |
