Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: VMX: Register a new IPI for posted interrupt

Posted Interrupt feature requires a special IPI to deliver posted interrupt
to guest. And it should has a high priority so the interrupt will not be
blocked by others.
Normally, the posted interrupt will be consumed by vcpu if target vcpu is
running and transparent to OS. But in some cases, the interrupt will arrive
when target vcpu is scheduled out. And host will see it. So we need to
register a dump handler to handle it.

Signed-off-by: Yang Zhang <yang.z.zhang@Intel.com>
Acked-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Gleb Natapov <gleb@redhat.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>

authored by

Yang Zhang and committed by
Marcelo Tosatti
d78f2664 a547c6db

+44
+4
arch/x86/include/asm/entry_arch.h
··· 19 19 20 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 27 * every pentium local APIC has two 'local interrupts', with a 24 28 * soft-definable vector attached to both interrupts, one of
+3
arch/x86/include/asm/hardirq.h
··· 12 12 unsigned int irq_spurious_count; 13 13 unsigned int icr_read_retry_count; 14 14 #endif 15 + #ifdef CONFIG_HAVE_KVM 16 + unsigned int kvm_posted_intr_ipis; 17 + #endif 15 18 unsigned int x86_platform_ipis; /* arch dependent */ 16 19 unsigned int apic_perf_irqs; 17 20 unsigned int apic_irq_work_irqs;
+1
arch/x86/include/asm/hw_irq.h
··· 28 28 /* Interrupt handlers registered during init_IRQ */ 29 29 extern void apic_timer_interrupt(void); 30 30 extern void x86_platform_ipi(void); 31 + extern void kvm_posted_intr_ipi(void); 31 32 extern void error_interrupt(void); 32 33 extern void irq_work_interrupt(void); 33 34
+5
arch/x86/include/asm/irq_vectors.h
··· 102 102 */ 103 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 111 * IRQ work vector: 107 112 */
+5
arch/x86/kernel/entry_64.S
··· 1166 1166 apicinterrupt X86_PLATFORM_IPI_VECTOR \ 1167 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 1174 apicinterrupt THRESHOLD_APIC_VECTOR \ 1170 1175 threshold_interrupt smp_threshold_interrupt 1171 1176 apicinterrupt THERMAL_APIC_VECTOR \
+22
arch/x86/kernel/irq.c
··· 228 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 253 EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); 232 254 233 255 #ifdef CONFIG_HOTPLUG_CPU
+4
arch/x86/kernel/irqinit.c
··· 172 172 173 173 /* IPI for X86 platform specific use */ 174 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 180 /* IPI vectors for APIC spurious and error interrupts */ 177 181 alloc_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);