lkml.org 
[lkml]   [2015]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[v5 3/3] x86, irq: Define a global vector for VT-d Posted-Interrupts
    Date
    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.

    Signed-off-by: Feng Wu <feng.wu@intel.com>
    Suggested-by: Yang Zhang <yang.z.zhang@intel.com>
    Acked-by: H. Peter Anvin <hpa@linux.intel.com>
    ---
    arch/x86/include/asm/entry_arch.h | 2 ++
    arch/x86/include/asm/hardirq.h | 1 +
    arch/x86/include/asm/hw_irq.h | 2 ++
    arch/x86/include/asm/irq.h | 4 ++++
    arch/x86/include/asm/irq_vectors.h | 1 +
    arch/x86/kernel/entry_64.S | 2 ++
    arch/x86/kernel/irq.c | 23 +++++++++++++++++++++++
    arch/x86/kernel/irqinit.c | 2 ++
    8 files changed, 37 insertions(+)

    diff --git a/arch/x86/include/asm/entry_arch.h b/arch/x86/include/asm/entry_arch.h
    index dc5fa66..27ca0af 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)
    #ifdef CONFIG_HAVE_KVM
    BUILD_INTERRUPT3(kvm_posted_intr_ipi, POSTED_INTR_VECTOR,
    smp_kvm_posted_intr_ipi)
    +BUILD_INTERRUPT3(kvm_posted_intr_wakeup_ipi, POSTED_INTR_WAKEUP_VECTOR,
    + smp_kvm_posted_intr_wakeup_ipi)
    #endif

    /*
    diff --git a/arch/x86/include/asm/hardirq.h b/arch/x86/include/asm/hardirq.h
    index 0f5fb6b..9866065 100644
    --- a/arch/x86/include/asm/hardirq.h
    +++ b/arch/x86/include/asm/hardirq.h
    @@ -14,6 +14,7 @@ typedef struct {
    #endif
    #ifdef CONFIG_HAVE_KVM
    unsigned int kvm_posted_intr_ipis;
    + unsigned int kvm_posted_intr_wakeup_ipis;
    #endif
    unsigned int x86_platform_ipis; /* arch dependent */
    unsigned int apic_perf_irqs;
    diff --git a/arch/x86/include/asm/hw_irq.h b/arch/x86/include/asm/hw_irq.h
    index 1f88e71..6ffc847 100644
    --- a/arch/x86/include/asm/hw_irq.h
    +++ b/arch/x86/include/asm/hw_irq.h
    @@ -29,6 +29,7 @@
    extern asmlinkage void apic_timer_interrupt(void);
    extern asmlinkage void x86_platform_ipi(void);
    extern asmlinkage void kvm_posted_intr_ipi(void);
    +extern asmlinkage void kvm_posted_intr_wakeup_ipi(void);
    extern asmlinkage void error_interrupt(void);
    extern asmlinkage void irq_work_interrupt(void);

    @@ -92,6 +93,7 @@ extern void trace_call_function_single_interrupt(void);
    #define trace_irq_move_cleanup_interrupt irq_move_cleanup_interrupt
    #define trace_reboot_interrupt reboot_interrupt
    #define trace_kvm_posted_intr_ipi kvm_posted_intr_ipi
    +#define trace_kvm_posted_intr_wakeup_ipi kvm_posted_intr_wakeup_ipi
    #endif /* CONFIG_TRACING */

    #ifdef CONFIG_X86_LOCAL_APIC
    diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h
    index a80cbb8..16bfe4e 100644
    --- a/arch/x86/include/asm/irq.h
    +++ b/arch/x86/include/asm/irq.h
    @@ -30,6 +30,10 @@ extern void fixup_irqs(void);
    extern void irq_force_complete_move(int);
    #endif

    +#ifdef CONFIG_HAVE_KVM
    + extern void (*wakeup_handler_callback)(void);
    +#endif
    +
    extern void (*x86_platform_ipi_callback)(void);
    extern void native_init_IRQ(void);
    extern 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 b26cb12..dca94f2 100644
    --- a/arch/x86/include/asm/irq_vectors.h
    +++ b/arch/x86/include/asm/irq_vectors.h
    @@ -105,6 +105,7 @@
    /* Vector for KVM to deliver posted interrupt IPI */
    #ifdef CONFIG_HAVE_KVM
    #define POSTED_INTR_VECTOR 0xf2
    +#define POSTED_INTR_WAKEUP_VECTOR 0xf1
    #endif

    /*
    diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
    index c7b2384..177feec 100644
    --- a/arch/x86/kernel/entry_64.S
    +++ b/arch/x86/kernel/entry_64.S
    @@ -919,6 +919,8 @@ apicinterrupt X86_PLATFORM_IPI_VECTOR \
    #ifdef CONFIG_HAVE_KVM
    apicinterrupt3 POSTED_INTR_VECTOR \
    kvm_posted_intr_ipi smp_kvm_posted_intr_ipi
    +apicinterrupt3 POSTED_INTR_WAKEUP_VECTOR \
    + kvm_posted_intr_wakeup_ipi smp_kvm_posted_intr_wakeup_ipi
    #endif

    #ifdef CONFIG_X86_MCE_THRESHOLD
    diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
    index e5952c2..87620bf 100644
    --- a/arch/x86/kernel/irq.c
    +++ b/arch/x86/kernel/irq.c
    @@ -237,6 +237,9 @@ __visible void smp_x86_platform_ipi(struct pt_regs *regs)
    }

    #ifdef CONFIG_HAVE_KVM
    +void (*wakeup_handler_callback)(void);
    +EXPORT_SYMBOL_GPL(wakeup_handler_callback);
    +
    /*
    * Handler for POSTED_INTERRUPT_VECTOR.
    */
    @@ -256,6 +259,26 @@ __visible void smp_kvm_posted_intr_ipi(struct pt_regs *regs)

    set_irq_regs(old_regs);
    }
    +
    +/*
    + * Handler for POSTED_INTERRUPT_WAKEUP_VECTOR.
    + */
    +__visible void smp_kvm_posted_intr_wakeup_ipi(struct pt_regs *regs)
    +{
    + struct pt_regs *old_regs = set_irq_regs(regs);
    +
    + entering_ack_irq();
    +
    + inc_irq_stat(kvm_posted_intr_wakeup_ipis);
    +
    + if (wakeup_handler_callback)
    + wakeup_handler_callback();
    +
    + exiting_irq();
    +
    + set_irq_regs(old_regs);
    +}
    +
    #endif

    __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 cd10a64..895941d 100644
    --- a/arch/x86/kernel/irqinit.c
    +++ b/arch/x86/kernel/irqinit.c
    @@ -144,6 +144,8 @@ static void __init apic_intr_init(void)
    #ifdef CONFIG_HAVE_KVM
    /* IPI for KVM to deliver posted interrupt */
    alloc_intr_gate(POSTED_INTR_VECTOR, kvm_posted_intr_ipi);
    + /* IPI for KVM to deliver interrupt to wake up tasks */
    + alloc_intr_gate(POSTED_INTR_WAKEUP_VECTOR, kvm_posted_intr_wakeup_ipi);
    #endif

    /* IPI vectors for APIC spurious and error interrupts */
    --
    2.1.0


    \
     
     \ /
      Last update: 2015-05-18 13:01    [W:4.410 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site