[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, &current_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(&regs);
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


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.