[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] Clean the pending_intr processing sequence and fix some potential bugs.
# HG changeset patch # User kaf24@xxxxxxxxxxxxxxxxxxxx # Node ID 00061c916dbb765b928760665ad610929ce7aa95 # Parent 8bb494bccdac3c85bffcd134b15c247d7d566a90 Clean the pending_intr processing sequence and fix some potential bugs. Signed-off-by: Eddie Dong <eddie.dong@xxxxxxxxx> Signed-off-by: Xiaowei Yang <xiaowei.yang@xxxxxxxxx> diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vlapic.c --- a/xen/arch/x86/hvm/vlapic.c Fri Mar 10 08:11:33 2006 +++ b/xen/arch/x86/hvm/vlapic.c Fri Mar 10 08:12:22 2006 @@ -943,6 +943,20 @@ return -1; } +int cpu_has_apic_interrupt(struct vcpu* v) +{ + struct vlapic *vlapic = VLAPIC(v); + + if (vlapic && vlapic_enabled(vlapic)) { + int highest_irr = vlapic_find_highest_irr(vlapic); + + if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) { + return 1; + } + } + return 0; +} + void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode) { struct vlapic *vlapic = VLAPIC(v); diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/io.c --- a/xen/arch/x86/hvm/vmx/io.c Fri Mar 10 08:11:33 2006 +++ b/xen/arch/x86/hvm/vmx/io.c Fri Mar 10 08:12:22 2006 @@ -86,28 +86,53 @@ } static inline void -enable_irq_window(unsigned long cpu_exec_control) -{ - if (!(cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) { - cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; - __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control); +enable_irq_window(struct vcpu *v) +{ + u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control; + + if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) { + *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control); } } static inline void -disable_irq_window(unsigned long cpu_exec_control) -{ - if ( cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) { - cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; - __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control); - } +disable_irq_window(struct vcpu *v) +{ + u32 *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control; + + if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) { + *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING; + __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control); + } +} + +static inline int is_interruptibility_state(void) +{ + int interruptibility; + __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility); + return interruptibility; +} + +/* check to see if there is pending interrupt */ +int cpu_has_pending_irq(struct vcpu *v) +{ + struct hvm_domain *plat = &v->domain->arch.hvm_domain; + + /* APIC */ + if ( cpu_has_apic_interrupt(v) ) return 1; + + /* PIC */ + if ( !vlapic_accept_pic_intr(v) ) return 0; + + return plat->interrupt_request; } asmlinkage void vmx_intr_assist(void) { int intr_type = 0; int highest_vector; - unsigned long intr_fields, eflags, interruptibility, cpu_exec_control; + unsigned long eflags; struct vcpu *v = current; struct hvm_domain *plat=&v->domain->arch.hvm_domain; struct hvm_virpit *vpit = &plat->vpit; @@ -121,37 +146,21 @@ pic_set_irq(pic, 0, 1); } - __vmread_vcpu(v, CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control); - __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields); - - if (intr_fields & INTR_INFO_VALID_MASK) { - enable_irq_window(cpu_exec_control); - HVM_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx", - intr_fields); - return; - } - - __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility); - - if (interruptibility) { - enable_irq_window(cpu_exec_control); - HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility: %lx",interruptibility); + if ( !cpu_has_pending_irq(v) ) return; + + if ( is_interruptibility_state() ) { /* pre-cleared for emulated instruction */ + enable_irq_window(v); + HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility"); return; } __vmread(GUEST_RFLAGS, &eflags); if (irq_masked(eflags)) { - enable_irq_window(cpu_exec_control); + enable_irq_window(v); return; } highest_vector = cpu_get_interrupt(v, &intr_type); - - if (highest_vector == -1) { - disable_irq_window(cpu_exec_control); - return; - } - switch (intr_type) { case VLAPIC_DELIV_MODE_EXT: case VLAPIC_DELIV_MODE_FIXED: diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/vmcs.c --- a/xen/arch/x86/hvm/vmx/vmcs.c Fri Mar 10 08:11:33 2006 +++ b/xen/arch/x86/hvm/vmx/vmcs.c Fri Mar 10 08:12:22 2006 @@ -219,6 +219,7 @@ error |= __vmwrite(CR0_READ_SHADOW, cr0); error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL, MONITOR_CPU_BASED_EXEC_CONTROLS); + v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS; __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (cr4) : ); diff -r 8bb494bccdac -r 00061c916dbb xen/arch/x86/hvm/vmx/vmx.c --- a/xen/arch/x86/hvm/vmx/vmx.c Fri Mar 10 08:11:33 2006 +++ b/xen/arch/x86/hvm/vmx/vmx.c Fri Mar 10 08:12:22 2006 @@ -595,6 +595,7 @@ __vmread(GUEST_RIP, ¤t_eip); __vmwrite(GUEST_RIP, current_eip + inst_len); + __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0); } @@ -2025,6 +2026,7 @@ case EXIT_REASON_PENDING_INTERRUPT: __vmwrite(CPU_BASED_VM_EXEC_CONTROL, MONITOR_CPU_BASED_EXEC_CONTROLS); + v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS; break; case EXIT_REASON_TASK_SWITCH: __hvm_bug(®s); diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/io.h --- a/xen/include/asm-x86/hvm/io.h Fri Mar 10 08:11:33 2006 +++ b/xen/include/asm-x86/hvm/io.h Fri Mar 10 08:12:22 2006 @@ -154,6 +154,7 @@ extern void pic_irq_request(int *interrupt_request, int level); extern void hvm_pic_assist(struct vcpu *v); extern int cpu_get_interrupt(struct vcpu *v, int *type); +extern int cpu_has_pending_irq(struct vcpu *v); // XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame. #define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT))) diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/vlapic.h --- a/xen/include/asm-x86/hvm/vlapic.h Fri Mar 10 08:11:33 2006 +++ b/xen/include/asm-x86/hvm/vlapic.h Fri Mar 10 08:12:22 2006 @@ -209,6 +209,7 @@ void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode); +int cpu_has_apic_interrupt(struct vcpu* v); int cpu_get_apic_interrupt(struct vcpu* v, int *mode); extern uint32_t vlapic_update_ppr(struct vlapic *vlapic); diff -r 8bb494bccdac -r 00061c916dbb xen/include/asm-x86/hvm/vmx/vmcs.h --- a/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Mar 10 08:11:33 2006 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h Fri Mar 10 08:12:22 2006 @@ -69,6 +69,7 @@ struct arch_vmx_struct { struct vmcs_struct *vmcs; /* VMCS pointer in virtual. */ unsigned int launch_cpu; /* VMCS is valid on this CPU. */ + u32 exec_control; /* cache of cpu execution control */ unsigned long flags; /* VMCS flags */ unsigned long cpu_cr0; /* copy of guest CR0 */ unsigned long cpu_shadow_cr0; /* copy of guest read shadow CR0 */ _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |