ia64/xen-unstable

changeset 9219:00061c916dbb

Clean the pending_intr processing sequence and fix some potential bugs.

Signed-off-by: Eddie Dong <eddie.dong@intel.com>
Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Mar 10 09:12:22 2006 +0100 (2006-03-10)
parents 8bb494bccdac
children e0741ec5ec52
files xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmcs.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/vlapic.h xen/include/asm-x86/hvm/vmx/vmcs.h
line diff
     1.1 --- a/xen/arch/x86/hvm/vlapic.c	Fri Mar 10 09:11:33 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/vlapic.c	Fri Mar 10 09:12:22 2006 +0100
     1.3 @@ -943,6 +943,20 @@ int cpu_get_apic_interrupt(struct vcpu *
     1.4      return -1;
     1.5  }
     1.6  
     1.7 +int cpu_has_apic_interrupt(struct vcpu* v)
     1.8 +{
     1.9 +    struct vlapic *vlapic = VLAPIC(v);
    1.10 +
    1.11 +    if (vlapic && vlapic_enabled(vlapic)) {
    1.12 +        int highest_irr = vlapic_find_highest_irr(vlapic);
    1.13 +
    1.14 +        if (highest_irr != -1 && highest_irr >= vlapic->processor_priority) {
    1.15 +            return 1;
    1.16 +        }
    1.17 +    }
    1.18 +    return 0;
    1.19 +}
    1.20 + 
    1.21  void vlapic_post_injection(struct vcpu *v, int vector, int deliver_mode)
    1.22  {
    1.23      struct vlapic *vlapic = VLAPIC(v);
     2.1 --- a/xen/arch/x86/hvm/vmx/io.c	Fri Mar 10 09:11:33 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Fri Mar 10 09:12:22 2006 +0100
     2.3 @@ -86,28 +86,53 @@ interrupt_post_injection(struct vcpu * v
     2.4  }
     2.5  
     2.6  static inline void
     2.7 -enable_irq_window(unsigned long cpu_exec_control)
     2.8 +enable_irq_window(struct vcpu *v)
     2.9  {
    2.10 -    if (!(cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
    2.11 -        cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
    2.12 -        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
    2.13 +    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    2.14 +    
    2.15 +    if (!(*cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING)) {
    2.16 +        *cpu_exec_control |= CPU_BASED_VIRTUAL_INTR_PENDING;
    2.17 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    2.18      }
    2.19  }
    2.20  
    2.21  static inline void
    2.22 -disable_irq_window(unsigned long cpu_exec_control)
    2.23 +disable_irq_window(struct vcpu *v)
    2.24 +{
    2.25 +    u32  *cpu_exec_control = &v->arch.hvm_vcpu.u.vmx.exec_control;
    2.26 +    
    2.27 +    if ( *cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
    2.28 +        *cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
    2.29 +        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, *cpu_exec_control);
    2.30 +    }
    2.31 +}
    2.32 +
    2.33 +static inline int is_interruptibility_state(void)
    2.34  {
    2.35 -    if ( cpu_exec_control & CPU_BASED_VIRTUAL_INTR_PENDING ) {
    2.36 -        cpu_exec_control &= ~CPU_BASED_VIRTUAL_INTR_PENDING;
    2.37 -        __vmwrite(CPU_BASED_VM_EXEC_CONTROL, cpu_exec_control);
    2.38 -    }
    2.39 +    int  interruptibility;
    2.40 +    __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
    2.41 +    return interruptibility;
    2.42 +}
    2.43 +
    2.44 +/* check to see if there is pending interrupt  */
    2.45 +int cpu_has_pending_irq(struct vcpu *v)
    2.46 +{
    2.47 +    struct hvm_domain *plat = &v->domain->arch.hvm_domain;
    2.48 +
    2.49 +    /* APIC */
    2.50 +    if ( cpu_has_apic_interrupt(v) ) return 1;
    2.51 +    
    2.52 +    /* PIC */
    2.53 +    if ( !vlapic_accept_pic_intr(v) ) return 0;
    2.54 +
    2.55 +    return plat->interrupt_request;
    2.56  }
    2.57  
    2.58  asmlinkage void vmx_intr_assist(void)
    2.59  {
    2.60      int intr_type = 0;
    2.61      int highest_vector;
    2.62 -    unsigned long intr_fields, eflags, interruptibility, cpu_exec_control;
    2.63 +    unsigned long eflags;
    2.64      struct vcpu *v = current;
    2.65      struct hvm_domain *plat=&v->domain->arch.hvm_domain;
    2.66      struct hvm_virpit *vpit = &plat->vpit;
    2.67 @@ -121,37 +146,21 @@ asmlinkage void vmx_intr_assist(void)
    2.68          pic_set_irq(pic, 0, 1);
    2.69      }
    2.70  
    2.71 -    __vmread_vcpu(v, CPU_BASED_VM_EXEC_CONTROL, &cpu_exec_control);
    2.72 -    __vmread(VM_ENTRY_INTR_INFO_FIELD, &intr_fields);
    2.73 +    if ( !cpu_has_pending_irq(v) ) return;
    2.74  
    2.75 -    if (intr_fields & INTR_INFO_VALID_MASK) {
    2.76 -        enable_irq_window(cpu_exec_control);
    2.77 -        HVM_DBG_LOG(DBG_LEVEL_1, "vmx_intr_assist: intr_fields: %lx",
    2.78 -                    intr_fields);
    2.79 -        return;
    2.80 -    }
    2.81 -
    2.82 -    __vmread(GUEST_INTERRUPTIBILITY_INFO, &interruptibility);
    2.83 -
    2.84 -    if (interruptibility) {
    2.85 -        enable_irq_window(cpu_exec_control);
    2.86 -        HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility: %lx",interruptibility);
    2.87 +    if ( is_interruptibility_state() ) {    /* pre-cleared for emulated instruction */
    2.88 +        enable_irq_window(v);
    2.89 +        HVM_DBG_LOG(DBG_LEVEL_1, "interruptibility");
    2.90          return;
    2.91      }
    2.92  
    2.93      __vmread(GUEST_RFLAGS, &eflags);
    2.94      if (irq_masked(eflags)) {
    2.95 -        enable_irq_window(cpu_exec_control);
    2.96 +        enable_irq_window(v);
    2.97          return;
    2.98      }
    2.99  
   2.100      highest_vector = cpu_get_interrupt(v, &intr_type); 
   2.101 -
   2.102 -    if (highest_vector == -1) {
   2.103 -        disable_irq_window(cpu_exec_control);
   2.104 -        return;
   2.105 -    }
   2.106 -
   2.107      switch (intr_type) {
   2.108      case VLAPIC_DELIV_MODE_EXT:
   2.109      case VLAPIC_DELIV_MODE_FIXED:
     3.1 --- a/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 10 09:11:33 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/vmx/vmcs.c	Fri Mar 10 09:12:22 2006 +0100
     3.3 @@ -219,6 +219,7 @@ static void vmx_do_launch(struct vcpu *v
     3.4      error |= __vmwrite(CR0_READ_SHADOW, cr0);
     3.5      error |= __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
     3.6                         MONITOR_CPU_BASED_EXEC_CONTROLS);
     3.7 +    v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
     3.8  
     3.9      __asm__ __volatile__ ("mov %%cr4,%0" : "=r" (cr4) : );
    3.10  
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 10 09:11:33 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Mar 10 09:12:22 2006 +0100
     4.3 @@ -595,6 +595,7 @@ static void inline __update_guest_eip(un
     4.4  
     4.5      __vmread(GUEST_RIP, &current_eip);
     4.6      __vmwrite(GUEST_RIP, current_eip + inst_len);
     4.7 +    __vmwrite(GUEST_INTERRUPTIBILITY_INFO, 0);
     4.8  }
     4.9  
    4.10  
    4.11 @@ -2025,6 +2026,7 @@ asmlinkage void vmx_vmexit_handler(struc
    4.12      case EXIT_REASON_PENDING_INTERRUPT:
    4.13          __vmwrite(CPU_BASED_VM_EXEC_CONTROL,
    4.14                    MONITOR_CPU_BASED_EXEC_CONTROLS);
    4.15 +        v->arch.hvm_vcpu.u.vmx.exec_control = MONITOR_CPU_BASED_EXEC_CONTROLS;
    4.16          break;
    4.17      case EXIT_REASON_TASK_SWITCH:
    4.18          __hvm_bug(&regs);
     5.1 --- a/xen/include/asm-x86/hvm/io.h	Fri Mar 10 09:11:33 2006 +0100
     5.2 +++ b/xen/include/asm-x86/hvm/io.h	Fri Mar 10 09:12:22 2006 +0100
     5.3 @@ -154,6 +154,7 @@ extern void hvm_io_assist(struct vcpu *v
     5.4  extern void pic_irq_request(int *interrupt_request, int level);
     5.5  extern void hvm_pic_assist(struct vcpu *v);
     5.6  extern int cpu_get_interrupt(struct vcpu *v, int *type);
     5.7 +extern int cpu_has_pending_irq(struct vcpu *v);
     5.8  
     5.9  // XXX - think about this, maybe use bit 30 of the mfn to signify an MMIO frame.
    5.10  #define mmio_space(gpa) (!VALID_MFN(get_mfn_from_gpfn((gpa) >> PAGE_SHIFT)))
     6.1 --- a/xen/include/asm-x86/hvm/vlapic.h	Fri Mar 10 09:11:33 2006 +0100
     6.2 +++ b/xen/include/asm-x86/hvm/vlapic.h	Fri Mar 10 09:12:22 2006 +0100
     6.3 @@ -209,6 +209,7 @@ static uint32_t inline vlapic_get_base_a
     6.4  
     6.5  void vlapic_post_injection(struct vcpu* v, int vector, int deliver_mode);
     6.6  
     6.7 +int cpu_has_apic_interrupt(struct vcpu* v);
     6.8  int cpu_get_apic_interrupt(struct vcpu* v, int *mode);
     6.9  
    6.10  extern uint32_t vlapic_update_ppr(struct vlapic *vlapic);
     7.1 --- a/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 10 09:11:33 2006 +0100
     7.2 +++ b/xen/include/asm-x86/hvm/vmx/vmcs.h	Fri Mar 10 09:12:22 2006 +0100
     7.3 @@ -69,6 +69,7 @@ struct vmx_msr_state {
     7.4  struct arch_vmx_struct {
     7.5      struct vmcs_struct      *vmcs;  /* VMCS pointer in virtual. */
     7.6      unsigned int            launch_cpu; /* VMCS is valid on this CPU. */
     7.7 +    u32                     exec_control; /* cache of cpu execution control */
     7.8      unsigned long           flags;  /* VMCS flags */
     7.9      unsigned long           cpu_cr0; /* copy of guest CR0 */
    7.10      unsigned long           cpu_shadow_cr0; /* copy of guest read shadow CR0 */