ia64/xen-unstable

changeset 15902:764d33505b98

[IA64] Make viosapic SMP-safe adding lock/unlock similar to x86 vioapic

Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp>
author Alex Williamson <alex.williamson@hp.com>
date Thu Sep 27 09:08:26 2007 -0600 (2007-09-27)
parents b658296982ee
children eae7b887e5ac
files xen/arch/ia64/vmx/viosapic.c xen/arch/ia64/vmx/vlsapic.c
line diff
     1.1 --- a/xen/arch/ia64/vmx/viosapic.c	Thu Sep 27 09:03:43 2007 -0600
     1.2 +++ b/xen/arch/ia64/vmx/viosapic.c	Thu Sep 27 09:08:26 2007 -0600
     1.3 @@ -23,6 +23,10 @@
     1.4   *
     1.5   *  Yunhong Jiang <yunhong.jiang@intel.com>
     1.6   *  Ported to xen by using virtual IRQ line.
     1.7 + * 
     1.8 + *  Copyright (C) 2007 VA Linux Systems Japan K.K.
     1.9 + *  Isaku Yamahata <yamahata at valinux co jp>
    1.10 + *  SMP support
    1.11   */
    1.12  
    1.13  #include <xen/config.h>
    1.14 @@ -44,6 +48,7 @@ static void viosapic_deliver(struct vios
    1.15      uint8_t vector = viosapic->redirtbl[irq].vector;
    1.16      struct vcpu *v;
    1.17  
    1.18 +    ASSERT(spin_is_locked(&viosapic->lock));
    1.19      switch ( delivery_mode )
    1.20      {
    1.21      case SAPIC_FIXED:
    1.22 @@ -90,6 +95,7 @@ static int get_redir_num(struct viosapic
    1.23  {
    1.24      int i;
    1.25  
    1.26 +    ASSERT(spin_is_locked(&viosapic->lock));
    1.27      for ( i = 0; i < VIOSAPIC_NUM_PINS; i++ )
    1.28          if ( viosapic->redirtbl[i].vector == vector )
    1.29              return i;
    1.30 @@ -118,19 +124,23 @@ static void viosapic_update_EOI(struct v
    1.31  {
    1.32      int redir_num;
    1.33  
    1.34 +    spin_lock(&viosapic->lock);
    1.35      if ( (redir_num = get_redir_num(viosapic, vector)) == -1 )
    1.36      {
    1.37 +        spin_unlock(&viosapic->lock);
    1.38          gdprintk(XENLOG_WARNING, "Can't find redir item for %d EOI\n", vector);
    1.39          return;
    1.40      }
    1.41  
    1.42      if ( !test_and_clear_bit(redir_num, &viosapic->isr) )
    1.43      {
    1.44 +        spin_unlock(&viosapic->lock);
    1.45          gdprintk(XENLOG_WARNING, "redir %d not set for %d EOI\n",
    1.46                   redir_num, vector);
    1.47          return;
    1.48      }
    1.49      service_iosapic(viosapic);
    1.50 +    spin_unlock(&viosapic->lock);
    1.51  }
    1.52  
    1.53  
    1.54 @@ -149,18 +159,21 @@ static unsigned long viosapic_read_indir
    1.55  
    1.56      default:
    1.57      {
    1.58 -        uint32_t redir_index = (viosapic->ioregsel - 0x10) >> 1;
    1.59 +        /* ioregsel might be written at the same time. copy it before use. */
    1.60 +        uint32_t ioregsel = viosapic->ioregsel;
    1.61 +        uint32_t redir_index;
    1.62          uint64_t redir_content;
    1.63  
    1.64 +        redir_index = (ioregsel - 0x10) >> 1;
    1.65          if ( redir_index >= VIOSAPIC_NUM_PINS )
    1.66          {
    1.67              gdprintk(XENLOG_WARNING, "viosapic_read_indirect:undefined "
    1.68 -                     "ioregsel %x\n", viosapic->ioregsel);
    1.69 +                     "ioregsel %x\n", ioregsel);
    1.70              break;
    1.71          }
    1.72  
    1.73          redir_content = viosapic->redirtbl[redir_index].bits;
    1.74 -        result = (viosapic->ioregsel & 0x1) ?
    1.75 +        result = (ioregsel & 0x1) ?
    1.76                   (redir_content >> 32) & 0xffffffff :
    1.77                   redir_content & 0xffffffff;
    1.78          break;
    1.79 @@ -212,9 +225,12 @@ static void viosapic_write_indirect(stru
    1.80  
    1.81      default:
    1.82      {
    1.83 -        uint32_t redir_index = (viosapic->ioregsel - 0x10) >> 1;
    1.84 +        /* ioregsel might be written at the same time. copy it before use. */
    1.85 +        uint32_t ioregsel = viosapic->ioregsel;
    1.86 +        uint32_t redir_index;
    1.87          uint64_t redir_content;
    1.88  
    1.89 +        redir_index = (ioregsel - 0x10) >> 1;
    1.90          if ( redir_index >= VIOSAPIC_NUM_PINS )
    1.91          {
    1.92              gdprintk(XENLOG_WARNING, "viosapic_write_indirect "
    1.93 @@ -222,9 +238,10 @@ static void viosapic_write_indirect(stru
    1.94              break;
    1.95          }
    1.96  
    1.97 +        spin_lock(&viosapic->lock);
    1.98          redir_content = viosapic->redirtbl[redir_index].bits;
    1.99  
   1.100 -        if ( viosapic->ioregsel & 0x1 )
   1.101 +        if ( ioregsel & 0x1 )
   1.102          {
   1.103              redir_content = (((uint64_t)val & 0xffffffff) << 32) |
   1.104                              (redir_content & 0xffffffff);
   1.105 @@ -235,6 +252,7 @@ static void viosapic_write_indirect(stru
   1.106                              (val & 0xffffffff);
   1.107          }
   1.108          viosapic->redirtbl[redir_index].bits = redir_content;
   1.109 +        spin_unlock(&viosapic->lock);
   1.110          break;
   1.111      }
   1.112      } /* switch */
     2.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Thu Sep 27 09:03:43 2007 -0600
     2.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Thu Sep 27 09:08:26 2007 -0600
     2.3 @@ -768,6 +768,8 @@ static void vlsapic_write_xtp(struct vcp
     2.4      struct viosapic * viosapic;
     2.5      struct vcpu *lvcpu, *vcpu;
     2.6      viosapic = vcpu_viosapic(v); 
     2.7 +
     2.8 +    spin_lock(&viosapic->lock);
     2.9      lvcpu = viosapic->lowest_vcpu;
    2.10      VLSAPIC_XTP(v) = val;
    2.11      
    2.12 @@ -780,6 +782,7 @@ static void vlsapic_write_xtp(struct vcp
    2.13          lvcpu = NULL;
    2.14  
    2.15      viosapic->lowest_vcpu = lvcpu;
    2.16 +    spin_unlock(&viosapic->lock);
    2.17  }
    2.18  
    2.19  void vlsapic_write(struct vcpu *v,