ia64/xen-unstable

changeset 12319:6555ca56d844

[HVM] Simplify relationship between VIOAPIC and VLAPICs.
It's not really dynamic since there is always exactly
one VLAPIC per VCPU.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Wed Nov 08 15:11:18 2006 +0000 (2006-11-08)
parents 1d4fc7396c41
children 9f9f569b0a1d
files xen/arch/ia64/vmx/vlsapic.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vlapic.c xen/include/asm-x86/hvm/vioapic.h
line diff
     1.1 --- a/xen/arch/ia64/vmx/vlsapic.c	Wed Nov 08 15:10:21 2006 +0000
     1.2 +++ b/xen/arch/ia64/vmx/vlsapic.c	Wed Nov 08 15:11:18 2006 +0000
     1.3 @@ -324,9 +324,9 @@ void vtm_domain_in(VCPU *vcpu)
     1.4   */
     1.5  
     1.6  #ifdef V_IOSAPIC_READY
     1.7 -int ioapic_match_logical_addr(struct vioapic *s, int number, uint16_t dest)
     1.8 +int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest)
     1.9  {
    1.10 -    return (VLAPIC_ID(s->lapic_info[number]) == dest);
    1.11 +    return (VLAPIC_ID(vlapic) == dest);
    1.12  }
    1.13  
    1.14  struct vlapic* apic_round_robin(struct domain *d,
    1.15 @@ -334,21 +334,17 @@ struct vlapic* apic_round_robin(struct d
    1.16  				uint8_t vector,
    1.17  				uint32_t bitmap)
    1.18  {
    1.19 -    uint8_t bit;
    1.20 -    struct vioapic *s;
    1.21 +    uint8_t bit = 0;
    1.22      
    1.23      if (!bitmap) {
    1.24  	printk("<apic_round_robin> no bit on bitmap\n");
    1.25  	return NULL;
    1.26      }
    1.27  
    1.28 -    s = domain_vioapic(d);
    1.29 -    for (bit = 0; bit < s->lapic_count; bit++) {
    1.30 -	if (bitmap & (1 << bit))
    1.31 -	    return s->lapic_info[bit];
    1.32 -    }
    1.33 +    while (!(bitmap & (1 << bit)))
    1.34 +        bit++;
    1.35  
    1.36 -    return NULL;
    1.37 +    return vcpu_vlapic(d->vcpu[bit]);
    1.38  }
    1.39  #endif
    1.40  
    1.41 @@ -375,7 +371,6 @@ void vlsapic_reset(VCPU *vcpu)
    1.42  
    1.43  #ifdef V_IOSAPIC_READY
    1.44      vcpu->arch.arch_vmx.vlapic.vcpu = vcpu;
    1.45 -    vioapic_add_lapic(&vcpu->arch.arch_vmx.vlapic, vcpu);
    1.46  #endif
    1.47      dprintk(XENLOG_INFO, "VLSAPIC inservice base=%p\n", &VLSAPIC_INSVC(vcpu,0) );
    1.48  }
     2.1 --- a/xen/arch/x86/hvm/vioapic.c	Wed Nov 08 15:10:21 2006 +0000
     2.2 +++ b/xen/arch/x86/hvm/vioapic.c	Wed Nov 08 15:11:18 2006 +0000
     2.3 @@ -49,19 +49,6 @@ static int redir_warning_done = 0;
     2.4  #define opt_hvm_debug_level opt_vmx_debug_level
     2.5  #endif
     2.6  
     2.7 -#ifdef HVM_DOMAIN_SAVE_RESTORE
     2.8 -void ioapic_save(QEMUFile* f, void* opaque)
     2.9 -{
    2.10 -    printk("no implementation for ioapic_save\n");
    2.11 -}
    2.12 -
    2.13 -int ioapic_load(QEMUFile* f, void* opaque, int version_id)
    2.14 -{
    2.15 -    printk("no implementation for ioapic_load\n");
    2.16 -    return 0;
    2.17 -}
    2.18 -#endif
    2.19 -
    2.20  static unsigned long vioapic_read_indirect(struct vioapic *vioapic,
    2.21                                             unsigned long addr,
    2.22                                             unsigned long length)
    2.23 @@ -299,19 +286,18 @@ static int ioapic_inj_irq(struct vioapic
    2.24  }
    2.25  
    2.26  #ifndef __ia64__
    2.27 -static int ioapic_match_logical_addr(
    2.28 -    struct vioapic *vioapic, int number, uint8_t dest)
    2.29 +static int vlapic_match_logical_addr(struct vlapic *vlapic, uint8_t dest)
    2.30  {
    2.31      int result = 0;
    2.32      uint32_t logical_dest;
    2.33  
    2.34 -    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_match_logical_addr "
    2.35 -                "number %i dest %x\n",
    2.36 -                number, dest);
    2.37 +    HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "vlapic_match_logical_addr "
    2.38 +                "vcpu=%d vlapic_id=%x dest=%x\n",
    2.39 +                vlapic_vcpu(vlapic)->vcpu_id, VLAPIC_ID(vlapic), dest);
    2.40  
    2.41 -    logical_dest = vlapic_get_reg(vioapic->lapic_info[number], APIC_LDR);
    2.42 +    logical_dest = vlapic_get_reg(vlapic, APIC_LDR);
    2.43  
    2.44 -    switch ( vlapic_get_reg(vioapic->lapic_info[number], APIC_DFR) )
    2.45 +    switch ( vlapic_get_reg(vlapic, APIC_DFR) )
    2.46      {
    2.47      case APIC_DFR_FLAT:
    2.48          result = ((dest & GET_APIC_LOGICAL_ID(logical_dest)) != 0);
    2.49 @@ -324,15 +310,15 @@ static int ioapic_match_logical_addr(
    2.50              result = 1;
    2.51          break;
    2.52      default:
    2.53 -        gdprintk(XENLOG_WARNING, "error DFR value for %x lapic\n", number);
    2.54 +        gdprintk(XENLOG_WARNING, "error DFR value for lapic of vcpu %d\n",
    2.55 +                 vlapic_vcpu(vlapic)->vcpu_id);
    2.56          break;
    2.57      }
    2.58  
    2.59      return result;
    2.60  }
    2.61  #else
    2.62 -extern int ioapic_match_logical_addr(
    2.63 -    struct vioapic *vioapic, int number, uint8_t dest);
    2.64 +extern int vlapic_match_logical_addr(struct vlapic *vlapic, uint16_t dest);
    2.65  #endif
    2.66  
    2.67  static uint32_t ioapic_get_delivery_bitmask(struct vioapic *vioapic,
    2.68 @@ -342,49 +328,40 @@ static uint32_t ioapic_get_delivery_bitm
    2.69                                              uint8_t delivery_mode)
    2.70  {
    2.71      uint32_t mask = 0;
    2.72 -    int i;
    2.73 +    struct vcpu *v;
    2.74  
    2.75      HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
    2.76 -                "dest %d dest_mode %d "
    2.77 -                "vector %d del_mode %d, lapic_count %d\n",
    2.78 -                dest, dest_mode, vector, delivery_mode, vioapic->lapic_count);
    2.79 +                "dest %d dest_mode %d vector %d del_mode %d\n",
    2.80 +                dest, dest_mode, vector, delivery_mode);
    2.81  
    2.82 -    if ( dest_mode == 0 )
    2.83 +    if ( dest_mode == 0 ) /* Physical mode. */
    2.84      {
    2.85 -        /* Physical mode. */
    2.86 -        for ( i = 0; i < vioapic->lapic_count; i++ )
    2.87 +        if ( dest == 0xFF ) /* Broadcast. */
    2.88          {
    2.89 -            if ( VLAPIC_ID(vioapic->lapic_info[i]) == dest )
    2.90 +            for_each_vcpu ( vioapic_domain(vioapic), v )
    2.91 +                mask |= 1 << v->vcpu_id;
    2.92 +            goto out;
    2.93 +        }
    2.94 +
    2.95 +        for_each_vcpu ( vioapic_domain(vioapic), v )
    2.96 +        {
    2.97 +            if ( VLAPIC_ID(vcpu_vlapic(v)) == dest )
    2.98              {
    2.99 -                mask = 1 << i;
   2.100 +                mask = 1 << v->vcpu_id;
   2.101                  break;
   2.102              }
   2.103          }
   2.104 -
   2.105 -        /* Broadcast. */
   2.106 -        if ( dest == 0xFF )
   2.107 -        {
   2.108 -            for ( i = 0; i < vioapic->lapic_count; i++ )
   2.109 -                mask |= ( 1 << i );
   2.110 -        }
   2.111      }
   2.112 -    else
   2.113 +    else if ( dest != 0 ) /* Logical mode, MDA non-zero. */
   2.114      {
   2.115 -        /* Logical destination. Call match_logical_addr for each APIC. */
   2.116 -        if ( dest != 0 )
   2.117 -        {
   2.118 -            for ( i = 0; i < vioapic->lapic_count; i++ )
   2.119 -            {
   2.120 -                if ( vioapic->lapic_info[i] &&
   2.121 -                     ioapic_match_logical_addr(vioapic, i, dest) )
   2.122 -                    mask |= (1<<i);
   2.123 -            }
   2.124 -        }
   2.125 +        for_each_vcpu ( vioapic_domain(vioapic), v )
   2.126 +            if ( vlapic_match_logical_addr(vcpu_vlapic(v), dest) )
   2.127 +                mask |= 1 << v->vcpu_id;
   2.128      }
   2.129  
   2.130 + out:
   2.131      HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic_get_delivery_bitmask "
   2.132                  "mask %x\n", mask);
   2.133 -
   2.134      return mask;
   2.135  }
   2.136  
   2.137 @@ -397,6 +374,7 @@ static void ioapic_deliver(struct vioapi
   2.138      uint8_t trig_mode = vioapic->redirtbl[irq].fields.trig_mode;
   2.139      uint32_t deliver_bitmask;
   2.140      struct vlapic *target;
   2.141 +    struct vcpu *v;
   2.142  
   2.143      HVM_DBG_LOG(DBG_LEVEL_IOAPIC,
   2.144                  "dest=%x dest_mode=%x delivery_mode=%x "
   2.145 @@ -419,7 +397,10 @@ static void ioapic_deliver(struct vioapi
   2.146  #ifdef IRQ0_SPECIAL_ROUTING
   2.147          /* Force round-robin to pick VCPU 0 */
   2.148          if ( irq == 0 )
   2.149 -            target = vioapic->lapic_info[0];
   2.150 +        {
   2.151 +            v = vioapic_domain(vioapic)->vcpu[0];
   2.152 +            target = v ? vcpu_vlapic(v) : NULL;
   2.153 +        }
   2.154          else
   2.155  #endif
   2.156              target = apic_round_robin(vioapic_domain(vioapic), dest_mode,
   2.157 @@ -442,19 +423,21 @@ static void ioapic_deliver(struct vioapi
   2.158      case dest_ExtINT:
   2.159      {
   2.160          uint8_t bit;
   2.161 -        for ( bit = 0; bit < vioapic->lapic_count; bit++ )
   2.162 +        for ( bit = 0; deliver_bitmask != 0; bit++ )
   2.163          {
   2.164              if ( !(deliver_bitmask & (1 << bit)) )
   2.165                  continue;
   2.166 +            deliver_bitmask &= ~(1 << bit);
   2.167  #ifdef IRQ0_SPECIAL_ROUTING
   2.168              /* Do not deliver timer interrupts to VCPU != 0 */
   2.169              if ( (irq == 0) && (bit != 0) )
   2.170 -                target = vioapic->lapic_info[0];
   2.171 +                v = vioapic_domain(vioapic)->vcpu[0];
   2.172              else
   2.173  #endif
   2.174 -                target = vioapic->lapic_info[bit];
   2.175 -            if ( target != NULL )
   2.176 +                v = vioapic_domain(vioapic)->vcpu[bit];
   2.177 +            if ( v != NULL )
   2.178              {
   2.179 +                target = vcpu_vlapic(v);
   2.180                  ioapic_inj_irq(vioapic, target, vector,
   2.181                                 trig_mode, delivery_mode);
   2.182                  vcpu_kick(vlapic_vcpu(target));
   2.183 @@ -595,26 +578,6 @@ void vioapic_update_EOI(struct domain *d
   2.184      }
   2.185  }
   2.186  
   2.187 -int vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v)
   2.188 -{
   2.189 -    struct vioapic *vioapic = domain_vioapic(v->domain);
   2.190 -
   2.191 -    if ( v->vcpu_id != vioapic->lapic_count )
   2.192 -    {
   2.193 -        gdprintk(XENLOG_ERR, "vioapic_add_lapic "
   2.194 -                 "cpu_id not match vcpu_id %x lapic_count %x\n",
   2.195 -                 v->vcpu_id, vioapic->lapic_count);
   2.196 -        domain_crash_synchronous();
   2.197 -    }
   2.198 -
   2.199 -    /* Update count later for race condition on interrupt. */
   2.200 -    vioapic->lapic_info[vioapic->lapic_count] = vlapic;
   2.201 -    wmb();
   2.202 -    vioapic->lapic_count++;
   2.203 -
   2.204 -    return vioapic->lapic_count;
   2.205 -}
   2.206 -
   2.207  void vioapic_init(struct domain *d)
   2.208  {
   2.209      struct vioapic *vioapic = domain_vioapic(d);
     3.1 --- a/xen/arch/x86/hvm/vlapic.c	Wed Nov 08 15:10:21 2006 +0000
     3.2 +++ b/xen/arch/x86/hvm/vlapic.c	Wed Nov 08 15:11:18 2006 +0000
     3.3 @@ -1001,8 +1001,6 @@ int vlapic_init(struct vcpu *v)
     3.4      if ( v->vcpu_id == 0 )
     3.5          vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
     3.6  
     3.7 -    vioapic_add_lapic(vlapic, v);
     3.8 -
     3.9      init_timer(&vlapic->vlapic_timer,
    3.10                    vlapic_timer_fn, vlapic, v->processor);
    3.11  
     4.1 --- a/xen/include/asm-x86/hvm/vioapic.h	Wed Nov 08 15:10:21 2006 +0000
     4.2 +++ b/xen/include/asm-x86/hvm/vioapic.h	Wed Nov 08 15:11:18 2006 +0000
     4.3 @@ -94,19 +94,11 @@ struct vioapic {
     4.4      uint32_t id;
     4.5      unsigned long base_address;
     4.6      union vioapic_redir_entry redirtbl[VIOAPIC_NUM_PINS];
     4.7 -    struct vlapic *lapic_info[32];
     4.8 -    uint32_t lapic_count;
     4.9  };
    4.10  
    4.11  void vioapic_init(struct domain *d);
    4.12  void vioapic_set_xen_irq(struct domain *d, int irq, int level);
    4.13  void vioapic_set_irq(struct domain *d, int irq, int level);
    4.14 -int  vioapic_add_lapic(struct vlapic *vlapic, struct vcpu *v);
    4.15  void vioapic_update_EOI(struct domain *d, int vector);
    4.16  
    4.17 -#ifdef HVM_DOMAIN_SAVE_RESTORE
    4.18 -void ioapic_save(QEMUFile* f, void* opaque);
    4.19 -int ioapic_load(QEMUFile* f, void* opaque, int version_id);
    4.20 -#endif
    4.21 -
    4.22  #endif /* __ASM_X86_HVM_VIOAPIC_H__ */