aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeng Wu <feng.wu@intel.com>2015-05-19 05:07:16 -0400
committerThomas Gleixner <tglx@linutronix.de>2015-05-19 09:51:17 -0400
commitf6b3c72c23661e5534cd2eede16e9bac7ebb761c (patch)
tree9a4033e16059ae731bd8fc5420a942b9dcecaadc
parenta2f1c8bdc02bfcaa5a658283b883fdb54e328b36 (diff)
x86/irq: Define a global vector for VT-d Posted-Interrupts
Currently, we use a global vector as the Posted-Interrupts Notification Event for all the vCPUs in the system. We need to introduce another global vector for VT-d Posted-Interrtups, which will be used to wakeup the sleep vCPU when an external interrupt from a direct-assigned device happens for that vCPU. [ tglx: Removed a gazillion of extra newlines ] Signed-off-by: Feng Wu <feng.wu@intel.com> Cc: jiang.liu@linux.intel.com Link: http://lkml.kernel.org/r/1432026437-16560-4-git-send-email-feng.wu@intel.com Suggested-by: Yang Zhang <yang.z.zhang@intel.com> Acked-by: H. Peter Anvin <hpa@linux.intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-rw-r--r--arch/x86/include/asm/entry_arch.h2
-rw-r--r--arch/x86/include/asm/hardirq.h1
-rw-r--r--arch/x86/include/asm/hw_irq.h2
-rw-r--r--arch/x86/include/asm/irq.h4
-rw-r--r--arch/x86/include/asm/irq_vectors.h1
-rw-r--r--arch/x86/kernel/entry_64.S2
-rw-r--r--arch/x86/kernel/irq.c26
-rw-r--r--arch/x86/kernel/irqinit.c2
8 files changed, 40 insertions, 0 deletions
diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
index dc5fa661465f..27ca0afcccd7 100644
--- a/arch/x86/include/asm/entry_arch.h
+++ b/arch/x86/include/asm/entry_arch.h
@@ -23,6 +23,8 @@ BUILD_INTERRUPT(x86_platform_ipi, X86_PLATFORM_IPI_VECTOR)
23#ifdef CONFIG_HAVE_KVM 23#ifdef CONFIG_HAVE_KVM
24BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR, 24BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
25 smp_kvm_posted_intr_ipi) 25 smp_kvm_posted_intr_ipi)
26BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR,
27 smp_kvm_posted_intr_wakeup_ipi)
26#endif 28#endif
27 29
28/* 30/*
diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
index 0f5fb6b6567e..986606539395 100644
--- a/arch/x86/include/asm/hardirq.h
+++ b/arch/x86/include/asm/hardirq.h
@@ -14,6 +14,7 @@ typedef struct {
14#endif 14#endif
15#ifdef CONFIG_HAVE_KVM 15#ifdef CONFIG_HAVE_KVM
16 unsigned int kvm_posted_intr_ipis; 16 unsigned int kvm_posted_intr_ipis;
17 unsigned int kvm_posted_intr_wakeup_ipis;
17#endif 18#endif
18 unsigned int x86_platform_ipis; /* arch dependent */ 19 unsigned int x86_platform_ipis; /* arch dependent */
19 unsigned int apic_perf_irqs; 20 unsigned int apic_perf_irqs;
diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
index 9ec5d37d8da3..10c80d4f8386 100644
--- a/arch/x86/include/asm/hw_irq.h
+++ b/arch/x86/include/asm/hw_irq.h
@@ -29,6 +29,7 @@
29extern asmlinkage void apic_timer_interrupt(void); 29extern asmlinkage void apic_timer_interrupt(void);
30extern asmlinkage void x86_platform_ipi(void); 30extern asmlinkage void x86_platform_ipi(void);
31extern asmlinkage void kvm_posted_intr_ipi(void); 31extern asmlinkage void kvm_posted_intr_ipi(void);
32extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
32extern asmlinkage void error_interrupt(void); 33extern asmlinkage void error_interrupt(void);
33extern asmlinkage void irq_work_interrupt(void); 34extern asmlinkage void irq_work_interrupt(void);
34 35
@@ -58,6 +59,7 @@ extern void trace_call_function_single_interrupt(void);
58#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt 59#define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
59#define trace_reboot_interrupt reboot_interrupt 60#define trace_reboot_interrupt reboot_interrupt
60#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi 61#define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
62#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
61#endif /* CONFIG_TRACING */ 63#endif /* CONFIG_TRACING */
62 64
63#ifdef CONFIG_X86_LOCAL_APIC 65#ifdef CONFIG_X86_LOCAL_APIC
diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
index a80cbb88ea91..8008d06581c7 100644
--- a/arch/x86/include/asm/irq.h
+++ b/arch/x86/include/asm/irq.h
@@ -30,6 +30,10 @@ extern void fixup_irqs(void);
30extern void irq_force_complete_move(int); 30extern void irq_force_complete_move(int);
31#endif 31#endif
32 32
33#ifdef CONFIG_HAVE_KVM
34extern void kvm_set_posted_intr_wakeup_handler(void (*handler)(void));
35#endif
36
33extern void (*x86_platform_ipi_callback)(void); 37extern void (*x86_platform_ipi_callback)(void);
34extern void native_init_IRQ(void); 38extern void native_init_IRQ(void);
35extern bool handle_irq(unsigned irq, struct pt_regs *regs); 39extern bool handle_irq(unsigned irq, struct pt_regs *regs);
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index bf55235d7772..0ed29ac13a9d 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -86,6 +86,7 @@
86/* Vector for KVM to deliver posted interrupt IPI */ 86/* Vector for KVM to deliver posted interrupt IPI */
87#ifdef CONFIG_HAVE_KVM 87#ifdef CONFIG_HAVE_KVM
88#define POSTED_INTR_VECTOR 0xf2 88#define POSTED_INTR_VECTOR 0xf2
89#define POSTED_INTR_WAKEUP_VECTOR 0xf1
89#endif 90#endif
90 91
91/* 92/*
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 47b95813dc37..22aadc917868 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -916,6 +916,8 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \
916#ifdef CONFIG_HAVE_KVM 916#ifdef CONFIG_HAVE_KVM
917apicinterrupt3 POSTED_INTR_VECTOR \ 917apicinterrupt3 POSTED_INTR_VECTOR \
918 kvm_posted_intr_ipi smp_kvm_posted_intr_ipi 918 kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
919apicinterrupt3 POSTED_INTR_WAKEUP_VECTOR \
920 kvm_posted_intr_wakeup_ipi smp_kvm_posted_intr_wakeup_ipi
919#endif 921#endif
920 922
921#ifdef CONFIG_X86_MCE_THRESHOLD 923#ifdef CONFIG_X86_MCE_THRESHOLD
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index be3894512820..90b2f7052f5b 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -242,6 +242,18 @@ __visible void smp_x86_platform_ipi(struct pt_regs *regs)
242} 242}
243 243
244#ifdef CONFIG_HAVE_KVM 244#ifdef CONFIG_HAVE_KVM
245static void dummy_handler(void) {}
246static void (*kvm_posted_intr_wakeup_handler)(void) = dummy_handler;
247
248void kvm_set_posted_intr_wakeup_handler(void (*handler)(void))
249{
250 if (handler)
251 kvm_posted_intr_wakeup_handler = handler;
252 else
253 kvm_posted_intr_wakeup_handler = dummy_handler;
254}
255EXPORT_SYMBOL_GPL(kvm_set_posted_intr_wakeup_handler);
256
245/* 257/*
246 * Handler for POSTED_INTERRUPT_VECTOR. 258 * Handler for POSTED_INTERRUPT_VECTOR.
247 */ 259 */
@@ -254,6 +266,20 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)
254 exiting_irq(); 266 exiting_irq();
255 set_irq_regs(old_regs); 267 set_irq_regs(old_regs);
256} 268}
269
270/*
271 * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
272 */
273__visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
274{
275 struct pt_regs *old_regs = set_irq_regs(regs);
276
277 entering_ack_irq();
278 inc_irq_stat(kvm_posted_intr_wakeup_ipis);
279 kvm_posted_intr_wakeup_handler();
280 exiting_irq();
281 set_irq_regs(old_regs);
282}
257#endif 283#endif
258 284
259__visible void smp_trace_x86_platform_ipi(struct pt_regs *regs) 285__visible void smp_trace_x86_platform_ipi(struct pt_regs *regs)
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index dc1e08d23552..680723a8e4b6 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -144,6 +144,8 @@ static void __init apic_intr_init(void)
144#ifdef CONFIG_HAVE_KVM 144#ifdef CONFIG_HAVE_KVM
145 /* IPI for KVM to deliver posted interrupt */ 145 /* IPI for KVM to deliver posted interrupt */
146 alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi); 146 alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
147 /* IPI for KVM to deliver interrupt to wake up tasks */
148 alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
147#endif 149#endif
148 150
149 /* IPI vectors for APIC spurious and error interrupts */ 151 /* IPI vectors for APIC spurious and error interrupts */