ia64/xen-unstable

changeset 12431:e0dc5a544ea1

[HVM] vlapic: More cleanups, simplifications and fixes.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kfraser@localhost.localdomain
date Tue Nov 14 10:44:16 2006 +0000 (2006-11-14)
parents 5b97dafc7448
children 72560fd8e9bf
files xen/arch/x86/hvm/svm/svm.c xen/arch/x86/hvm/vlapic.c xen/arch/x86/hvm/vmx/io.c xen/arch/x86/hvm/vmx/vmx.c xen/include/asm-x86/hvm/vlapic.h
line diff
     1.1 --- a/xen/arch/x86/hvm/svm/svm.c	Mon Nov 13 17:23:49 2006 -0700
     1.2 +++ b/xen/arch/x86/hvm/svm/svm.c	Tue Nov 14 10:44:16 2006 +0000
     1.3 @@ -990,7 +990,7 @@ static void svm_vmexit_do_cpuid(struct v
     1.4          cpuid(input, &eax, &ebx, &ecx, &edx);       
     1.5          if (input == 0x00000001 || input == 0x80000001 )
     1.6          {
     1.7 -            if ( !vlapic_global_enabled(vcpu_vlapic(v)) )
     1.8 +            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
     1.9              {
    1.10                  /* Since the apic is disabled, avoid any confusion 
    1.11                     about SMP cpus being available */
     2.1 --- a/xen/arch/x86/hvm/vlapic.c	Mon Nov 13 17:23:49 2006 -0700
     2.2 +++ b/xen/arch/x86/hvm/vlapic.c	Tue Nov 14 10:44:16 2006 +0000
     2.3 @@ -71,18 +71,23 @@ static unsigned int vlapic_lvt_mask[VLAP
     2.4  #define APIC_DEST_NOSHORT                0x0
     2.5  #define APIC_DEST_MASK                   0x800
     2.6  
     2.7 -#define vlapic_lvt_enabled(vlapic, lvt_type)    \
     2.8 +#define vlapic_lvt_enabled(vlapic, lvt_type)                    \
     2.9      (!(vlapic_get_reg(vlapic, lvt_type) & APIC_LVT_MASKED))
    2.10  
    2.11 -#define vlapic_lvt_vector(vlapic, lvt_type)     \
    2.12 +#define vlapic_lvt_vector(vlapic, lvt_type)                     \
    2.13      (vlapic_get_reg(vlapic, lvt_type) & APIC_VECTOR_MASK)
    2.14  
    2.15 -#define vlapic_lvt_dm(vlapic, lvt_type)           \
    2.16 +#define vlapic_lvt_dm(vlapic, lvt_type)                         \
    2.17      (vlapic_get_reg(vlapic, lvt_type) & APIC_MODE_MASK)
    2.18  
    2.19 -#define vlapic_lvtt_period(vlapic)     \
    2.20 +#define vlapic_lvtt_period(vlapic)                              \
    2.21      (vlapic_get_reg(vlapic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC)
    2.22  
    2.23 +#define vlapic_base_address(vlapic)                             \
    2.24 +    (vlapic->apic_base_msr & MSR_IA32_APICBASE_BASE)
    2.25 +
    2.26 +static int vlapic_reset(struct vlapic *vlapic);
    2.27 +
    2.28  /*
    2.29   * Generic APIC bitmap vector update & search routines.
    2.30   */
    2.31 @@ -238,8 +243,7 @@ static int vlapic_match_dest(struct vcpu
    2.32          if ( dest_mode == 0 )
    2.33          {
    2.34              /* Physical mode. */
    2.35 -            if ( (dest == 0xFF) || /* broadcast? */
    2.36 -                 (GET_APIC_ID(vlapic_get_reg(target, APIC_ID)) == dest) )
    2.37 +            if ( (dest == 0xFF) || (dest == v->vcpu_id) )
    2.38                  result = 1;
    2.39          }
    2.40          else
    2.41 @@ -283,7 +287,7 @@ static int vlapic_accept_irq(struct vcpu
    2.42      case APIC_DM_FIXED:
    2.43      case APIC_DM_LOWEST:
    2.44          /* FIXME add logic for vcpu on reset */
    2.45 -        if ( unlikely(vlapic == NULL || !vlapic_enabled(vlapic)) )
    2.46 +        if ( unlikely(!vlapic_enabled(vlapic)) )
    2.47              break;
    2.48  
    2.49          if ( vlapic_test_and_set_irr(vector, vlapic) && trig_mode )
    2.50 @@ -319,7 +323,7 @@ static int vlapic_accept_irq(struct vcpu
    2.51          if ( trig_mode && !(level & APIC_INT_ASSERT) )
    2.52              break;
    2.53          /* FIXME How to check the situation after vcpu reset? */
    2.54 -        if ( test_and_clear_bit(_VCPUF_initialised, &v->vcpu_flags) )
    2.55 +        if ( test_bit(_VCPUF_initialised, &v->vcpu_flags) )
    2.56          {
    2.57              gdprintk(XENLOG_ERR, "Reset hvm vcpu not supported yet\n");
    2.58              goto exit_and_crash;
    2.59 @@ -371,21 +375,15 @@ struct vlapic *apic_round_robin(
    2.60  
    2.61      old = next = d->arch.hvm_domain.round_info[vector];
    2.62  
    2.63 -    /* the vcpu array is arranged according to vcpu_id */
    2.64      do {
    2.65          if ( ++next == MAX_VIRT_CPUS ) 
    2.66              next = 0;
    2.67 -        if ( (d->vcpu[next] == NULL) ||
    2.68 -             !test_bit(_VCPUF_initialised, &d->vcpu[next]->vcpu_flags) )
    2.69 +        if ( (d->vcpu[next] == NULL) || !test_bit(next, &bitmap) )
    2.70              continue;
    2.71 -
    2.72 -        if ( test_bit(next, &bitmap) )
    2.73 -        {
    2.74 -            target = vcpu_vlapic(d->vcpu[next]);
    2.75 -            if ( vlapic_enabled(target) )
    2.76 -                break;
    2.77 -            target = NULL;
    2.78 -        }
    2.79 +        target = vcpu_vlapic(d->vcpu[next]);
    2.80 +        if ( vlapic_enabled(target) )
    2.81 +            break;
    2.82 +        target = NULL;
    2.83      } while ( next != old );
    2.84  
    2.85      d->arch.hvm_domain.round_info[vector] = next;
    2.86 @@ -398,10 +396,9 @@ void vlapic_EOI_set(struct vlapic *vlapi
    2.87  {
    2.88      int vector = vlapic_find_highest_isr(vlapic);
    2.89  
    2.90 -    /* Not every write EOI will has correpsoning ISR,
    2.91 -       one example is when Kernel check timer on setup_IO_APIC */
    2.92 +    /* Some EOI writes may not have a matching to an in-service interrupt. */
    2.93      if ( vector == -1 )
    2.94 -        return ;
    2.95 +        return;
    2.96  
    2.97      vlapic_clear_vector(vector, vlapic->regs + APIC_ISR);
    2.98  
    2.99 @@ -538,7 +535,7 @@ static unsigned long vlapic_read(struct 
   2.100      unsigned int tmp;
   2.101      unsigned long result;
   2.102      struct vlapic *vlapic = vcpu_vlapic(v);
   2.103 -    unsigned int offset = address - vlapic->base_address;
   2.104 +    unsigned int offset = address - vlapic_base_address(vlapic);
   2.105  
   2.106      if ( offset > APIC_TDCR )
   2.107          return 0;
   2.108 @@ -588,7 +585,7 @@ static void vlapic_write(struct vcpu *v,
   2.109                           unsigned long len, unsigned long val)
   2.110  {
   2.111      struct vlapic *vlapic = vcpu_vlapic(v);
   2.112 -    unsigned int offset = address - vlapic->base_address;
   2.113 +    unsigned int offset = address - vlapic_base_address(vlapic);
   2.114  
   2.115      if ( offset != 0xb0 )
   2.116          HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
   2.117 @@ -641,10 +638,6 @@ static void vlapic_write(struct vcpu *v,
   2.118  
   2.119      switch ( offset )
   2.120      {
   2.121 -    case APIC_ID:   /* Local APIC ID */
   2.122 -        vlapic_set_reg(vlapic, APIC_ID, val);
   2.123 -        break;
   2.124 -
   2.125      case APIC_TASKPRI:
   2.126          vlapic_set_reg(vlapic, APIC_TASKPRI, val & 0xff);
   2.127          vlapic->flush_tpr_threshold = 1;
   2.128 @@ -670,7 +663,7 @@ static void vlapic_write(struct vcpu *v,
   2.129              int i;
   2.130              uint32_t lvt_val;
   2.131  
   2.132 -            vlapic->status |= VLAPIC_SOFTWARE_DISABLE_MASK;
   2.133 +            vlapic->disabled |= VLAPIC_SW_DISABLED;
   2.134  
   2.135              for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
   2.136              {
   2.137 @@ -678,17 +671,11 @@ static void vlapic_write(struct vcpu *v,
   2.138                  vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i,
   2.139                                 lvt_val | APIC_LVT_MASKED);
   2.140              }
   2.141 -
   2.142 -            if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
   2.143 -                 == APIC_DM_EXTINT )
   2.144 -                clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.145          }
   2.146          else
   2.147          {
   2.148 -            vlapic->status &= ~VLAPIC_SOFTWARE_DISABLE_MASK;
   2.149 -            if ( (vlapic_get_reg(vlapic, APIC_LVT0) & APIC_MODE_MASK)
   2.150 -                  == APIC_DM_EXTINT )
   2.151 -                set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.152 +            vlapic->disabled &= ~VLAPIC_SW_DISABLED;
   2.153 +            vlapic->flush_tpr_threshold = 1;
   2.154          }
   2.155          break;
   2.156  
   2.157 @@ -712,26 +699,11 @@ static void vlapic_write(struct vcpu *v,
   2.158      case APIC_LVT0:         /* LVT LINT0 Reg */
   2.159      case APIC_LVT1:         /* LVT Lint1 Reg */
   2.160      case APIC_LVTERR:       /* LVT Error Reg */
   2.161 -    {
   2.162 -        if ( vlapic->status & VLAPIC_SOFTWARE_DISABLE_MASK )
   2.163 +        if ( vlapic_sw_disabled(vlapic) )
   2.164              val |= APIC_LVT_MASKED;
   2.165 -
   2.166          val &= vlapic_lvt_mask[(offset - APIC_LVTT) >> 4];
   2.167 -
   2.168          vlapic_set_reg(vlapic, offset, val);
   2.169 -
   2.170 -        if ( (vlapic_vcpu(vlapic)->vcpu_id == 0) && (offset == APIC_LVT0) )
   2.171 -        {
   2.172 -            if ( (val & APIC_MODE_MASK) == APIC_DM_EXTINT )
   2.173 -                if ( val & APIC_LVT_MASKED)
   2.174 -                    clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.175 -                else
   2.176 -                    set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.177 -            else
   2.178 -                clear_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.179 -        }
   2.180 -    }
   2.181 -    break;
   2.182 +        break;
   2.183  
   2.184      case APIC_TMICT:
   2.185      {
   2.186 @@ -773,10 +745,8 @@ static void vlapic_write(struct vcpu *v,
   2.187  static int vlapic_range(struct vcpu *v, unsigned long addr)
   2.188  {
   2.189      struct vlapic *vlapic = vcpu_vlapic(v);
   2.190 -
   2.191 -    return (vlapic_global_enabled(vlapic) &&
   2.192 -            (addr >= vlapic->base_address) &&
   2.193 -            (addr < vlapic->base_address + PAGE_SIZE));
   2.194 +    unsigned long offset  = addr - vlapic_base_address(vlapic);
   2.195 +    return (!vlapic_hw_disabled(vlapic) && (offset < PAGE_SIZE));
   2.196  }
   2.197  
   2.198  struct hvm_mmio_handler vlapic_mmio_handler = {
   2.199 @@ -787,17 +757,23 @@ struct hvm_mmio_handler vlapic_mmio_hand
   2.200  
   2.201  void vlapic_msr_set(struct vlapic *vlapic, uint64_t value)
   2.202  {
   2.203 -    vlapic->apic_base_msr = value;
   2.204 -    vlapic->base_address  = vlapic->apic_base_msr & MSR_IA32_APICBASE_BASE;
   2.205 +    if ( (vlapic->apic_base_msr ^ value) & MSR_IA32_APICBASE_ENABLE )
   2.206 +    {
   2.207 +        if ( value & MSR_IA32_APICBASE_ENABLE )
   2.208 +        {
   2.209 +            vlapic_reset(vlapic);
   2.210 +            vlapic->disabled &= ~VLAPIC_HW_DISABLED;
   2.211 +        }
   2.212 +        else
   2.213 +        {
   2.214 +            vlapic->disabled |= VLAPIC_HW_DISABLED;
   2.215 +        }
   2.216 +    }
   2.217  
   2.218 -    if ( !(value & MSR_IA32_APICBASE_ENABLE) )
   2.219 -        set_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status );
   2.220 -    else
   2.221 -        clear_bit(_VLAPIC_GLOB_DISABLE, &vlapic->status);
   2.222 +    vlapic->apic_base_msr = value;
   2.223  
   2.224      HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
   2.225 -                "apic base msr is 0x%016"PRIx64", and base address is 0x%lx.",
   2.226 -                vlapic->apic_base_msr, vlapic->base_address);
   2.227 +                "apic base msr is 0x%016"PRIx64".", vlapic->apic_base_msr);
   2.228  }
   2.229  
   2.230  void vlapic_timer_fn(void *data)
   2.231 @@ -845,8 +821,15 @@ void vlapic_timer_fn(void *data)
   2.232  int vlapic_accept_pic_intr(struct vcpu *v)
   2.233  {
   2.234      struct vlapic *vlapic = vcpu_vlapic(v);
   2.235 +    uint32_t lvt0 = vlapic_get_reg(vlapic, APIC_LVT0);
   2.236  
   2.237 -    return vlapic ? test_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status) : 1;
   2.238 +    /*
   2.239 +     * Only CPU0 is wired to the 8259A. INTA cycles occur if LINT0 is set up
   2.240 +     * accept ExtInts, or if the LAPIC is disabled (so LINT0 behaves as INTR).
   2.241 +     */
   2.242 +    return ((v->vcpu_id == 0) &&
   2.243 +            (((lvt0 & (APIC_MODE_MASK|APIC_LVT_MASKED)) == APIC_DM_EXTINT) ||
   2.244 +             vlapic_hw_disabled(vlapic)));
   2.245  }
   2.246  
   2.247  int cpu_get_apic_interrupt(struct vcpu *v, int *mode)
   2.248 @@ -854,7 +837,7 @@ int cpu_get_apic_interrupt(struct vcpu *
   2.249      struct vlapic *vlapic = vcpu_vlapic(v);
   2.250      int highest_irr;
   2.251  
   2.252 -    if ( !vlapic || !vlapic_enabled(vlapic) )
   2.253 +    if ( !vlapic_enabled(vlapic) )
   2.254          return -1;
   2.255  
   2.256      highest_irr = vlapic_find_highest_irr(vlapic);
   2.257 @@ -887,9 +870,6 @@ void vlapic_post_injection(struct vcpu *
   2.258  {
   2.259      struct vlapic *vlapic = vcpu_vlapic(v);
   2.260  
   2.261 -    if ( unlikely(vlapic == NULL) )
   2.262 -        return;
   2.263 -
   2.264      switch ( deliver_mode )
   2.265      {
   2.266      case APIC_DM_FIXED:
   2.267 @@ -920,36 +900,38 @@ void vlapic_post_injection(struct vcpu *
   2.268      }
   2.269  }
   2.270  
   2.271 +/* Reset the VLPAIC back to its power-on/reset state. */
   2.272  static int vlapic_reset(struct vlapic *vlapic)
   2.273  {
   2.274      struct vcpu *v = vlapic_vcpu(vlapic);
   2.275      int i;
   2.276  
   2.277 -    vlapic_set_reg(vlapic, APIC_ID, v->vcpu_id << 24);
   2.278 +    vlapic_set_reg(vlapic, APIC_ID,  v->vcpu_id << 24);
   2.279 +    vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION);
   2.280  
   2.281 -    vlapic_set_reg(vlapic, APIC_LVR, VLAPIC_VERSION);
   2.282 +    for ( i = 0; i < 8; i++ )
   2.283 +    {
   2.284 +        vlapic_set_reg(vlapic, APIC_IRR + 0x10 * i, 0);
   2.285 +        vlapic_set_reg(vlapic, APIC_ISR + 0x10 * i, 0);
   2.286 +        vlapic_set_reg(vlapic, APIC_TMR + 0x10 * i, 0);
   2.287 +    }
   2.288 +    vlapic_set_reg(vlapic, APIC_ICR,     0);
   2.289 +    vlapic_set_reg(vlapic, APIC_ICR2,    0);
   2.290 +    vlapic_set_reg(vlapic, APIC_LDR,     0);
   2.291 +    vlapic_set_reg(vlapic, APIC_TASKPRI, 0);
   2.292 +    vlapic_set_reg(vlapic, APIC_TMICT,   0);
   2.293 +    vlapic_set_reg(vlapic, APIC_TMCCT,   0);
   2.294 +    vlapic_set_tdcr(vlapic, 0);
   2.295 +
   2.296 +    vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU);
   2.297  
   2.298      for ( i = 0; i < VLAPIC_LVT_NUM; i++ )
   2.299          vlapic_set_reg(vlapic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
   2.300  
   2.301 -    vlapic_set_reg(vlapic, APIC_DFR, 0xffffffffU);
   2.302 -
   2.303      vlapic_set_reg(vlapic, APIC_SPIV, 0xff);
   2.304 -
   2.305 -    vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
   2.306 -
   2.307 -    vlapic->flush_tpr_threshold = 0;
   2.308 +    vlapic->disabled |= VLAPIC_SW_DISABLED;
   2.309  
   2.310 -    vlapic_set_tdcr(vlapic, 0);
   2.311 -
   2.312 -    vlapic->base_address = vlapic->apic_base_msr &
   2.313 -                           MSR_IA32_APICBASE_BASE;
   2.314 -
   2.315 -    HVM_DBG_LOG(DBG_LEVEL_VLAPIC,
   2.316 -                "vcpu=%p, id=%d, vlapic_apic_base_msr=0x%016"PRIx64", "
   2.317 -                "base_address=0x%0lx.",
   2.318 -                v,  GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)),
   2.319 -                vlapic->apic_base_msr, vlapic->base_address);
   2.320 +    vlapic->flush_tpr_threshold = 1;
   2.321  
   2.322      return 1;
   2.323  }
   2.324 @@ -974,6 +956,7 @@ int vlapic_init(struct vcpu *v)
   2.325  
   2.326      vlapic_reset(vlapic);
   2.327  
   2.328 +    vlapic->apic_base_msr = MSR_IA32_APICBASE_ENABLE | APIC_DEFAULT_PHYS_BASE;
   2.329      if ( v->vcpu_id == 0 )
   2.330          vlapic->apic_base_msr |= MSR_IA32_APICBASE_BSP;
   2.331  
   2.332 @@ -986,7 +969,6 @@ int vlapic_init(struct vcpu *v)
   2.333      {
   2.334          vlapic_set_reg(vlapic, APIC_LVT0, APIC_MODE_EXTINT << 8);
   2.335          vlapic_set_reg(vlapic, APIC_LVT1, APIC_MODE_NMI << 8);
   2.336 -        set_bit(_VLAPIC_BSP_ACCEPT_PIC, &vlapic->status);
   2.337      }
   2.338  #endif
   2.339  
     3.1 --- a/xen/arch/x86/hvm/vmx/io.c	Mon Nov 13 17:23:49 2006 -0700
     3.2 +++ b/xen/arch/x86/hvm/vmx/io.c	Tue Nov 14 10:44:16 2006 +0000
     3.3 @@ -69,20 +69,21 @@ static inline int is_interruptibility_st
     3.4  #ifdef __x86_64__
     3.5  static void update_tpr_threshold(struct vlapic *vlapic)
     3.6  {
     3.7 -    int highest_irr, tpr;
     3.8 +    int max_irr, tpr;
     3.9  
    3.10      /* Clear the work-to-do flag /then/ do the work. */
    3.11      vlapic->flush_tpr_threshold = 0;
    3.12      mb();
    3.13  
    3.14 -    highest_irr = vlapic_find_highest_irr(vlapic);
    3.15 -    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
    3.16 +    if ( !vlapic_enabled(vlapic) || 
    3.17 +         ((max_irr = vlapic_find_highest_irr(vlapic)) == -1) )
    3.18 +    {
    3.19 +        __vmwrite(TPR_THRESHOLD, 0);
    3.20 +        return;
    3.21 +    }
    3.22  
    3.23 -    if ( highest_irr == -1 )
    3.24 -        __vmwrite(TPR_THRESHOLD, 0);
    3.25 -    else
    3.26 -        __vmwrite(TPR_THRESHOLD,
    3.27 -                  (highest_irr > tpr) ? (tpr >> 4) : (highest_irr >> 4));
    3.28 +    tpr = vlapic_get_reg(vlapic, APIC_TASKPRI) & 0xF0;
    3.29 +    __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
    3.30  }
    3.31  #else
    3.32  #define update_tpr_threshold(v) ((void)0)
    3.33 @@ -115,7 +116,7 @@ asmlinkage void vmx_intr_assist(void)
    3.34              pic_set_xen_irq(pic, callback_irq, local_events_need_delivery());
    3.35      }
    3.36  
    3.37 -    if ( vlapic_enabled(vlapic) && vlapic->flush_tpr_threshold )
    3.38 +    if ( vlapic->flush_tpr_threshold )
    3.39          update_tpr_threshold(vlapic);
    3.40  
    3.41      has_ext_irq = cpu_has_pending_irq(v);
     4.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Mon Nov 13 17:23:49 2006 -0700
     4.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Tue Nov 14 10:44:16 2006 +0000
     4.3 @@ -853,7 +853,7 @@ static void vmx_do_cpuid(struct cpu_user
     4.4              /* Mask off reserved bits. */
     4.5              ecx &= ~VMX_VCPU_CPUID_L1_ECX_RESERVED;
     4.6  
     4.7 -            if ( !vlapic_global_enabled(vcpu_vlapic(v)) )
     4.8 +            if ( vlapic_hw_disabled(vcpu_vlapic(v)) )
     4.9                  clear_bit(X86_FEATURE_APIC, &edx);
    4.10      
    4.11  #if CONFIG_PAGING_LEVELS >= 3
     5.1 --- a/xen/include/asm-x86/hvm/vlapic.h	Mon Nov 13 17:23:49 2006 -0700
     5.2 +++ b/xen/include/asm-x86/hvm/vlapic.h	Tue Nov 14 10:44:16 2006 +0000
     5.3 @@ -33,22 +33,23 @@
     5.4  #define VLAPIC_ID(vlapic)   \
     5.5      (GET_APIC_ID(vlapic_get_reg(vlapic, APIC_ID)))
     5.6  
     5.7 -#define _VLAPIC_GLOB_DISABLE            0x0
     5.8 -#define VLAPIC_GLOB_DISABLE_MASK        0x1
     5.9 -#define VLAPIC_SOFTWARE_DISABLE_MASK    0x2
    5.10 -#define _VLAPIC_BSP_ACCEPT_PIC          0x3
    5.11 -
    5.12 -#define vlapic_enabled(vlapic)              \
    5.13 -    (!((vlapic)->status &                   \
    5.14 -       (VLAPIC_GLOB_DISABLE_MASK | VLAPIC_SOFTWARE_DISABLE_MASK)))
    5.15 -
    5.16 -#define vlapic_global_enabled(vlapic)       \
    5.17 -    (!(test_bit(_VLAPIC_GLOB_DISABLE, &(vlapic)->status)))
    5.18 +/*
    5.19 + * APIC can be disabled in two ways:
    5.20 + *  1. 'Hardware disable': via IA32_APIC_BASE_MSR[11]
    5.21 + *     CPU should behave as if it does not have an APIC.
    5.22 + *  2. 'Software disable': via APIC_SPIV[8].
    5.23 + *     APIC is visible but does not respond to interrupt messages.
    5.24 + */
    5.25 +#define VLAPIC_HW_DISABLED              0x1
    5.26 +#define VLAPIC_SW_DISABLED              0x2
    5.27 +#define vlapic_sw_disabled(vlapic)  ((vlapic)->disabled & VLAPIC_SW_DISABLED)
    5.28 +#define vlapic_hw_disabled(vlapic)  ((vlapic)->disabled & VLAPIC_HW_DISABLED)
    5.29 +#define vlapic_disabled(vlapic)     ((vlapic)->disabled)
    5.30 +#define vlapic_enabled(vlapic)      (!vlapic_disabled(vlapic))
    5.31  
    5.32  struct vlapic {
    5.33 -    uint32_t           status;
    5.34      uint64_t           apic_base_msr;
    5.35 -    unsigned long      base_address;
    5.36 +    uint32_t           disabled; /* VLAPIC_xx_DISABLED */
    5.37      uint32_t           timer_divisor;
    5.38      struct timer       vlapic_timer;
    5.39      int                timer_pending_count;