diff options
-rw-r--r-- | arch/x86/include/asm/entry_arch.h | 4 | ||||
-rw-r--r-- | arch/x86/include/asm/hardirq.h | 3 | ||||
-rw-r--r-- | arch/x86/include/asm/hw_irq.h | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/irq_vectors.h | 5 | ||||
-rw-r--r-- | arch/x86/kernel/entry_64.S | 5 | ||||
-rw-r--r-- | arch/x86/kernel/irq.c | 22 | ||||
-rw-r--r-- | arch/x86/kernel/irqinit.c | 4 |
7 files changed, 44 insertions, 0 deletions
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h index 40afa0005c69..9bd4ecac72be 100644 --- a/arch/x86/include/asm/entry_arch.h +++ b/arch/x86/include/asm/entry_arch.h | |||
@@ -19,6 +19,10 @@ BUILD_INTERRUPT(reboot_interrupt,REBOOT_VECTOR) | |||
19 | 19 | ||
20 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) | 20 | BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR) |
21 | 21 | ||
22 | #ifdef CONFIG_HAVE_KVM | ||
23 | BUILD_INTERRUPT(kvm_posted_intr_ipi, POSTED_INTR_VECTOR) | ||
24 | #endif | ||
25 | |||
22 | /* | 26 | /* |
23 | * every pentium local APIC has two 'local interrupts', with a | 27 | * every pentium local APIC has two 'local interrupts', with a |
24 | * soft-definable vector attached to both interrupts, one of | 28 | * soft-definable vector attached to both interrupts, one of |
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h index 81f04cee5f74..ab0ae1aa6d0a 100644 --- a/arch/x86/include/asm/hardirq.h +++ b/arch/x86/include/asm/hardirq.h | |||
@@ -12,6 +12,9 @@ typedef struct { | |||
12 | unsigned int irq_spurious_count; | 12 | unsigned int irq_spurious_count; |
13 | unsigned int icr_read_retry_count; | 13 | unsigned int icr_read_retry_count; |
14 | #endif | 14 | #endif |
15 | #ifdef CONFIG_HAVE_KVM | ||
16 | unsigned int kvm_posted_intr_ipis; | ||
17 | #endif | ||
15 | unsigned int x86_platform_ipis; /* arch dependent */ | 18 | unsigned int x86_platform_ipis; /* arch dependent */ |
16 | unsigned int apic_perf_irqs; | 19 | unsigned int apic_perf_irqs; |
17 | unsigned int apic_irq_work_irqs; | 20 | unsigned int apic_irq_work_irqs; |
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h index 10a78c3d3d5a..1da97efad08a 100644 --- a/arch/x86/include/asm/hw_irq.h +++ b/arch/x86/include/asm/hw_irq.h | |||
@@ -28,6 +28,7 @@ | |||
28 | /* Interrupt handlers registered during init_IRQ */ | 28 | /* Interrupt handlers registered during init_IRQ */ |
29 | extern void apic_timer_interrupt(void); | 29 | extern void apic_timer_interrupt(void); |
30 | extern void x86_platform_ipi(void); | 30 | extern void x86_platform_ipi(void); |
31 | extern void kvm_posted_intr_ipi(void); | ||
31 | extern void error_interrupt(void); | 32 | extern void error_interrupt(void); |
32 | extern void irq_work_interrupt(void); | 33 | extern void irq_work_interrupt(void); |
33 | 34 | ||
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h index aac5fa62a86c..5702d7e3111d 100644 --- a/arch/x86/include/asm/irq_vectors.h +++ b/arch/x86/include/asm/irq_vectors.h | |||
@@ -102,6 +102,11 @@ | |||
102 | */ | 102 | */ |
103 | #define X86_PLATFORM_IPI_VECTOR 0xf7 | 103 | #define X86_PLATFORM_IPI_VECTOR 0xf7 |
104 | 104 | ||
105 | /* Vector for KVM to deliver posted interrupt IPI */ | ||
106 | #ifdef CONFIG_HAVE_KVM | ||
107 | #define POSTED_INTR_VECTOR 0xf2 | ||
108 | #endif | ||
109 | |||
105 | /* | 110 | /* |
106 | * IRQ work vector: | 111 | * IRQ work vector: |
107 | */ | 112 | */ |
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S index c1d01e6ca790..727208941030 100644 --- a/arch/x86/kernel/entry_64.S +++ b/arch/x86/kernel/entry_64.S | |||
@@ -1166,6 +1166,11 @@ apicinterrupt LOCAL_TIMER_VECTOR \ | |||
1166 | apicinterrupt X86_PLATFORM_IPI_VECTOR \ | 1166 | apicinterrupt X86_PLATFORM_IPI_VECTOR \ |
1167 | x86_platform_ipi smp_x86_platform_ipi | 1167 | x86_platform_ipi smp_x86_platform_ipi |
1168 | 1168 | ||
1169 | #ifdef CONFIG_HAVE_KVM | ||
1170 | apicinterrupt POSTED_INTR_VECTOR \ | ||
1171 | kvm_posted_intr_ipi smp_kvm_posted_intr_ipi | ||
1172 | #endif | ||
1173 | |||
1169 | apicinterrupt THRESHOLD_APIC_VECTOR \ | 1174 | apicinterrupt THRESHOLD_APIC_VECTOR \ |
1170 | threshold_interrupt smp_threshold_interrupt | 1175 | threshold_interrupt smp_threshold_interrupt |
1171 | apicinterrupt THERMAL_APIC_VECTOR \ | 1176 | apicinterrupt THERMAL_APIC_VECTOR \ |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index e4595f105910..6ae6ea1d27d9 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -228,6 +228,28 @@ void smp_x86_platform_ipi(struct pt_regs *regs) | |||
228 | set_irq_regs(old_regs); | 228 | set_irq_regs(old_regs); |
229 | } | 229 | } |
230 | 230 | ||
231 | #ifdef CONFIG_HAVE_KVM | ||
232 | /* | ||
233 | * Handler for POSTED_INTERRUPT_VECTOR. | ||
234 | */ | ||
235 | void smp_kvm_posted_intr_ipi(struct pt_regs *regs) | ||
236 | { | ||
237 | struct pt_regs *old_regs = set_irq_regs(regs); | ||
238 | |||
239 | ack_APIC_irq(); | ||
240 | |||
241 | irq_enter(); | ||
242 | |||
243 | exit_idle(); | ||
244 | |||
245 | inc_irq_stat(kvm_posted_intr_ipis); | ||
246 | |||
247 | irq_exit(); | ||
248 | |||
249 | set_irq_regs(old_regs); | ||
250 | } | ||
251 | #endif | ||
252 | |||
231 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); | 253 | EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); |
232 | 254 | ||
233 | #ifdef CONFIG_HOTPLUG_CPU | 255 | #ifdef CONFIG_HOTPLUG_CPU |
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c index 7dc4e459c2b3..a2a1fbc594ff 100644 --- a/arch/x86/kernel/irqinit.c +++ b/arch/x86/kernel/irqinit.c | |||
@@ -172,6 +172,10 @@ static void __init apic_intr_init(void) | |||
172 | 172 | ||
173 | /* IPI for X86 platform specific use */ | 173 | /* IPI for X86 platform specific use */ |
174 | alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi); | 174 | alloc_intr_gate(X86_PLATFORM_IPI_VECTOR, x86_platform_ipi); |
175 | #ifdef CONFIG_HAVE_KVM | ||
176 | /* IPI for KVM to deliver posted interrupt */ | ||
177 | alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi); | ||
178 | #endif | ||
175 | 179 | ||
176 | /* IPI vectors for APIC spurious and error interrupts */ | 180 | /* IPI vectors for APIC spurious and error interrupts */ |
177 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); | 181 | alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt); |