ia64/xen-unstable

changeset 7765:c405c0d1b49b

This patch fix some issue on masked interrupt:
1) check the mask setting on vmx_vioapic_do_irqs and
ioapic_get_highest_irq
2) Place mask info to a seperated data structure, and access it
atomically

Signed-off-by: Yunhong Jiang <yunhong.jiang@intel.com>
author kaf24@firebug.cl.cam.ac.uk
date Thu Nov 10 12:12:00 2005 +0100 (2005-11-10)
parents bee09e2200ab
children d916497135ac
files xen/arch/x86/dm/vmx_vioapic.c xen/include/asm-x86/vmx_vioapic.h
line diff
     1.1 --- a/xen/arch/x86/dm/vmx_vioapic.c	Thu Nov 10 12:11:39 2005 +0100
     1.2 +++ b/xen/arch/x86/dm/vmx_vioapic.c	Thu Nov 10 12:12:00 2005 +0100
     1.3 @@ -158,6 +158,14 @@ static unsigned long vmx_vioapic_read(st
     1.4      return result;
     1.5  }
     1.6  
     1.7 +static void vmx_vioapic_update_imr(struct vmx_vioapic *s, int index)
     1.8 +{
     1.9 +   if (s->redirtbl[index].RedirForm.mask)
    1.10 +       set_bit(index, &s->imr);
    1.11 +   else
    1.12 +       clear_bit(index, &s->imr);
    1.13 +}
    1.14 +
    1.15  static void vmx_vioapic_write_indirect(struct vmx_vioapic *s,
    1.16                                        unsigned long addr,
    1.17                                        unsigned long length,
    1.18 @@ -200,6 +208,7 @@ static void vmx_vioapic_write_indirect(s
    1.19                      redir_content = ((redir_content >> 32) << 32) |
    1.20                                      (val & 0xffffffff);
    1.21                  s->redirtbl[redir_index].value = redir_content;
    1.22 +                vmx_vioapic_update_imr(s, redir_index);
    1.23              } else  {
    1.24                  printk("vmx_vioapic_write_indirect "
    1.25                    "error register %x\n", s->ioregsel);
    1.26 @@ -264,8 +273,10 @@ static void vmx_vioapic_reset(vmx_vioapi
    1.27  
    1.28      memset(s, 0, sizeof(vmx_vioapic_t));
    1.29  
    1.30 -    for (i = 0; i < IOAPIC_NUM_PINS; i++)
    1.31 +    for (i = 0; i < IOAPIC_NUM_PINS; i++) {
    1.32          s->redirtbl[i].RedirForm.mask = 0x1;
    1.33 +        vmx_vioapic_update_imr(s, i);
    1.34 +    }
    1.35  }
    1.36  
    1.37  static void ioapic_update_config(vmx_vioapic_t *s,
    1.38 @@ -422,7 +433,13 @@ static void ioapic_deliver(vmx_vioapic_t
    1.39  
    1.40          target = apic_round_robin(
    1.41                  s->domain, dest_mode, vector, deliver_bitmask);
    1.42 -        ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
    1.43 +        if (target)
    1.44 +            ioapic_inj_irq(s, target, vector, trig_mode, delivery_mode);
    1.45 +        else{
    1.46 +            VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "ioapic deliver "
    1.47 +              "null round robin mask %x vector %x delivery_mode %x\n",
    1.48 +              deliver_bitmask, vector, deliver_bitmask);
    1.49 +        }
    1.50          break;
    1.51      }
    1.52  
    1.53 @@ -457,7 +474,7 @@ static int ioapic_get_highest_irq(vmx_vi
    1.54  
    1.55      ASSERT(s);
    1.56  
    1.57 -    irqs = s->irr & ~s->isr;
    1.58 +    irqs = s->irr & ~s->isr & ~s->imr;
    1.59      return __fls(irqs);
    1.60  }
    1.61  
    1.62 @@ -471,7 +488,7 @@ static void service_ioapic(vmx_vioapic_t
    1.63          VMX_DBG_LOG(DBG_LEVEL_IOAPIC, "service_ioapic "
    1.64            "highest irqno %x\n", irqno);
    1.65  
    1.66 -        if (!s->redirtbl[irqno].RedirForm.mask) {
    1.67 +        if (!test_bit(irqno, &s->imr)) {
    1.68              ioapic_deliver(s, irqno);
    1.69          }
    1.70  
    1.71 @@ -490,7 +507,7 @@ void vmx_vioapic_do_irqs(struct domain *
    1.72      if (!vmx_apic_support(d))
    1.73          return;
    1.74  
    1.75 -    s->irr |= irqs;
    1.76 +    s->irr |= irqs & ~s->imr;
    1.77      service_ioapic(s);
    1.78  }
    1.79  
    1.80 @@ -584,7 +601,9 @@ int vmx_vioapic_add_lapic(struct vlapic 
    1.81          domain_crash_synchronous();
    1.82      }
    1.83  
    1.84 -    s->lapic_info[s->lapic_count ++] = vlapic;
    1.85 +    /* update count later for race condition on interrupt */
    1.86 +    s->lapic_info[s->lapic_count] = vlapic;
    1.87 +    s->lapic_count ++;
    1.88  
    1.89      return s->lapic_count;
    1.90  }
     2.1 --- a/xen/include/asm-x86/vmx_vioapic.h	Thu Nov 10 12:11:39 2005 +0100
     2.2 +++ b/xen/include/asm-x86/vmx_vioapic.h	Thu Nov 10 12:12:00 2005 +0100
     2.3 @@ -92,9 +92,10 @@ typedef union RedirStatus
     2.4  #define MAX_LAPIC_NUM        32
     2.5  
     2.6  typedef struct vmx_vioapic {
     2.7 -    uint32_t ioregsel;
     2.8      uint32_t irr;
     2.9      uint32_t isr;           /* This is used for level trigger */
    2.10 +    uint32_t imr;
    2.11 +    uint32_t ioregsel;
    2.12      uint32_t flags;
    2.13      uint32_t lapic_count;
    2.14      uint32_t id;