ia64/xen-unstable

changeset 8843:3cb8e672b115

Fix HVM event handling some more.

Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Mon Feb 13 15:58:50 2006 +0100 (2006-02-13)
parents 79d6a1061ad2
children d6b16f57058a
files xen/arch/x86/hvm/io.c xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/svm/vmcb.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/io.h
line diff
     1.1 --- a/xen/arch/x86/hvm/io.c	Mon Feb 13 14:54:27 2006 +0100
     1.2 +++ b/xen/arch/x86/hvm/io.c	Mon Feb 13 15:58:50 2006 +0100
     1.3 @@ -704,7 +704,6 @@ void hvm_wait_io(void)
     1.4      {
     1.5          /* Clear master flag, selector flag, event flag each in turn. */
     1.6          v->vcpu_info->evtchn_upcall_pending = 0;
     1.7 -        smp_mb__before_clear_bit();
     1.8          clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
     1.9          smp_mb__after_clear_bit();
    1.10          if ( test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]) )
    1.11 @@ -727,6 +726,31 @@ void hvm_wait_io(void)
    1.12          v->vcpu_info->evtchn_upcall_pending = 1;
    1.13  }
    1.14  
    1.15 +void hvm_safe_block(void)
    1.16 +{
    1.17 +    struct vcpu *v = current;
    1.18 +    struct domain *d = v->domain;    
    1.19 +    int port = iopacket_port(d);
    1.20 +
    1.21 +    for ( ; ; )
    1.22 +    {
    1.23 +        /* Clear master flag & selector flag so we will wake from block. */
    1.24 +        v->vcpu_info->evtchn_upcall_pending = 0;
    1.25 +        clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
    1.26 +        smp_mb__after_clear_bit();
    1.27 +
    1.28 +        /* Event pending already? */
    1.29 +        if ( test_bit(port, &d->shared_info->evtchn_pending[0]) )
    1.30 +            break;
    1.31 +
    1.32 +        do_sched_op(SCHEDOP_block, 0);
    1.33 +    }
    1.34 +
    1.35 +    /* Reflect pending event in selector and master flags. */
    1.36 +    set_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
    1.37 +    v->vcpu_info->evtchn_upcall_pending = 1;
    1.38 +}
    1.39 +
    1.40  /*
    1.41   * Local variables:
    1.42   * mode: C
     2.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Feb 13 14:54:27 2006 +0100
     2.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Mon Feb 13 15:58:50 2006 +0100
     2.3 @@ -25,7 +25,6 @@
     2.4  #include <xen/sched.h>
     2.5  #include <xen/irq.h>
     2.6  #include <xen/softirq.h>
     2.7 -#include <xen/hypercall.h>
     2.8  #include <asm/current.h>
     2.9  #include <asm/io.h>
    2.10  #include <asm/shadow.h>
    2.11 @@ -1812,16 +1811,14 @@ static inline void svm_vmexit_do_hlt(str
    2.12      inst_len = __get_instruction_length(vmcb, INSTR_HLT, NULL);
    2.13      __update_guest_eip(vmcb, inst_len);
    2.14  
    2.15 -    if ( !v->vcpu_id ) {
    2.16 +    if ( !v->vcpu_id )
    2.17          next_pit = get_pit_scheduled(v, vpit);
    2.18 -    }
    2.19      next_wakeup = get_apictime_scheduled(v);
    2.20 -    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 ) {
    2.21 +    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
    2.22          next_wakeup = next_pit;
    2.23 -    }
    2.24      if ( next_wakeup != - 1 )
    2.25          set_timer(&current->arch.hvm_svm.hlt_timer, next_wakeup);
    2.26 -    do_sched_op(SCHEDOP_block, 0);
    2.27 +    hvm_safe_block();
    2.28  }
    2.29  
    2.30  
    2.31 @@ -2434,7 +2431,6 @@ asmlinkage void svm_vmexit_handler(struc
    2.32  #else
    2.33          svm_store_cpu_user_regs(&regs, v);
    2.34          domain_pause_for_debugger();  
    2.35 -        do_sched_op(SCHEDOP_yield, 0);
    2.36  #endif
    2.37      }
    2.38      break;
     3.1 --- a/xen/arch/x86/hvm/svm/vmcb.c	Mon Feb 13 14:54:27 2006 +0100
     3.2 +++ b/xen/arch/x86/hvm/svm/vmcb.c	Mon Feb 13 15:58:50 2006 +0100
     3.3 @@ -487,16 +487,16 @@ int load_vmcb(struct arch_svm_struct *ar
     3.4   */
     3.5  void svm_do_resume(struct vcpu *v) 
     3.6  {
     3.7 -    struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
     3.8 +    struct domain *d = v->domain;
     3.9 +    struct hvm_virpit *vpit = &d->arch.hvm_domain.vpit;
    3.10      
    3.11 -    if ( event_pending(v) ||
    3.12 +    if ( test_bit(iopacket_port(d), &d->shared_info->evtchn_pending[0]) ||
    3.13           test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
    3.14          hvm_wait_io();
    3.15  
    3.16      /* pick up the elapsed PIT ticks and re-enable pit_timer */
    3.17 -    if ( vpit->first_injected ) {
    3.18 +    if ( vpit->first_injected )
    3.19          pickup_deactive_ticks(vpit);
    3.20 -    }
    3.21      svm_set_tsc_shift(v, vpit);
    3.22      
    3.23      /* We can't resume the guest if we're waiting on I/O */
     4.1 --- a/xen/arch/x86/hvm/vmx/io.c	Mon Feb 13 14:54:27 2006 +0100
     4.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Mon Feb 13 15:58:50 2006 +0100
     4.3 @@ -173,11 +173,12 @@ asmlinkage void vmx_intr_assist(void)
     4.4  
     4.5  void vmx_do_resume(struct vcpu *v)
     4.6  {
     4.7 -    struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
     4.8 +    struct domain *d = v->domain;
     4.9 +    struct hvm_virpit *vpit = &v->domain->arch.hvm_domain.vpit;
    4.10  
    4.11      vmx_stts();
    4.12  
    4.13 -    if ( event_pending(v) ||
    4.14 +    if ( test_bit(iopacket_port(d), &d->shared_info->evtchn_pending[0]) ||
    4.15           test_bit(ARCH_HVM_IO_WAIT, &v->arch.hvm_vcpu.ioflags) )
    4.16          hvm_wait_io();
    4.17  
     5.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 13 14:54:27 2006 +0100
     5.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Mon Feb 13 15:58:50 2006 +0100
     5.3 @@ -25,7 +25,6 @@
     5.4  #include <xen/irq.h>
     5.5  #include <xen/softirq.h>
     5.6  #include <xen/domain_page.h>
     5.7 -#include <xen/hypercall.h>
     5.8  #include <asm/current.h>
     5.9  #include <asm/io.h>
    5.10  #include <asm/shadow.h>
    5.11 @@ -1643,16 +1642,14 @@ void vmx_vmexit_do_hlt(void)
    5.12      struct hvm_virpit *vpit = &(v->domain->arch.hvm_domain.vpit);
    5.13      s_time_t   next_pit=-1,next_wakeup;
    5.14  
    5.15 -    if ( !v->vcpu_id ) {
    5.16 +    if ( !v->vcpu_id )
    5.17          next_pit = get_pit_scheduled(v,vpit);
    5.18 -    }
    5.19      next_wakeup = get_apictime_scheduled(v);
    5.20 -    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 ) {
    5.21 +    if ( (next_pit != -1 && next_pit < next_wakeup) || next_wakeup == -1 )
    5.22          next_wakeup = next_pit;
    5.23 -    }
    5.24      if ( next_wakeup != - 1 ) 
    5.25          set_timer(&current->arch.hvm_vmx.hlt_timer, next_wakeup);
    5.26 -    do_sched_op(SCHEDOP_block, 0);
    5.27 +    hvm_safe_block();
    5.28  }
    5.29  
    5.30  static inline void vmx_vmexit_do_extint(struct cpu_user_regs *regs)
    5.31 @@ -1849,7 +1846,6 @@ asmlinkage void vmx_vmexit_handler(struc
    5.32              __vm_clear_bit(GUEST_PENDING_DBG_EXCEPTIONS, PENDING_DEBUG_EXC_BS);
    5.33  
    5.34              domain_pause_for_debugger();
    5.35 -            do_sched_op(SCHEDOP_yield, 0);
    5.36  
    5.37              break;
    5.38          }
     6.1 --- a/xen/include/asm-x86/hvm/io.h	Mon Feb 13 14:54:27 2006 +0100
     6.2 +++ b/xen/include/asm-x86/hvm/io.h	Mon Feb 13 15:58:50 2006 +0100
     6.3 @@ -148,6 +148,7 @@ static inline int irq_masked(unsigned lo
     6.4  
     6.5  extern void handle_mmio(unsigned long, unsigned long);
     6.6  extern void hvm_wait_io(void);
     6.7 +extern void hvm_safe_block(void);
     6.8  extern void hvm_io_assist(struct vcpu *v);
     6.9  extern void pic_irq_request(int *interrupt_request, int level);
    6.10  extern void hvm_pic_assist(struct vcpu *v);