[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC v2 11/15] vmx: Add a global wake-up vector for VT-d Posted-Interrupts
This patch adds a global vector which is used to wake up the blocked vCPU when an interrupt is being posted to it. Signed-off-by: Feng Wu <feng.wu@xxxxxxxxx> Suggested-by: Yang Zhang <yang.z.zhang@xxxxxxxxx> --- xen/arch/x86/hvm/vmx/vmx.c | 31 +++++++++++++++++++++++++++++++ xen/include/asm-x86/hvm/hvm.h | 1 + xen/include/asm-x86/hvm/vmx/vmx.h | 3 +++ xen/include/xen/sched.h | 2 ++ 4 files changed, 37 insertions(+) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 2451ca5..0e71d7e 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -90,6 +90,7 @@ DEFINE_PER_CPU(struct list_head, blocked_vcpu); DEFINE_PER_CPU(spinlock_t, blocked_vcpu_lock); uint8_t __read_mostly posted_intr_vector; +uint8_t __read_mostly pi_wakeup_vector; static int vmx_domain_initialise(struct domain *d) { @@ -132,6 +133,8 @@ static int vmx_vcpu_initialise(struct vcpu *v) if ( v->vcpu_id == 0 ) v->arch.user_regs.eax = 1; + INIT_LIST_HEAD(&v->blocked_vcpu_list); + return 0; } @@ -1835,11 +1838,17 @@ const struct hvm_function_table * __init start_vmx(void) } if ( cpu_has_vmx_posted_intr_processing ) + { alloc_direct_apic_vector(&posted_intr_vector, event_check_interrupt); + + if ( iommu_intpost ) + alloc_direct_apic_vector(&pi_wakeup_vector, pi_wakeup_interrupt); + } else { vmx_function_table.deliver_posted_intr = NULL; vmx_function_table.sync_pir_to_irr = NULL; + vmx_function_table.pi_desc_update = NULL; } if ( cpu_has_vmx_ept @@ -3262,6 +3271,28 @@ void vmx_vmenter_helper(const struct cpu_user_regs *regs) } /* + * Handle VT-d posted-interrupt when VCPU is blocked. + */ +void pi_wakeup_interrupt(struct cpu_user_regs *regs) +{ + struct vcpu *v; + unsigned int cpu = smp_processor_id(); + + spin_lock(&per_cpu(blocked_vcpu_lock, cpu)); + list_for_each_entry(v, &per_cpu(blocked_vcpu, cpu), + blocked_vcpu_list) { + struct pi_desc *pi_desc = &v->arch.hvm_vmx.pi_desc; + + if ( pi_desc->on == 1 ) + tasklet_schedule(&v->vcpu_wakeup_tasklet); + } + spin_unlock(&per_cpu(blocked_vcpu_lock, cpu)); + + ack_APIC_irq(); + this_cpu(irq_count)++; +} + +/* * Local variables: * mode: C * c-file-style: "BSD" diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index 77eeac5..e621c30 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -195,6 +195,7 @@ struct hvm_function_table { void (*deliver_posted_intr)(struct vcpu *v, u8 vector); void (*sync_pir_to_irr)(struct vcpu *v); void (*handle_eoi)(u8 vector); + void (*pi_desc_update)(struct vcpu *v, int old_state); /*Walk nested p2m */ int (*nhvm_hap_walk_L1_p2m)(struct vcpu *v, paddr_t L2_gpa, diff --git a/xen/include/asm-x86/hvm/vmx/vmx.h b/xen/include/asm-x86/hvm/vmx/vmx.h index 0d11f9c..3adf776 100644 --- a/xen/include/asm-x86/hvm/vmx/vmx.h +++ b/xen/include/asm-x86/hvm/vmx/vmx.h @@ -34,6 +34,7 @@ DECLARE_PER_CPU(struct list_head, blocked_vcpu); DECLARE_PER_CPU(spinlock_t, blocked_vcpu_lock); extern uint8_t posted_intr_vector; +extern uint8_t pi_wakeup_vector; typedef union { struct { @@ -552,6 +553,8 @@ int alloc_p2m_hap_data(struct p2m_domain *p2m); void free_p2m_hap_data(struct p2m_domain *p2m); void p2m_init_hap_data(struct p2m_domain *p2m); +void pi_wakeup_interrupt(struct cpu_user_regs *regs); + /* EPT violation qualifications definitions */ #define _EPT_READ_VIOLATION 0 #define EPT_READ_VIOLATION (1UL<<_EPT_READ_VIOLATION) diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index fd9e01e..4a7e6b3 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -148,6 +148,8 @@ struct vcpu struct vcpu *next_in_list; + struct list_head blocked_vcpu_list; + s_time_t periodic_period; s_time_t periodic_last_event; struct timer periodic_timer; -- 2.1.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |