[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] x86: Change Xen hypervisor's interrupt infrastructure



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1250682784 -3600
# Node ID 722c7e94e76421452c035b3e9a46f805a2815445
# Parent  1afd9142eed3f112c76d73818fed717837191caa
x86:  Change Xen hypervisor's interrupt infrastructure
from vector-based to IRQ-based.

In per-cpu vector environment, vector space changes to
multi-demension resource, so vector number is not appropriate
to index irq_desc which stands for unique interrupt source. As
Linux does, irq number is chosen to index irq_desc. This patch
changes vector-based interrupt infrastructure to irq-based one.
Mostly, it follows upstream linux's changes, and some parts are
adapted for Xen.

Signed-off-by: Xiantao Zhang <xiantao.zhang@xxxxxxxxx>
---
 xen/arch/x86/domain.c                          |   20 
 xen/arch/x86/hpet.c                            |  120 ++---
 xen/arch/x86/hvm/vmsi.c                        |    4 
 xen/arch/x86/i8259.c                           |   79 +--
 xen/arch/x86/io_apic.c                         |  218 +++------
 xen/arch/x86/irq.c                             |  573 +++++++++++++++----------
 xen/arch/x86/msi.c                             |  154 +++---
 xen/arch/x86/physdev.c                         |   44 -
 xen/arch/x86/setup.c                           |    2 
 xen/drivers/passthrough/amd/iommu_init.c       |   66 +-
 xen/drivers/passthrough/io.c                   |   53 +-
 xen/drivers/passthrough/pci.c                  |    4 
 xen/drivers/passthrough/vtd/iommu.c            |   95 ++--
 xen/drivers/passthrough/vtd/x86/vtd.c          |    2 
 xen/include/asm-x86/amd-iommu.h                |    2 
 xen/include/asm-x86/domain.h                   |    6 
 xen/include/asm-x86/irq.h                      |   30 -
 xen/include/asm-x86/mach-default/irq_vectors.h |    1 
 xen/include/asm-x86/msi.h                      |   14 
 xen/include/xen/hvm/irq.h                      |    2 
 xen/include/xen/iommu.h                        |    2 
 xen/include/xen/irq.h                          |   31 -
 22 files changed, 832 insertions(+), 690 deletions(-)

diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/domain.c     Wed Aug 19 12:53:04 2009 +0100
@@ -474,11 +474,17 @@ int arch_domain_create(struct domain *d,
         share_xen_page_with_guest(
             virt_to_page(d->shared_info), d, XENSHARE_writable);
 
-        d->arch.pirq_vector = xmalloc_array(s16, d->nr_pirqs);
-        if ( !d->arch.pirq_vector )
+        d->arch.pirq_irq = xmalloc_array(int, d->nr_pirqs);
+        if ( !d->arch.pirq_irq )
             goto fail;
-        memset(d->arch.pirq_vector, 0,
-               d->nr_pirqs * sizeof(*d->arch.pirq_vector));
+        memset(d->arch.pirq_irq, 0,
+               d->nr_pirqs * sizeof(*d->arch.pirq_irq));
+
+        d->arch.irq_pirq = xmalloc_array(int, nr_irqs);
+        if ( !d->arch.irq_pirq )
+            goto fail;
+        memset(d->arch.irq_pirq, 0,
+               nr_irqs * sizeof(*d->arch.irq_pirq));
 
         if ( (rc = iommu_domain_init(d)) != 0 )
             goto fail;
@@ -513,7 +519,8 @@ int arch_domain_create(struct domain *d,
 
  fail:
     d->is_dying = DOMDYING_dead;
-    xfree(d->arch.pirq_vector);
+    xfree(d->arch.pirq_irq);
+    xfree(d->arch.irq_pirq);
     free_xenheap_page(d->shared_info);
     if ( paging_initialised )
         paging_final_teardown(d);
@@ -562,7 +569,8 @@ void arch_domain_destroy(struct domain *
 #endif
 
     free_xenheap_page(d->shared_info);
-    xfree(d->arch.pirq_vector);
+    xfree(d->arch.pirq_irq);
+    xfree(d->arch.irq_pirq);
 }
 
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4)
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/hpet.c
--- a/xen/arch/x86/hpet.c       Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/hpet.c       Wed Aug 19 12:53:04 2009 +0100
@@ -38,7 +38,7 @@ struct hpet_event_channel
 
     unsigned int idx;   /* physical channel idx */
     int cpu;            /* msi target */
-    unsigned int vector;/* msi vector */
+    unsigned int irq;/* msi irq */
     unsigned int flags; /* HPET_EVT_x */
 } __cacheline_aligned;
 static struct hpet_event_channel legacy_hpet_event;
@@ -47,13 +47,13 @@ static unsigned int num_hpets_used; /* m
 
 DEFINE_PER_CPU(struct hpet_event_channel *, cpu_bc_channel);
 
-static int vector_channel[NR_VECTORS] = {[0 ... NR_VECTORS-1] = -1};
-
-#define vector_to_channel(vector)   vector_channel[vector]
+static int *irq_channel;
+
+#define irq_to_channel(irq)   irq_channel[irq]
 
 unsigned long hpet_address;
 
-void msi_compose_msg(struct pci_dev *pdev, int vector, struct msi_msg *msg);
+void msi_compose_msg(struct pci_dev *pdev, int irq, struct msi_msg *msg);
 
 /*
  * force_hpet_broadcast: by default legacy hpet broadcast will be stopped
@@ -208,7 +208,7 @@ again:
     spin_unlock_irq(&ch->lock);
 }
 
-static void hpet_interrupt_handler(int vector, void *data,
+static void hpet_interrupt_handler(int irq, void *data,
         struct cpu_user_regs *regs)
 {
     struct hpet_event_channel *ch = (struct hpet_event_channel *)data;
@@ -221,10 +221,10 @@ static void hpet_interrupt_handler(int v
     ch->event_handler(ch);
 }
 
-static void hpet_msi_unmask(unsigned int vector)
+static void hpet_msi_unmask(unsigned int irq)
 {
     unsigned long cfg;
-    int ch_idx = vector_to_channel(vector);
+    int ch_idx = irq_to_channel(irq);
     struct hpet_event_channel *ch;
 
     BUG_ON(ch_idx < 0);
@@ -235,10 +235,10 @@ static void hpet_msi_unmask(unsigned int
     hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
 }
 
-static void hpet_msi_mask(unsigned int vector)
+static void hpet_msi_mask(unsigned int irq)
 {
     unsigned long cfg;
-    int ch_idx = vector_to_channel(vector);
+    int ch_idx = irq_to_channel(irq);
     struct hpet_event_channel *ch;
 
     BUG_ON(ch_idx < 0);
@@ -249,9 +249,9 @@ static void hpet_msi_mask(unsigned int v
     hpet_write32(cfg, HPET_Tn_CFG(ch->idx));
 }
 
-static void hpet_msi_write(unsigned int vector, struct msi_msg *msg)
-{
-    int ch_idx = vector_to_channel(vector);
+static void hpet_msi_write(unsigned int irq, struct msi_msg *msg)
+{
+    int ch_idx = irq_to_channel(irq);
     struct hpet_event_channel *ch;
 
     BUG_ON(ch_idx < 0);
@@ -261,9 +261,9 @@ static void hpet_msi_write(unsigned int 
     hpet_write32(msg->address_lo, HPET_Tn_ROUTE(ch->idx) + 4);
 }
 
-static void hpet_msi_read(unsigned int vector, struct msi_msg *msg)
-{
-    int ch_idx = vector_to_channel(vector);
+static void hpet_msi_read(unsigned int irq, struct msi_msg *msg)
+{
+    int ch_idx = irq_to_channel(irq);
     struct hpet_event_channel *ch;
 
     BUG_ON(ch_idx < 0);
@@ -274,31 +274,32 @@ static void hpet_msi_read(unsigned int v
     msg->address_hi = 0;
 }
 
-static unsigned int hpet_msi_startup(unsigned int vector)
-{
-    hpet_msi_unmask(vector);
+static unsigned int hpet_msi_startup(unsigned int irq)
+{
+    hpet_msi_unmask(irq);
     return 0;
 }
 
-static void hpet_msi_shutdown(unsigned int vector)
-{
-    hpet_msi_mask(vector);
-}
-
-static void hpet_msi_ack(unsigned int vector)
+static void hpet_msi_shutdown(unsigned int irq)
+{
+    hpet_msi_mask(irq);
+}
+
+static void hpet_msi_ack(unsigned int irq)
 {
     ack_APIC_irq();
 }
 
-static void hpet_msi_end(unsigned int vector)
-{
-}
-
-static void hpet_msi_set_affinity(unsigned int vector, cpumask_t mask)
+static void hpet_msi_end(unsigned int irq)
+{
+}
+
+static void hpet_msi_set_affinity(unsigned int irq, cpumask_t mask)
 {
     struct msi_msg msg;
     unsigned int dest;
     cpumask_t tmp;
+    int vector = irq_to_vector(irq);
 
     cpus_and(tmp, mask, cpu_online_map);
     if ( cpus_empty(tmp) )
@@ -314,7 +315,7 @@ static void hpet_msi_set_affinity(unsign
     msg.address_lo |= MSI_ADDR_DEST_ID(dest);
 
     hpet_msi_write(vector, &msg);
-    irq_desc[vector].affinity = mask;
+    irq_desc[irq].affinity = mask;
 }
 
 /*
@@ -331,44 +332,44 @@ static struct hw_interrupt_type hpet_msi
     .set_affinity   = hpet_msi_set_affinity,
 };
 
-static int hpet_setup_msi_irq(unsigned int vector)
+static int hpet_setup_msi_irq(unsigned int irq)
 {
     int ret;
     struct msi_msg msg;
-    struct hpet_event_channel *ch = &hpet_events[vector_to_channel(vector)];
-
-    irq_desc[vector].handler = &hpet_msi_type;
-    ret = request_irq_vector(vector, hpet_interrupt_handler,
+    struct hpet_event_channel *ch = &hpet_events[irq_to_channel(irq)];
+
+    irq_desc[irq].handler = &hpet_msi_type;
+    ret = request_irq(irq, hpet_interrupt_handler,
                       0, "HPET", ch);
     if ( ret < 0 )
         return ret;
 
-    msi_compose_msg(NULL, vector, &msg);
-    hpet_msi_write(vector, &msg);
+    msi_compose_msg(NULL, irq, &msg);
+    hpet_msi_write(irq, &msg);
 
     return 0;
 }
 
 static int hpet_assign_irq(struct hpet_event_channel *ch)
 {
-    int vector;
-
-    if ( ch->vector )
+    int irq;
+
+    if ( ch->irq )
         return 0;
 
-    if ( (vector = assign_irq_vector(AUTO_ASSIGN_IRQ)) < 0 )
-        return vector;
-
-    vector_channel[vector] = ch - &hpet_events[0];
-
-    if ( hpet_setup_msi_irq(vector) )
-    {
-        free_irq_vector(vector);
-        vector_channel[vector] = -1;
+    if ( (irq = create_irq()) < 0 )
+        return irq;
+
+    irq_channel[irq] = ch - &hpet_events[0];
+
+    if ( hpet_setup_msi_irq(irq) )
+    {
+        destroy_irq(irq);
+        irq_channel[irq] = -1;
         return -EINVAL;
     }
 
-    ch->vector = vector;
+    ch->irq = irq;
     return 0;
 }
 
@@ -402,8 +403,8 @@ static int hpet_fsb_cap_lookup(void)
         /* set default irq affinity */
         ch->cpu = num_chs_used;
         per_cpu(cpu_bc_channel, ch->cpu) = ch;
-        irq_desc[ch->vector].handler->
-            set_affinity(ch->vector, cpumask_of_cpu(ch->cpu));
+        irq_desc[ch->irq].handler->
+            set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
 
         num_chs_used++;
 
@@ -462,8 +463,8 @@ static void hpet_attach_channel_share(in
         return;
 
     /* set irq affinity */
-    irq_desc[ch->vector].handler->
-        set_affinity(ch->vector, cpumask_of_cpu(ch->cpu));
+    irq_desc[ch->irq].handler->
+        set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
 }
 
 static void hpet_detach_channel_share(int cpu)
@@ -484,8 +485,8 @@ static void hpet_detach_channel_share(in
 
     ch->cpu = first_cpu(ch->cpumask);
     /* set irq affinity */
-    irq_desc[ch->vector].handler->
-        set_affinity(ch->vector, cpumask_of_cpu(ch->cpu));
+    irq_desc[ch->irq].handler->
+        set_affinity(ch->irq, cpumask_of_cpu(ch->cpu));
 }
 
 static void (*hpet_attach_channel)(int cpu, struct hpet_event_channel *ch);
@@ -522,6 +523,11 @@ void hpet_broadcast_init(void)
     u64 hpet_rate;
     u32 hpet_id, cfg;
     int i;
+
+    irq_channel= xmalloc_array(int, nr_irqs);
+    BUG_ON(!irq_channel);
+    for (i = 0; i < nr_irqs ; i++)
+        irq_channel[i] = -1;
 
     hpet_rate = hpet_setup();
     if ( hpet_rate == 0 )
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/hvm/vmsi.c
--- a/xen/arch/x86/hvm/vmsi.c   Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/hvm/vmsi.c   Wed Aug 19 12:53:04 2009 +0100
@@ -374,7 +374,7 @@ static void del_msixtbl_entry(struct msi
 
 int msixtbl_pt_register(struct domain *d, int pirq, uint64_t gtable)
 {
-    irq_desc_t *irq_desc;
+    struct irq_desc *irq_desc;
     struct msi_desc *msi_desc;
     struct pci_dev *pdev;
     struct msixtbl_entry *entry, *new_entry;
@@ -429,7 +429,7 @@ out:
 
 void msixtbl_pt_unregister(struct domain *d, int pirq)
 {
-    irq_desc_t *irq_desc;
+    struct irq_desc *irq_desc;
     struct msi_desc *msi_desc;
     struct pci_dev *pdev;
     struct msixtbl_entry *entry;
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/i8259.c      Wed Aug 19 12:53:04 2009 +0100
@@ -106,38 +106,28 @@ BUILD_SMP_INTERRUPT(cmci_interrupt, CMCI
 
 static DEFINE_SPINLOCK(i8259A_lock);
 
-static void disable_8259A_vector(unsigned int vector)
-{
-    disable_8259A_irq(LEGACY_IRQ_FROM_VECTOR(vector));
-}
-
-static void enable_8259A_vector(unsigned int vector)
-{
-    enable_8259A_irq(LEGACY_IRQ_FROM_VECTOR(vector));
-}
-
-static void mask_and_ack_8259A_vector(unsigned int);
-
-static void end_8259A_vector(unsigned int vector)
-{
-    if (!(irq_desc[vector].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
-        enable_8259A_vector(vector);
-}
-
-static unsigned int startup_8259A_vector(unsigned int vector)
-{ 
-    enable_8259A_vector(vector);
+static void mask_and_ack_8259A_irq(unsigned int irq);
+
+static unsigned int startup_8259A_irq(unsigned int irq)
+{
+    enable_8259A_irq(irq);
     return 0; /* never anything pending */
+}
+
+static void end_8259A_irq(unsigned int irq)
+{
+    if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS)))
+        enable_8259A_irq(irq);
 }
 
 static struct hw_interrupt_type i8259A_irq_type = {
     .typename = "XT-PIC",
-    .startup  = startup_8259A_vector,
-    .shutdown = disable_8259A_vector,
-    .enable   = enable_8259A_vector,
-    .disable  = disable_8259A_vector,
-    .ack      = mask_and_ack_8259A_vector,
-    .end      = end_8259A_vector
+    .startup  = startup_8259A_irq,
+    .shutdown = disable_8259A_irq,
+    .enable   = enable_8259A_irq,
+    .disable  = disable_8259A_irq,
+    .ack      = mask_and_ack_8259A_irq,
+    .end      = end_8259A_irq
 };
 
 /*
@@ -237,9 +227,8 @@ static inline int i8259A_irq_real(unsign
  * first, _then_ send the EOI, and the order of EOI
  * to the two 8259s is important!
  */
-static void mask_and_ack_8259A_vector(unsigned int vector)
-{
-    unsigned int irq = LEGACY_IRQ_FROM_VECTOR(vector);
+static void mask_and_ack_8259A_irq(unsigned int irq)
+{
     unsigned int irqmask = 1 << irq;
     unsigned long flags;
 
@@ -369,9 +358,9 @@ void __devinit init_8259A(int auto_eoi)
          * in AEOI mode we just have to mask the interrupt
          * when acking.
          */
-        i8259A_irq_type.ack = disable_8259A_vector;
-    else
-        i8259A_irq_type.ack = mask_and_ack_8259A_vector;
+        i8259A_irq_type.ack = disable_8259A_irq;
+    else
+        i8259A_irq_type.ack = mask_and_ack_8259A_irq;
 
     udelay(100);            /* wait for 8259A to initialize */
 
@@ -385,31 +374,25 @@ static struct irqaction cascade = { no_a
 
 void __init init_IRQ(void)
 {
-    int i;
+    int i, vector;
 
     init_bsp_APIC();
 
     init_8259A(0);
 
-    for ( i = 0; i < NR_VECTORS; i++ )
+    BUG_ON(init_irq_data() < 0);
+
+    for ( vector = FIRST_DYNAMIC_VECTOR; vector < NR_VECTORS; vector++ )
     {
-        irq_desc[i].status  = IRQ_DISABLED;
-        irq_desc[i].handler = &no_irq_type;
-        irq_desc[i].action  = NULL;
-        irq_desc[i].depth   = 1;
-        spin_lock_init(&irq_desc[i].lock);
-        cpus_setall(irq_desc[i].affinity);
-        if ( i >= 0x20 )
-            set_intr_gate(i, interrupt[i]);
-    }
-
-    irq_vector = xmalloc_array(u8, nr_irqs_gsi);
-    memset(irq_vector, 0, nr_irqs_gsi * sizeof(*irq_vector));
+        if (vector == HYPERCALL_VECTOR || vector == LEGACY_SYSCALL_VECTOR)
+            continue;
+        set_intr_gate(vector, interrupt[vector]);
+    }
 
     for ( i = 0; i < 16; i++ )
     {
         vector_irq[LEGACY_VECTOR(i)] = i;
-        irq_desc[LEGACY_VECTOR(i)].handler = &i8259A_irq_type;
+        irq_desc[i].handler = &i8259A_irq_type;
     }
 
     /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/io_apic.c    Wed Aug 19 12:53:04 2009 +0100
@@ -661,9 +661,6 @@ static inline int IO_APIC_irq_trigger(in
     return 0;
 }
 
-/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 *irq_vector __read_mostly = (u8 *)(1UL << (BITS_PER_LONG - 1));
-
 static struct hw_interrupt_type ioapic_level_type;
 static struct hw_interrupt_type ioapic_edge_type;
 
@@ -671,13 +668,13 @@ static struct hw_interrupt_type ioapic_e
 #define IOAPIC_EDGE    0
 #define IOAPIC_LEVEL   1
 
-static inline void ioapic_register_intr(int irq, int vector, unsigned long 
trigger)
+static inline void ioapic_register_intr(int irq, unsigned long trigger)
 {
     if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) ||
         trigger == IOAPIC_LEVEL)
-        irq_desc[vector].handler = &ioapic_level_type;
+        irq_desc[irq].handler = &ioapic_level_type;
     else
-        irq_desc[vector].handler = &ioapic_edge_type;
+        irq_desc[irq].handler = &ioapic_edge_type;
 }
 
 static void __init setup_IO_APIC_irqs(void)
@@ -740,7 +737,7 @@ static void __init setup_IO_APIC_irqs(vo
             if (IO_APIC_IRQ(irq)) {
                 vector = assign_irq_vector(irq);
                 entry.vector = vector;
-                ioapic_register_intr(irq, vector, IOAPIC_AUTO);
+                ioapic_register_intr(irq, IOAPIC_AUTO);
 
                 if (!apic && (irq < 16))
                     disable_8259A_irq(irq);
@@ -748,7 +745,7 @@ static void __init setup_IO_APIC_irqs(vo
             spin_lock_irqsave(&ioapic_lock, flags);
             io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
             io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
-            set_native_irq_info(entry.vector, TARGET_CPUS);
+            set_native_irq_info(irq, TARGET_CPUS);
             spin_unlock_irqrestore(&ioapic_lock, flags);
        }
     }
@@ -788,7 +785,7 @@ static void __init setup_ExtINT_IRQ0_pin
      * The timer IRQ doesn't have to know that behind the
      * scene we have a 8259A-master in AEOI mode ...
      */
-    irq_desc[IO_APIC_VECTOR(0)].handler = &ioapic_edge_type;
+    irq_desc[0].handler = &ioapic_edge_type;
 
     /*
      * Add it to the IO-APIC irq-routing table:
@@ -1269,7 +1266,7 @@ static unsigned int startup_edge_ioapic_
  */
 static void ack_edge_ioapic_irq(unsigned int irq)
 {
-    if ((irq_desc[IO_APIC_VECTOR(irq)].status & (IRQ_PENDING | IRQ_DISABLED))
+    if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED))
         == (IRQ_PENDING | IRQ_DISABLED))
         mask_IO_APIC_irq(irq);
     ack_APIC_irq();
@@ -1359,7 +1356,7 @@ static void end_level_ioapic_irq (unsign
 
     if ( !ioapic_ack_new )
     {
-        if ( !(irq_desc[IO_APIC_VECTOR(irq)].status & IRQ_DISABLED) )
+        if ( !(irq_desc[irq].status & IRQ_DISABLED) )
             unmask_IO_APIC_irq(irq);
         return;
     }
@@ -1395,70 +1392,19 @@ static void end_level_ioapic_irq (unsign
         __mask_IO_APIC_irq(irq);
         __edge_IO_APIC_irq(irq);
         __level_IO_APIC_irq(irq);
-        if ( !(irq_desc[IO_APIC_VECTOR(irq)].status & IRQ_DISABLED) )
+        if ( !(irq_desc[irq].status & IRQ_DISABLED) )
             __unmask_IO_APIC_irq(irq);
         spin_unlock(&ioapic_lock);
     }
 }
 
-static unsigned int startup_edge_ioapic_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    return startup_edge_ioapic_irq(irq);
-}
-
-static void ack_edge_ioapic_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    ack_edge_ioapic_irq(irq);
-}
-
-static unsigned int startup_level_ioapic_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    return startup_level_ioapic_irq (irq);
-}
-
-static void mask_and_ack_level_ioapic_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    mask_and_ack_level_ioapic_irq(irq);
-}
-
-static void end_level_ioapic_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    end_level_ioapic_irq(irq);
-}
-
-static void mask_IO_APIC_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    mask_IO_APIC_irq(irq);
-}
-
-static void unmask_IO_APIC_vector(unsigned int vector)
-{
-    int irq = vector_to_irq(vector);
-    unmask_IO_APIC_irq(irq);
-}
-
-static void set_ioapic_affinity_vector(
-    unsigned int vector, cpumask_t cpu_mask)
-{
-    int irq = vector_to_irq(vector);
-
-    set_native_irq_info(vector, cpu_mask);
-    set_ioapic_affinity_irq(irq, cpu_mask);
-}
-
-static void disable_edge_ioapic_vector(unsigned int vector)
-{
-}
-
-static void end_edge_ioapic_vector(unsigned int vector)
-{
-}
+static void disable_edge_ioapic_irq(unsigned int irq)
+{
+}
+
+static void end_edge_ioapic_irq(unsigned int irq)
+ {
+ }
 
 /*
  * Level and edge triggered IO-APIC interrupts need different handling,
@@ -1470,53 +1416,54 @@ static void end_edge_ioapic_vector(unsig
  */
 static struct hw_interrupt_type ioapic_edge_type = {
     .typename  = "IO-APIC-edge",
-    .startup   = startup_edge_ioapic_vector,
-    .shutdown  = disable_edge_ioapic_vector,
-    .enable    = unmask_IO_APIC_vector,
-    .disable   = disable_edge_ioapic_vector,
-    .ack               = ack_edge_ioapic_vector,
-    .end               = end_edge_ioapic_vector,
-    .set_affinity      = set_ioapic_affinity_vector,
+    .startup   = startup_edge_ioapic_irq,
+    .shutdown  = disable_edge_ioapic_irq,
+    .enable    = unmask_IO_APIC_irq,
+    .disable   = disable_edge_ioapic_irq,
+    .ack               = ack_edge_ioapic_irq,
+    .end               = end_edge_ioapic_irq,
+    .set_affinity      = set_ioapic_affinity_irq,
 };
 
 static struct hw_interrupt_type ioapic_level_type = {
     .typename  = "IO-APIC-level",
-    .startup   = startup_level_ioapic_vector,
-    .shutdown  = mask_IO_APIC_vector,
-    .enable    = unmask_IO_APIC_vector,
-    .disable   = mask_IO_APIC_vector,
-    .ack               = mask_and_ack_level_ioapic_vector,
-    .end               = end_level_ioapic_vector,
-    .set_affinity      = set_ioapic_affinity_vector,
+    .startup   = startup_level_ioapic_irq,
+    .shutdown  = mask_IO_APIC_irq,
+    .enable    = unmask_IO_APIC_irq,
+    .disable   = mask_IO_APIC_irq,
+    .ack               = mask_and_ack_level_ioapic_irq,
+    .end               = end_level_ioapic_irq,
+    .set_affinity      = set_ioapic_affinity_irq,
 };
 
-static unsigned int startup_msi_vector(unsigned int vector)
-{
-    unmask_msi_vector(vector);
+static unsigned int startup_msi_irq(unsigned int irq)
+{
+    unmask_msi_irq(irq);
     return 0;
 }
 
-static void ack_msi_vector(unsigned int vector)
-{
-    if ( msi_maskable_irq(irq_desc[vector].msi_desc) )
+static void ack_msi_irq(unsigned int irq)
+{
+    struct irq_desc *desc = irq_to_desc(irq);
+
+    if ( msi_maskable_irq(desc->msi_desc) )
         ack_APIC_irq(); /* ACKTYPE_NONE */
 }
 
-static void end_msi_vector(unsigned int vector)
-{
-    if ( !msi_maskable_irq(irq_desc[vector].msi_desc) )
+static void end_msi_irq(unsigned int irq)
+{
+    if ( !msi_maskable_irq(irq_desc[irq].msi_desc) )
         ack_APIC_irq(); /* ACKTYPE_EOI */
 }
 
-static void shutdown_msi_vector(unsigned int vector)
-{
-    mask_msi_vector(vector);
-}
-
-static void set_msi_affinity_vector(unsigned int vector, cpumask_t cpu_mask)
-{
-    set_native_irq_info(vector, cpu_mask);
-    set_msi_affinity(vector, cpu_mask);
+static void shutdown_msi_irq(unsigned int irq)
+{
+    mask_msi_irq(irq);
+}
+
+static void set_msi_affinity_irq(unsigned int irq, cpumask_t cpu_mask)
+{
+    set_msi_affinity(irq, cpu_mask);
 }
 
 /*
@@ -1525,13 +1472,13 @@ static void set_msi_affinity_vector(unsi
  */
 struct hw_interrupt_type pci_msi_type = {
     .typename   = "PCI-MSI",
-    .startup    = startup_msi_vector,
-    .shutdown   = shutdown_msi_vector,
-    .enable        = unmask_msi_vector,
-    .disable    = mask_msi_vector,
-    .ack        = ack_msi_vector,
-    .end        = end_msi_vector,
-    .set_affinity   = set_msi_affinity_vector,
+    .startup    = startup_msi_irq,
+    .shutdown   = shutdown_msi_irq,
+    .enable        = unmask_msi_irq,
+    .disable    = mask_msi_irq,
+    .ack        = ack_msi_irq,
+    .end        = end_msi_irq,
+    .set_affinity   = set_msi_affinity_irq,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -1543,7 +1490,7 @@ static inline void init_IO_APIC_traps(vo
             make_8259A_irq(irq);
 }
 
-static void enable_lapic_vector(unsigned int vector)
+static void enable_lapic_irq(unsigned int irq)
 {
     unsigned long v;
 
@@ -1551,7 +1498,7 @@ static void enable_lapic_vector(unsigned
     apic_write_around(APIC_LVT0, v & ~APIC_LVT_MASKED);
 }
 
-static void disable_lapic_vector(unsigned int vector)
+static void disable_lapic_irq(unsigned int irq)
 {
     unsigned long v;
 
@@ -1559,21 +1506,21 @@ static void disable_lapic_vector(unsigne
     apic_write_around(APIC_LVT0, v | APIC_LVT_MASKED);
 }
 
-static void ack_lapic_vector(unsigned int vector)
+static void ack_lapic_irq(unsigned int irq)
 {
     ack_APIC_irq();
 }
 
-static void end_lapic_vector(unsigned int vector) { /* nothing */ }
+static void end_lapic_irq(unsigned int irq) { /* nothing */ }
 
 static struct hw_interrupt_type lapic_irq_type = {
     .typename  = "local-APIC-edge",
     .startup   = NULL, /* startup_irq() not used for IRQ0 */
     .shutdown  = NULL, /* shutdown_irq() not used for IRQ0 */
-    .enable    = enable_lapic_vector,
-    .disable   = disable_lapic_vector,
-    .ack               = ack_lapic_vector,
-    .end               = end_lapic_vector
+    .enable    = enable_lapic_irq,
+    .disable   = disable_lapic_irq,
+    .ack               = ack_lapic_irq,
+    .end               = end_lapic_irq,
 };
 
 /*
@@ -1661,9 +1608,9 @@ static inline void check_timer(void)
     disable_8259A_irq(0);
     vector = assign_irq_vector(0);
 
-    irq_desc[IO_APIC_VECTOR(0)].action = irq_desc[LEGACY_VECTOR(0)].action;
-    irq_desc[IO_APIC_VECTOR(0)].depth  = 0;
-    irq_desc[IO_APIC_VECTOR(0)].status &= ~IRQ_DISABLED;
+    irq_desc[0].depth  = 0;
+    irq_desc[0].status &= ~IRQ_DISABLED;
+    irq_desc[0].handler = &ioapic_edge_type;
 
     /*
      * Subtle, code in do_timer_interrupt() expects an AEOI
@@ -1736,7 +1683,7 @@ static inline void check_timer(void)
     printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ...");
 
     disable_8259A_irq(0);
-    irq_desc[vector].handler = &lapic_irq_type;
+    irq_desc[0].handler = &lapic_irq_type;
     apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector);      /* Fixed mode */
     enable_8259A_irq(0);
 
@@ -2002,7 +1949,7 @@ int io_apic_set_pci_routing (int ioapic,
                mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
                edge_level, active_high_low);
 
-    ioapic_register_intr(irq, entry.vector, edge_level);
+    ioapic_register_intr(irq, edge_level);
 
     if (!ioapic && (irq < 16))
         disable_8259A_irq(irq);
@@ -2010,7 +1957,7 @@ int io_apic_set_pci_routing (int ioapic,
     spin_lock_irqsave(&ioapic_lock, flags);
     io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
     io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
-    set_native_irq_info(entry.vector, TARGET_CPUS);
+    set_native_irq_info(irq, TARGET_CPUS);
     spin_unlock_irqrestore(&ioapic_lock, flags);
 
     return 0;
@@ -2114,12 +2061,13 @@ int ioapic_guest_write(unsigned long phy
 
     if ( old_rte.vector >= FIRST_DYNAMIC_VECTOR )
         old_irq = vector_irq[old_rte.vector];
+
     if ( new_rte.vector >= FIRST_DYNAMIC_VECTOR )
         new_irq = vector_irq[new_rte.vector];
 
     if ( (old_irq != new_irq) && (old_irq >= 0) && IO_APIC_IRQ(old_irq) )
     {
-        if ( irq_desc[IO_APIC_VECTOR(old_irq)].action )
+        if ( irq_desc[old_irq].action )
         {
             WARN_BOGUS_WRITE("Attempt to remove IO-APIC pin of in-use IRQ!\n");
             spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -2131,7 +2079,7 @@ int ioapic_guest_write(unsigned long phy
 
     if ( (new_irq >= 0) && IO_APIC_IRQ(new_irq) )
     {
-        if ( irq_desc[IO_APIC_VECTOR(new_irq)].action )
+        if ( irq_desc[new_irq].action )
         {
             WARN_BOGUS_WRITE("Attempt to %s IO-APIC pin for in-use IRQ!\n",
                              (old_irq != new_irq) ? "add" : "modify");
@@ -2140,7 +2088,7 @@ int ioapic_guest_write(unsigned long phy
         }
         
         /* Set the correct irq-handling type. */
-        irq_desc[IO_APIC_VECTOR(new_irq)].handler = new_rte.trigger ? 
+        irq_desc[new_irq].handler = new_rte.trigger ? 
             &ioapic_level_type: &ioapic_edge_type;
         
         if ( old_irq != new_irq )
@@ -2252,11 +2200,17 @@ void __init init_ioapic_mappings(void)
     }
     if ( !smp_found_config || skip_ioapic_setup || nr_irqs_gsi < 16 )
         nr_irqs_gsi = 16;
-    else if ( nr_irqs_gsi > PAGE_SIZE * 8 )
+    else if ( nr_irqs_gsi > MAX_GSI_IRQS)
     {
         /* for PHYSDEVOP_pirq_eoi_gmfn guest assumptions */
-        printk(KERN_WARNING "Limiting number of IRQs found (%u) to %lu\n",
-               nr_irqs_gsi, PAGE_SIZE * 8);
-        nr_irqs_gsi = PAGE_SIZE * 8;
-    }
-}
+        printk(KERN_WARNING "Limiting number of GSI IRQs found (%u) to %lu\n",
+               nr_irqs_gsi, MAX_GSI_IRQS);
+        nr_irqs_gsi = MAX_GSI_IRQS;
+    }
+
+    if (nr_irqs < 2 * nr_irqs_gsi)
+        nr_irqs = 2 * nr_irqs_gsi;
+
+    if (nr_irqs > MAX_NR_IRQS)
+        nr_irqs = MAX_NR_IRQS;
+}
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/irq.c        Wed Aug 19 12:53:04 2009 +0100
@@ -27,13 +27,162 @@ boolean_param("noirqbalance", opt_noirqb
 boolean_param("noirqbalance", opt_noirqbalance);
 
 unsigned int __read_mostly nr_irqs_gsi = 16;
-irq_desc_t irq_desc[NR_VECTORS];
+unsigned int __read_mostly nr_irqs = 1024;
+integer_param("nr_irqs", nr_irqs);
+
+u8 __read_mostly *irq_vector;
+struct irq_desc __read_mostly *irq_desc = NULL;
+
+int __read_mostly *irq_status = NULL;
+#define IRQ_UNUSED      (0)
+#define IRQ_USED        (1)
+#define IRQ_RSVD        (2)
+
+static struct timer *irq_guest_eoi_timer;
 
 static DEFINE_SPINLOCK(vector_lock);
 int vector_irq[NR_VECTORS] __read_mostly = {
     [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN_IRQ
 };
 
+static inline int find_unassigned_irq(void)
+{
+    int irq;
+
+    for (irq = nr_irqs_gsi; irq < nr_irqs; irq++)
+        if (irq_status[irq] == IRQ_UNUSED)
+            return irq;
+    return -ENOSPC;
+}
+
+/*
+ * Dynamic irq allocate and deallocation for MSI
+ */
+int create_irq(void)
+{
+    unsigned long flags;
+    int irq, ret;
+    irq = -ENOSPC;
+
+    spin_lock_irqsave(&vector_lock, flags);
+
+    irq = find_unassigned_irq();
+    if (irq < 0)
+         goto out;
+    ret = __assign_irq_vector(irq);
+    if (ret < 0)
+        irq = ret;
+out:
+     spin_unlock_irqrestore(&vector_lock, flags);
+
+    return irq;
+}
+
+void dynamic_irq_cleanup(unsigned int irq)
+{
+    struct irq_desc *desc = irq_to_desc(irq);
+    struct irqaction *action;
+    unsigned long flags;
+
+    spin_lock_irqsave(&desc->lock, flags);
+    desc->status  |= IRQ_DISABLED;
+    desc->handler->shutdown(irq);
+    action = desc->action;
+    desc->action  = NULL;
+    desc->depth   = 1;
+    desc->msi_desc = NULL;
+    desc->handler = &no_irq_type;
+    cpus_setall(desc->affinity);
+    spin_unlock_irqrestore(&desc->lock, flags);
+
+    /* Wait to make sure it's not being used on another CPU */
+    do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS );
+
+    if (action)
+        xfree(action);
+}
+
+static void __clear_irq_vector(int irq)
+{
+    int vector = irq_vector[irq];
+    vector_irq[vector] = FREE_TO_ASSIGN_IRQ;
+    irq_vector[irq] = 0;
+    irq_status[irq] = IRQ_UNUSED;
+}
+
+void clear_irq_vector(int irq)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&vector_lock, flags);
+    __clear_irq_vector(irq);
+    spin_unlock_irqrestore(&vector_lock, flags);
+}
+
+void destroy_irq(unsigned int irq)
+{
+    dynamic_irq_cleanup(irq);
+    clear_irq_vector(irq);
+}
+
+int irq_to_vector(int irq)
+{
+    int vector = -1;
+
+    BUG_ON(irq >= nr_irqs || irq < 0);
+
+    if (IO_APIC_IRQ(irq) || MSI_IRQ(irq))
+        vector = irq_vector[irq];
+    else
+        vector = LEGACY_VECTOR(irq);
+
+    return vector;
+}
+
+static void init_one_irq_desc(struct irq_desc *desc)
+{
+        desc->status  = IRQ_DISABLED;
+        desc->handler = &no_irq_type;
+        desc->action  = NULL;
+        desc->depth   = 1;
+        desc->msi_desc = NULL;
+        spin_lock_init(&desc->lock);
+        cpus_setall(desc->affinity);
+}
+
+static void init_one_irq_status(int irq)
+{
+    irq_status[irq] = IRQ_UNUSED;
+}
+
+int init_irq_data(void)
+{
+    struct irq_desc *desc;
+    int irq;
+
+    irq_desc = xmalloc_array(struct irq_desc, nr_irqs);
+    irq_status = xmalloc_array(int, nr_irqs);
+    irq_guest_eoi_timer = xmalloc_array(struct timer, nr_irqs);
+    irq_vector = xmalloc_array(u8, nr_irqs);
+    
+    if (!irq_desc || !irq_status ||! irq_vector || !irq_guest_eoi_timer)
+        return -1;
+
+    memset(irq_desc, 0,  nr_irqs * sizeof(*irq_desc));
+    memset(irq_status, 0,  nr_irqs * sizeof(*irq_status));
+    memset(irq_vector, 0, nr_irqs * sizeof(*irq_vector));
+    memset(irq_guest_eoi_timer, 0, nr_irqs * sizeof(*irq_guest_eoi_timer));
+    
+    for (irq = 0; irq < nr_irqs; irq++) {
+        desc = irq_to_desc(irq);
+        desc->irq = irq;
+        init_one_irq_desc(desc);
+        init_one_irq_status(irq);
+    }
+
+    return 0;
+}
+
 static void __do_IRQ_guest(int vector);
 
 void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs) { }
@@ -41,9 +190,9 @@ static void enable_none(unsigned int vec
 static void enable_none(unsigned int vector) { }
 static unsigned int startup_none(unsigned int vector) { return 0; }
 static void disable_none(unsigned int vector) { }
-static void ack_none(unsigned int vector)
-{
-    ack_bad_irq(vector);
+static void ack_none(unsigned int irq)
+{
+    ack_bad_irq(irq);
 }
 
 #define shutdown_none   disable_none
@@ -61,33 +210,15 @@ struct hw_interrupt_type no_irq_type = {
 
 atomic_t irq_err_count;
 
-int free_irq_vector(int vector)
-{
-    int irq;
-
-    BUG_ON((vector > LAST_DYNAMIC_VECTOR) || (vector < FIRST_DYNAMIC_VECTOR));
-
-    spin_lock(&vector_lock);
-    if ((irq = vector_irq[vector]) == AUTO_ASSIGN_IRQ)
-        vector_irq[vector] = FREE_TO_ASSIGN_IRQ;
-    spin_unlock(&vector_lock);
-
-    return (irq == AUTO_ASSIGN_IRQ) ? 0 : -EINVAL;
-}
-
-int assign_irq_vector(int irq)
+int __assign_irq_vector(int irq)
 {
     static unsigned current_vector = FIRST_DYNAMIC_VECTOR;
     unsigned vector;
 
-    BUG_ON(irq >= nr_irqs_gsi && irq != AUTO_ASSIGN_IRQ);
-
-    spin_lock(&vector_lock);
-
-    if ((irq != AUTO_ASSIGN_IRQ) && (irq_to_vector(irq) > 0)) {
-        spin_unlock(&vector_lock);
+    BUG_ON(irq >= nr_irqs || irq < 0);
+
+    if ((irq_to_vector(irq) > 0)) 
         return irq_to_vector(irq);
-    }
 
     vector = current_vector;
     while (vector_irq[vector] != FREE_TO_ASSIGN_IRQ) {
@@ -95,40 +226,59 @@ int assign_irq_vector(int irq)
         if (vector > LAST_DYNAMIC_VECTOR)
             vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7);
 
-        if (vector == current_vector) {
-            spin_unlock(&vector_lock);
+        if (vector == current_vector)
             return -ENOSPC;
-        }
     }
 
     current_vector = vector;
     vector_irq[vector] = irq;
-    if (irq != AUTO_ASSIGN_IRQ)
-        IO_APIC_VECTOR(irq) = vector;
-
-    spin_unlock(&vector_lock);
+    irq_vector[irq] = vector;
+    irq_status[irq] = IRQ_USED;
 
     return vector;
 }
 
+int assign_irq_vector(int irq)
+{
+    int ret;
+    unsigned long flags;
+    
+    spin_lock_irqsave(&vector_lock, flags);
+    ret = __assign_irq_vector(irq);
+    spin_unlock_irqrestore(&vector_lock, flags);
+
+    return ret;
+}
+
+
 asmlinkage void do_IRQ(struct cpu_user_regs *regs)
 {
-    unsigned int      vector = regs->entry_vector;
-    irq_desc_t       *desc = &irq_desc[vector];
     struct irqaction *action;
     uint32_t          tsc_in;
-
+    unsigned int      vector = regs->entry_vector;
+    int irq = vector_irq[vector];
+    struct irq_desc  *desc;
+    
     perfc_incr(irqs);
 
+    if (irq < 0) {
+        ack_APIC_irq();
+        printk("%s: %d.%d No irq handler for vector (irq %d)\n",
+                __func__, smp_processor_id(), vector, irq);
+        return;
+    }
+
+    desc = irq_to_desc(irq);
+
     spin_lock(&desc->lock);
-    desc->handler->ack(vector);
+    desc->handler->ack(irq);
 
     if ( likely(desc->status & IRQ_GUEST) )
     {
         irq_enter();
         tsc_in = tb_init_done ? get_cycles() : 0;
-        __do_IRQ_guest(vector);
-        TRACE_3D(TRC_TRACE_IRQ, vector, tsc_in, get_cycles());
+        __do_IRQ_guest(irq);
+        TRACE_3D(TRC_TRACE_IRQ, irq, tsc_in, get_cycles());
         irq_exit();
         spin_unlock(&desc->lock);
         return;
@@ -153,8 +303,8 @@ asmlinkage void do_IRQ(struct cpu_user_r
         irq_enter();
         spin_unlock_irq(&desc->lock);
         tsc_in = tb_init_done ? get_cycles() : 0;
-        action->handler(vector_to_irq(vector), action->dev_id, regs);
-        TRACE_3D(TRC_TRACE_IRQ, vector, tsc_in, get_cycles());
+        action->handler(irq, action->dev_id, regs);
+        TRACE_3D(TRC_TRACE_IRQ, irq, tsc_in, get_cycles());
         spin_lock_irq(&desc->lock);
         irq_exit();
     }
@@ -162,11 +312,11 @@ asmlinkage void do_IRQ(struct cpu_user_r
     desc->status &= ~IRQ_INPROGRESS;
 
  out:
-    desc->handler->end(vector);
+    desc->handler->end(irq);
     spin_unlock(&desc->lock);
 }
 
-int request_irq_vector(unsigned int vector,
+int request_irq(unsigned int irq,
         void (*handler)(int, void *, struct cpu_user_regs *),
         unsigned long irqflags, const char * devname, void *dev_id)
 {
@@ -179,7 +329,7 @@ int request_irq_vector(unsigned int vect
      * which interrupt is which (messes up the interrupt freeing
      * logic etc).
      */
-    if (vector >= NR_VECTORS)
+    if (irq >= nr_irqs)
         return -EINVAL;
     if (!handler)
         return -EINVAL;
@@ -192,33 +342,42 @@ int request_irq_vector(unsigned int vect
     action->name = devname;
     action->dev_id = dev_id;
 
-    retval = setup_irq_vector(vector, action);
+    retval = setup_irq(irq, action);
     if (retval)
         xfree(action);
 
     return retval;
 }
 
-void release_irq_vector(unsigned int vector)
-{
-    irq_desc_t *desc = &irq_desc[vector];
+void release_irq(unsigned int irq)
+{
+    struct irq_desc *desc;
     unsigned long flags;
+    struct irqaction *action;
+
+    desc = irq_to_desc(irq);
 
     spin_lock_irqsave(&desc->lock,flags);
+    action = desc->action;
     desc->action  = NULL;
     desc->depth   = 1;
     desc->status |= IRQ_DISABLED;
-    desc->handler->shutdown(vector);
+    desc->handler->shutdown(irq);
     spin_unlock_irqrestore(&desc->lock,flags);
 
     /* Wait to make sure it's not being used on another CPU */
     do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS );
-}
-
-int setup_irq_vector(unsigned int vector, struct irqaction *new)
-{
-    irq_desc_t *desc = &irq_desc[vector];
+
+    if (action)
+        xfree(action);
+}
+
+int setup_irq(unsigned int irq, struct irqaction *new)
+{
+    struct irq_desc *desc;
     unsigned long flags;
+
+    desc = irq_to_desc(irq);
  
     spin_lock_irqsave(&desc->lock,flags);
 
@@ -231,7 +390,7 @@ int setup_irq_vector(unsigned int vector
     desc->action  = new;
     desc->depth   = 0;
     desc->status &= ~IRQ_DISABLED;
-    desc->handler->startup(vector);
+    desc->handler->startup(irq);
 
     spin_unlock_irqrestore(&desc->lock,flags);
 
@@ -261,9 +420,10 @@ typedef struct {
  * order, as only the current highest-priority pending irq can be EOIed.
  */
 struct pending_eoi {
-    u8 vector; /* Vector awaiting EOI */
+    u8 vector; /* vector awaiting EOI */
     u8 ready;  /* Ready for EOI now?  */
 };
+
 static DEFINE_PER_CPU(struct pending_eoi, pending_eoi[NR_VECTORS]);
 #define pending_eoi_sp(p) ((p)[NR_VECTORS-1].vector)
 
@@ -279,26 +439,25 @@ static inline void clear_pirq_eoi(struct
         clear_bit(irq, d->arch.pirq_eoi_map);
 }
 
-static void _irq_guest_eoi(irq_desc_t *desc)
+static void _irq_guest_eoi(struct irq_desc *desc)
 {
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
-    unsigned int i, vector = desc - irq_desc;
+    unsigned int i, irq = desc - irq_desc;
 
     if ( !(desc->status & IRQ_GUEST_EOI_PENDING) )
         return;
 
     for ( i = 0; i < action->nr_guests; ++i )
         clear_pirq_eoi(action->guest[i],
-                       domain_vector_to_irq(action->guest[i], vector));
+                       domain_irq_to_pirq(action->guest[i], irq));
 
     desc->status &= ~(IRQ_INPROGRESS|IRQ_GUEST_EOI_PENDING);
-    desc->handler->enable(vector);
-}
-
-static struct timer irq_guest_eoi_timer[NR_VECTORS];
+    desc->handler->enable(irq);
+}
+
 static void irq_guest_eoi_timer_fn(void *data)
 {
-    irq_desc_t *desc = data;
+    struct irq_desc *desc = data;
     unsigned long flags;
 
     spin_lock_irqsave(&desc->lock, flags);
@@ -306,20 +465,21 @@ static void irq_guest_eoi_timer_fn(void 
     spin_unlock_irqrestore(&desc->lock, flags);
 }
 
-static void __do_IRQ_guest(int vector)
-{
-    irq_desc_t         *desc = &irq_desc[vector];
+static void __do_IRQ_guest(int irq)
+{
+    struct irq_desc         *desc = irq_to_desc(irq);
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
     struct domain      *d;
     int                 i, sp, already_pending = 0;
     struct pending_eoi *peoi = this_cpu(pending_eoi);
+    int vector = irq_to_vector(irq);
 
     if ( unlikely(action->nr_guests == 0) )
     {
         /* An interrupt may slip through while freeing an ACKTYPE_EOI irq. */
         ASSERT(action->ack_type == ACKTYPE_EOI);
         ASSERT(desc->status & IRQ_DISABLED);
-        desc->handler->end(vector);
+        desc->handler->end(irq);
         return;
     }
 
@@ -336,13 +496,13 @@ static void __do_IRQ_guest(int vector)
 
     for ( i = 0; i < action->nr_guests; i++ )
     {
-        unsigned int irq;
+        unsigned int pirq;
         d = action->guest[i];
-        irq = domain_vector_to_irq(d, vector);
+        pirq = domain_irq_to_pirq(d, irq);
         if ( (action->ack_type != ACKTYPE_NONE) &&
-             !test_and_set_bit(irq, d->pirq_mask) )
+             !test_and_set_bit(pirq, d->pirq_mask) )
             action->in_flight++;
-        if ( hvm_do_IRQ_dpci(d, irq) )
+        if ( hvm_do_IRQ_dpci(d, pirq) )
         {
             if ( action->ack_type == ACKTYPE_NONE )
             {
@@ -350,7 +510,7 @@ static void __do_IRQ_guest(int vector)
                 desc->status |= IRQ_INPROGRESS; /* cleared during hvm eoi */
             }
         }
-        else if ( send_guest_pirq(d, irq) &&
+        else if ( send_guest_pirq(d, pirq) &&
                   (action->ack_type == ACKTYPE_NONE) )
         {
             already_pending++;
@@ -359,13 +519,13 @@ static void __do_IRQ_guest(int vector)
 
     if ( already_pending == action->nr_guests )
     {
-        stop_timer(&irq_guest_eoi_timer[vector]);
-        desc->handler->disable(vector);
+        stop_timer(&irq_guest_eoi_timer[irq]);
+        desc->handler->disable(irq);
         desc->status |= IRQ_GUEST_EOI_PENDING;
         for ( i = 0; i < already_pending; ++i )
         {
             d = action->guest[i];
-            set_pirq_eoi(d, domain_vector_to_irq(d, vector));
+            set_pirq_eoi(d, domain_irq_to_pirq(d, irq));
             /*
              * Could check here whether the guest unmasked the event by now
              * (or perhaps just re-issue the send_guest_pirq()), and if it
@@ -375,9 +535,9 @@ static void __do_IRQ_guest(int vector)
              * - skip the timer setup below.
              */
         }
-        init_timer(&irq_guest_eoi_timer[vector],
+        init_timer(&irq_guest_eoi_timer[irq],
                    irq_guest_eoi_timer_fn, desc, smp_processor_id());
-        set_timer(&irq_guest_eoi_timer[vector], NOW() + MILLISECS(1));
+        set_timer(&irq_guest_eoi_timer[irq], NOW() + MILLISECS(1));
     }
 }
 
@@ -386,21 +546,21 @@ static void __do_IRQ_guest(int vector)
  * The descriptor is returned locked. This function is safe against changes
  * to the per-domain irq-to-vector mapping.
  */
-irq_desc_t *domain_spin_lock_irq_desc(
-    struct domain *d, int irq, unsigned long *pflags)
-{
-    unsigned int vector;
+struct irq_desc *domain_spin_lock_irq_desc(
+    struct domain *d, int pirq, unsigned long *pflags)
+{
+    unsigned int irq;
     unsigned long flags;
-    irq_desc_t *desc;
+    struct irq_desc *desc;
 
     for ( ; ; )
     {
-        vector = domain_irq_to_vector(d, irq);
-        if ( vector <= 0 )
+        irq = domain_pirq_to_irq(d, pirq);
+        if ( irq <= 0 )
             return NULL;
-        desc = &irq_desc[vector];
+        desc = irq_to_desc(irq);
         spin_lock_irqsave(&desc->lock, flags);
-        if ( vector == domain_irq_to_vector(d, irq) )
+        if ( irq == domain_pirq_to_irq(d, pirq) )
             break;
         spin_unlock_irqrestore(&desc->lock, flags);
     }
@@ -414,8 +574,8 @@ static void flush_ready_eoi(void)
 static void flush_ready_eoi(void)
 {
     struct pending_eoi *peoi = this_cpu(pending_eoi);
-    irq_desc_t         *desc;
-    int                 vector, sp;
+    struct irq_desc         *desc;
+    int                irq, sp;
 
     ASSERT(!local_irq_is_enabled());
 
@@ -423,23 +583,23 @@ static void flush_ready_eoi(void)
 
     while ( (--sp >= 0) && peoi[sp].ready )
     {
-        vector = peoi[sp].vector;
-        desc = &irq_desc[vector];
+        irq = vector_irq[peoi[sp].vector];
+        desc = irq_to_desc(irq);
         spin_lock(&desc->lock);
-        desc->handler->end(vector);
+        desc->handler->end(irq);
         spin_unlock(&desc->lock);
     }
 
     pending_eoi_sp(peoi) = sp+1;
 }
 
-static void __set_eoi_ready(irq_desc_t *desc)
+static void __set_eoi_ready(struct irq_desc *desc)
 {
     irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
     struct pending_eoi *peoi = this_cpu(pending_eoi);
-    int                 vector, sp;
-
-    vector = desc - irq_desc;
+    int                 irq, sp;
+
+    irq = desc - irq_desc;
 
     if ( !(desc->status & IRQ_GUEST) ||
          (action->in_flight != 0) ||
@@ -449,7 +609,7 @@ static void __set_eoi_ready(irq_desc_t *
     sp = pending_eoi_sp(peoi);
     do {
         ASSERT(sp > 0);
-    } while ( peoi[--sp].vector != vector );
+    } while ( peoi[--sp].vector != irq_to_vector(irq) );
     ASSERT(!peoi[sp].ready);
     peoi[sp].ready = 1;
 }
@@ -457,7 +617,7 @@ static void __set_eoi_ready(irq_desc_t *
 /* Mark specified IRQ as ready-for-EOI (if it really is) and attempt to EOI. */
 static void set_eoi_ready(void *data)
 {
-    irq_desc_t *desc = data;
+    struct irq_desc *desc = data;
 
     ASSERT(!local_irq_is_enabled());
 
@@ -468,29 +628,29 @@ static void set_eoi_ready(void *data)
     flush_ready_eoi();
 }
 
-static void __pirq_guest_eoi(struct domain *d, int irq)
-{
-    irq_desc_t         *desc;
+static void __pirq_guest_eoi(struct domain *d, int pirq)
+{
+    struct irq_desc         *desc;
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
-    int                 vector;
+    int                 irq;
 
     ASSERT(local_irq_is_enabled());
-    desc = domain_spin_lock_irq_desc(d, irq, NULL);
+    desc = domain_spin_lock_irq_desc(d, pirq, NULL);
     if ( desc == NULL )
         return;
 
     action = (irq_guest_action_t *)desc->action;
-    vector = desc - irq_desc;
+    irq = desc - irq_desc;
 
     if ( action->ack_type == ACKTYPE_NONE )
     {
-        ASSERT(!test_bit(irq, d->pirq_mask));
-        stop_timer(&irq_guest_eoi_timer[vector]);
+        ASSERT(!test_bit(pirq, d->pirq_mask));
+        stop_timer(&irq_guest_eoi_timer[irq]);
         _irq_guest_eoi(desc);
     }
 
-    if ( unlikely(!test_and_clear_bit(irq, d->pirq_mask)) ||
+    if ( unlikely(!test_and_clear_bit(pirq, d->pirq_mask)) ||
          unlikely(--action->in_flight != 0) )
     {
         spin_unlock_irq(&desc->lock);
@@ -500,7 +660,7 @@ static void __pirq_guest_eoi(struct doma
     if ( action->ack_type == ACKTYPE_UNMASK )
     {
         ASSERT(cpus_empty(action->cpu_eoi_map));
-        desc->handler->end(vector);
+        desc->handler->end(irq);
         spin_unlock_irq(&desc->lock);
         return;
     }
@@ -527,7 +687,7 @@ static void __pirq_guest_eoi(struct doma
 
 int pirq_guest_eoi(struct domain *d, int irq)
 {
-    if ( (irq < 0) || (irq >= d->nr_pirqs) )
+    if ( (irq < 0) || (irq > d->nr_pirqs) )
         return -EINVAL;
 
     __pirq_guest_eoi(d, irq);
@@ -551,16 +711,16 @@ int pirq_guest_unmask(struct domain *d)
 }
 
 extern int ioapic_ack_new;
-static int pirq_acktype(struct domain *d, int irq)
-{
-    irq_desc_t  *desc;
-    unsigned int vector;
-
-    vector = domain_irq_to_vector(d, irq);
-    if ( vector <= 0 )
+static int pirq_acktype(struct domain *d, int pirq)
+{
+    struct irq_desc  *desc;
+    unsigned int irq;
+
+    irq = domain_pirq_to_irq(d, pirq);
+    if ( irq <= 0 )
         return ACKTYPE_NONE;
 
-    desc = &irq_desc[vector];
+    desc = irq_to_desc(irq);
 
     if ( desc->handler == &no_irq_type )
         return ACKTYPE_NONE;
@@ -597,14 +757,14 @@ static int pirq_acktype(struct domain *d
     return 0;
 }
 
-int pirq_shared(struct domain *d, int irq)
-{
-    irq_desc_t         *desc;
+int pirq_shared(struct domain *d, int pirq)
+{
+    struct irq_desc         *desc;
     irq_guest_action_t *action;
     unsigned long       flags;
     int                 shared;
 
-    desc = domain_spin_lock_irq_desc(d, irq, &flags);
+    desc = domain_spin_lock_irq_desc(d, pirq, &flags);
     if ( desc == NULL )
         return 0;
 
@@ -616,10 +776,10 @@ int pirq_shared(struct domain *d, int ir
     return shared;
 }
 
-int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
-{
-    unsigned int        vector;
-    irq_desc_t         *desc;
+int pirq_guest_bind(struct vcpu *v, int pirq, int will_share)
+{
+    unsigned int        irq;
+    struct irq_desc         *desc;
     irq_guest_action_t *action, *newaction = NULL;
     int                 rc = 0;
     cpumask_t           cpumask = CPU_MASK_NONE;
@@ -628,7 +788,7 @@ int pirq_guest_bind(struct vcpu *v, int 
     BUG_ON(!local_irq_is_enabled());
 
  retry:
-    desc = domain_spin_lock_irq_desc(v->domain, irq, NULL);
+    desc = domain_spin_lock_irq_desc(v->domain, pirq, NULL);
     if ( desc == NULL )
     {
         rc = -EINVAL;
@@ -636,7 +796,7 @@ int pirq_guest_bind(struct vcpu *v, int 
     }
 
     action = (irq_guest_action_t *)desc->action;
-    vector = desc - irq_desc;
+    irq = desc - irq_desc;
 
     if ( !(desc->status & IRQ_GUEST) )
     {
@@ -644,7 +804,7 @@ int pirq_guest_bind(struct vcpu *v, int 
         {
             gdprintk(XENLOG_INFO,
                     "Cannot bind IRQ %d to guest. In use by '%s'.\n",
-                    irq, desc->action->name);
+                    pirq, desc->action->name);
             rc = -EBUSY;
             goto unlock_out;
         }
@@ -656,7 +816,7 @@ int pirq_guest_bind(struct vcpu *v, int 
                 goto retry;
             gdprintk(XENLOG_INFO,
                      "Cannot bind IRQ %d to guest. Out of memory.\n",
-                     irq);
+                     pirq);
             rc = -ENOMEM;
             goto out;
         }
@@ -668,23 +828,23 @@ int pirq_guest_bind(struct vcpu *v, int 
         action->nr_guests   = 0;
         action->in_flight   = 0;
         action->shareable   = will_share;
-        action->ack_type    = pirq_acktype(v->domain, irq);
+        action->ack_type    = pirq_acktype(v->domain, pirq);
         cpus_clear(action->cpu_eoi_map);
 
         desc->depth = 0;
         desc->status |= IRQ_GUEST;
         desc->status &= ~IRQ_DISABLED;
-        desc->handler->startup(vector);
+        desc->handler->startup(irq);
 
         /* Attempt to bind the interrupt target to the correct CPU. */
         cpu_set(v->processor, cpumask);
         if ( !opt_noirqbalance && (desc->handler->set_affinity != NULL) )
-            desc->handler->set_affinity(vector, cpumask);
+            desc->handler->set_affinity(irq, cpumask);
     }
     else if ( !will_share || !action->shareable )
     {
         gdprintk(XENLOG_INFO, "Cannot bind IRQ %d to guest. %s.\n",
-                 irq,
+                 pirq,
                  will_share ?
                  "Others do not share" :
                  "Will not share with others");
@@ -707,7 +867,7 @@ int pirq_guest_bind(struct vcpu *v, int 
     if ( action->nr_guests == IRQ_MAX_GUESTS )
     {
         gdprintk(XENLOG_INFO, "Cannot bind IRQ %d to guest. "
-               "Already at max share.\n", irq);
+               "Already at max share.\n", pirq);
         rc = -EBUSY;
         goto unlock_out;
     }
@@ -715,9 +875,9 @@ int pirq_guest_bind(struct vcpu *v, int 
     action->guest[action->nr_guests++] = v->domain;
 
     if ( action->ack_type != ACKTYPE_NONE )
-        set_pirq_eoi(v->domain, irq);
+        set_pirq_eoi(v->domain, pirq);
     else
-        clear_pirq_eoi(v->domain, irq);
+        clear_pirq_eoi(v->domain, pirq);
 
  unlock_out:
     spin_unlock_irq(&desc->lock);
@@ -728,9 +888,9 @@ int pirq_guest_bind(struct vcpu *v, int 
 }
 
 static irq_guest_action_t *__pirq_guest_unbind(
-    struct domain *d, int irq, irq_desc_t *desc)
-{
-    unsigned int        vector;
+    struct domain *d, int pirq, struct irq_desc *desc)
+{
+    unsigned int        irq;
     irq_guest_action_t *action;
     cpumask_t           cpu_eoi_map;
     int                 i;
@@ -738,7 +898,7 @@ static irq_guest_action_t *__pirq_guest_
     BUG_ON(!(desc->status & IRQ_GUEST));
 
     action = (irq_guest_action_t *)desc->action;
-    vector = desc - irq_desc;
+    irq = desc - irq_desc;
 
     for ( i = 0; (i < action->nr_guests) && (action->guest[i] != d); i++ )
         continue;
@@ -749,13 +909,13 @@ static irq_guest_action_t *__pirq_guest_
     switch ( action->ack_type )
     {
     case ACKTYPE_UNMASK:
-        if ( test_and_clear_bit(irq, d->pirq_mask) &&
+        if ( test_and_clear_bit(pirq, d->pirq_mask) &&
              (--action->in_flight == 0) )
-            desc->handler->end(vector);
+            desc->handler->end(irq);
         break;
     case ACKTYPE_EOI:
         /* NB. If #guests == 0 then we clear the eoi_map later on. */
-        if ( test_and_clear_bit(irq, d->pirq_mask) &&
+        if ( test_and_clear_bit(pirq, d->pirq_mask) &&
              (--action->in_flight == 0) &&
              (action->nr_guests != 0) )
         {
@@ -766,7 +926,7 @@ static irq_guest_action_t *__pirq_guest_
         }
         break;
     case ACKTYPE_NONE:
-        stop_timer(&irq_guest_eoi_timer[vector]);
+        stop_timer(&irq_guest_eoi_timer[irq]);
         _irq_guest_eoi(desc);
         break;
     }
@@ -775,7 +935,7 @@ static irq_guest_action_t *__pirq_guest_
      * The guest cannot re-bind to this IRQ until this function returns. So,
      * when we have flushed this IRQ from pirq_mask, it should remain flushed.
      */
-    BUG_ON(test_bit(irq, d->pirq_mask));
+    BUG_ON(test_bit(pirq, d->pirq_mask));
 
     if ( action->nr_guests != 0 )
         return NULL;
@@ -785,7 +945,7 @@ static irq_guest_action_t *__pirq_guest_
     /* Disabling IRQ before releasing the desc_lock avoids an IRQ storm. */
     desc->depth   = 1;
     desc->status |= IRQ_DISABLED;
-    desc->handler->disable(vector);
+    desc->handler->disable(irq);
 
     /*
      * Mark any remaining pending EOIs as ready to flush.
@@ -808,35 +968,35 @@ static irq_guest_action_t *__pirq_guest_
     desc->action = NULL;
     desc->status &= ~IRQ_GUEST;
     desc->status &= ~IRQ_INPROGRESS;
-    kill_timer(&irq_guest_eoi_timer[vector]);
-    desc->handler->shutdown(vector);
+    kill_timer(&irq_guest_eoi_timer[irq]);
+    desc->handler->shutdown(irq);
 
     /* Caller frees the old guest descriptor block. */
     return action;
 }
 
-void pirq_guest_unbind(struct domain *d, int irq)
+void pirq_guest_unbind(struct domain *d, int pirq)
 {
     irq_guest_action_t *oldaction = NULL;
-    irq_desc_t *desc;
-    int vector;
+    struct irq_desc *desc;
+    int irq;
 
     WARN_ON(!spin_is_locked(&d->event_lock));
 
     BUG_ON(!local_irq_is_enabled());
-    desc = domain_spin_lock_irq_desc(d, irq, NULL);
+    desc = domain_spin_lock_irq_desc(d, pirq, NULL);
 
     if ( desc == NULL )
     {
-        vector = -domain_irq_to_vector(d, irq);
-        BUG_ON(vector <= 0);
-        desc = &irq_desc[vector];
+        irq = -domain_pirq_to_irq(d, pirq);
+        BUG_ON(irq <= 0);
+        desc = irq_to_desc(irq);
         spin_lock_irq(&desc->lock);
-        d->arch.pirq_vector[irq] = d->arch.vector_pirq[vector] = 0;
+        d->arch.pirq_irq[pirq] = d->arch.irq_pirq[irq] = 0;
     }
     else
     {
-        oldaction = __pirq_guest_unbind(d, irq, desc);
+        oldaction = __pirq_guest_unbind(d, pirq, desc);
     }
 
     spin_unlock_irq(&desc->lock);
@@ -847,7 +1007,7 @@ void pirq_guest_unbind(struct domain *d,
 
 static int pirq_guest_force_unbind(struct domain *d, int irq)
 {
-    irq_desc_t *desc;
+    struct irq_desc *desc;
     irq_guest_action_t *action, *oldaction = NULL;
     int i, bound = 0;
 
@@ -887,7 +1047,7 @@ int get_free_pirq(struct domain *d, int 
     if ( type == MAP_PIRQ_TYPE_GSI )
     {
         for ( i = 16; i < nr_irqs_gsi; i++ )
-            if ( !d->arch.pirq_vector[i] )
+            if ( !d->arch.pirq_irq[i] )
                 break;
         if ( i == nr_irqs_gsi )
             return -ENOSPC;
@@ -895,7 +1055,7 @@ int get_free_pirq(struct domain *d, int 
     else
     {
         for ( i = d->nr_pirqs - 1; i >= 16; i-- )
-            if ( !d->arch.pirq_vector[i] )
+            if ( !d->arch.pirq_irq[i] )
                 break;
         if ( i == 16 )
             return -ENOSPC;
@@ -905,11 +1065,11 @@ int get_free_pirq(struct domain *d, int 
 }
 
 int map_domain_pirq(
-    struct domain *d, int pirq, int vector, int type, void *data)
+    struct domain *d, int pirq, int irq, int type, void *data)
 {
     int ret = 0;
-    int old_vector, old_pirq;
-    irq_desc_t *desc;
+    int old_irq, old_pirq;
+    struct irq_desc *desc;
     unsigned long flags;
     struct msi_desc *msi_desc;
     struct pci_dev *pdev = NULL;
@@ -920,21 +1080,21 @@ int map_domain_pirq(
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
 
-    if ( pirq < 0 || pirq >= d->nr_pirqs || vector < 0 || vector >= NR_VECTORS 
)
-    {
-        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or vector %d\n",
-                d->domain_id, pirq, vector);
+    if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs )
+    {
+        dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or irq %d\n",
+                d->domain_id, pirq, irq);
         return -EINVAL;
     }
 
-    old_vector = domain_irq_to_vector(d, pirq);
-    old_pirq = domain_vector_to_irq(d, vector);
-
-    if ( (old_vector && (old_vector != vector) ) ||
+    old_irq = domain_pirq_to_irq(d, pirq);
+    old_pirq = domain_irq_to_pirq(d, irq);
+
+    if ( (old_irq && (old_irq != irq) ) ||
          (old_pirq && (old_pirq != pirq)) )
     {
-        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or vector %d already mapped\n",
-                d->domain_id, pirq, vector);
+        dprintk(XENLOG_G_ERR, "dom%d: pirq %d or irq %d already mapped\n",
+                d->domain_id, pirq, irq);
         return -EINVAL;
     }
 
@@ -946,7 +1106,7 @@ int map_domain_pirq(
         return ret;
     }
 
-    desc = &irq_desc[vector];
+    desc = irq_to_desc(irq);
 
     if ( type == MAP_PIRQ_TYPE_MSI )
     {
@@ -964,18 +1124,18 @@ int map_domain_pirq(
         spin_lock_irqsave(&desc->lock, flags);
 
         if ( desc->handler != &no_irq_type )
-            dprintk(XENLOG_G_ERR, "dom%d: vector %d in use\n",
-              d->domain_id, vector);
+            dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n",
+              d->domain_id, irq);
         desc->handler = &pci_msi_type;
-        d->arch.pirq_vector[pirq] = vector;
-        d->arch.vector_pirq[vector] = pirq;
-        setup_msi_irq(pdev, msi_desc);
+        d->arch.pirq_irq[pirq] = irq;
+        d->arch.irq_pirq[irq] = pirq;
+        setup_msi_irq(pdev, msi_desc, irq);
         spin_unlock_irqrestore(&desc->lock, flags);
     } else
     {
         spin_lock_irqsave(&desc->lock, flags);
-        d->arch.pirq_vector[pirq] = vector;
-        d->arch.vector_pirq[vector] = pirq;
+        d->arch.pirq_irq[pirq] = irq;
+        d->arch.irq_pirq[irq] = pirq;
         spin_unlock_irqrestore(&desc->lock, flags);
     }
 
@@ -987,8 +1147,8 @@ int unmap_domain_pirq(struct domain *d, 
 int unmap_domain_pirq(struct domain *d, int pirq)
 {
     unsigned long flags;
-    irq_desc_t *desc;
-    int vector, ret = 0;
+    struct irq_desc *desc;
+    int irq, ret = 0;
     bool_t forced_unbind;
     struct msi_desc *msi_desc = NULL;
 
@@ -1001,8 +1161,8 @@ int unmap_domain_pirq(struct domain *d, 
     ASSERT(spin_is_locked(&pcidevs_lock));
     ASSERT(spin_is_locked(&d->event_lock));
 
-    vector = domain_irq_to_vector(d, pirq);
-    if ( vector <= 0 )
+    irq = domain_pirq_to_irq(d, pirq);
+    if ( irq <= 0 )
     {
         dprintk(XENLOG_G_ERR, "dom%d: pirq %d not mapped\n",
                 d->domain_id, pirq);
@@ -1015,44 +1175,41 @@ int unmap_domain_pirq(struct domain *d, 
         dprintk(XENLOG_G_WARNING, "dom%d: forcing unbind of pirq %d\n",
                 d->domain_id, pirq);
 
-    desc = &irq_desc[vector];
+    desc = irq_to_desc(irq);
 
     if ( (msi_desc = desc->msi_desc) != NULL )
         pci_disable_msi(msi_desc);
 
     spin_lock_irqsave(&desc->lock, flags);
 
-    BUG_ON(vector != domain_irq_to_vector(d, pirq));
+    BUG_ON(irq != domain_pirq_to_irq(d, pirq));
 
     if ( msi_desc )
-        teardown_msi_vector(vector);
-
-    if ( desc->handler == &pci_msi_type )
-        desc->handler = &no_irq_type;
+        teardown_msi_irq(irq);
 
     if ( !forced_unbind )
     {
-        d->arch.pirq_vector[pirq] = 0;
-        d->arch.vector_pirq[vector] = 0;
+        d->arch.pirq_irq[pirq] = 0;
+        d->arch.irq_pirq[irq] = 0;
     }
     else
     {
-        d->arch.pirq_vector[pirq] = -vector;
-        d->arch.vector_pirq[vector] = -pirq;
+        d->arch.pirq_irq[pirq] = -irq;
+        d->arch.irq_pirq[irq] = -pirq;
     }
 
     spin_unlock_irqrestore(&desc->lock, flags);
     if (msi_desc)
-    {
-        msi_free_vector(msi_desc);
-        free_irq_vector(vector);
-    }
+        msi_free_irq(msi_desc);
 
     ret = irq_deny_access(d, pirq);
     if ( ret )
         dprintk(XENLOG_G_ERR, "dom%d: could not deny access to irq %d\n",
                 d->domain_id, pirq);
 
+    if ( desc->handler == &pci_msi_type )
+        desc->handler = &no_irq_type;
+
  done:
     return ret;
 }
@@ -1065,7 +1222,7 @@ void free_domain_pirqs(struct domain *d)
     spin_lock(&d->event_lock);
 
     for ( i = 0; i < d->nr_pirqs; i++ )
-        if ( d->arch.pirq_vector[i] > 0 )
+        if ( d->arch.pirq_irq[i] > 0 )
             unmap_domain_pirq(d, i);
 
     spin_unlock(&d->event_lock);
@@ -1077,7 +1234,7 @@ static void dump_irqs(unsigned char key)
 static void dump_irqs(unsigned char key)
 {
     int i, glob_irq, irq, vector;
-    irq_desc_t *desc;
+    struct irq_desc *desc;
     irq_guest_action_t *action;
     struct domain *d;
     unsigned long flags;
@@ -1088,8 +1245,10 @@ static void dump_irqs(unsigned char key)
     {
 
         glob_irq = vector_to_irq(vector);
-
-        desc = &irq_desc[vector];
+        if (glob_irq < 0)
+            continue;
+
+        desc = irq_to_desc(glob_irq);
         if ( desc == NULL || desc->handler == &no_irq_type )
             continue;
 
@@ -1111,7 +1270,7 @@ static void dump_irqs(unsigned char key)
             for ( i = 0; i < action->nr_guests; i++ )
             {
                 d = action->guest[i];
-                irq = domain_vector_to_irq(d, vector);
+                irq = domain_irq_to_pirq(d, vector_irq[vector]);
                 printk("%u:%3d(%c%c%c%c)",
                        d->domain_id, irq,
                        (test_bit(d->pirq_to_evtchn[glob_irq],
@@ -1172,7 +1331,7 @@ void fixup_irqs(cpumask_t map)
         if ( vector_to_irq(vector) == 2 )
             continue;
 
-        desc = &irq_desc[vector];
+        desc = irq_to_desc(vector_to_irq(vector));
 
         spin_lock_irqsave(&desc->lock, flags);
 
@@ -1200,9 +1359,9 @@ void fixup_irqs(cpumask_t map)
     /* Clean up cpu_eoi_map of every interrupt to exclude this CPU. */
     for ( vector = 0; vector < NR_VECTORS; vector++ )
     {
-        if ( !(irq_desc[vector].status & IRQ_GUEST) )
+        if ( !(irq_desc[vector_to_irq(vector)].status & IRQ_GUEST) )
             continue;
-        action = (irq_guest_action_t *)irq_desc[vector].action;
+        action = (irq_guest_action_t *)irq_desc[vector_to_irq(vector)].action;
         cpu_clear(smp_processor_id(), action->cpu_eoi_map);
     }
 
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/msi.c
--- a/xen/arch/x86/msi.c        Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/msi.c        Wed Aug 19 12:53:04 2009 +0100
@@ -116,11 +116,12 @@ static void msix_put_fixmap(struct pci_d
 /*
  * MSI message composition
  */
-void msi_compose_msg(struct pci_dev *pdev, int vector,
+void msi_compose_msg(struct pci_dev *pdev, int irq,
                             struct msi_msg *msg)
 {
     unsigned dest;
     cpumask_t tmp;
+    int vector = irq_to_vector(irq);
 
     tmp = TARGET_CPUS;
     if ( vector )
@@ -195,31 +196,31 @@ static void read_msi_msg(struct msi_desc
         iommu_read_msi_from_ire(entry, msg);
 }
 
-static int set_vector_msi(struct msi_desc *entry)
-{
-    if ( entry->vector >= NR_VECTORS )
-    {
-        dprintk(XENLOG_ERR, "Trying to install msi data for Vector %d\n",
-                entry->vector);
+static int set_irq_msi(struct msi_desc *entry)
+{
+    if ( entry->irq >= nr_irqs )
+    {
+        dprintk(XENLOG_ERR, "Trying to install msi data for irq %d\n",
+                entry->irq);
         return -EINVAL;
     }
 
-    irq_desc[entry->vector].msi_desc = entry;
+    irq_desc[entry->irq].msi_desc = entry;
     return 0;
 }
 
-static int unset_vector_msi(int vector)
-{
-    ASSERT(spin_is_locked(&irq_desc[vector].lock));
-
-    if ( vector >= NR_VECTORS )
-    {
-        dprintk(XENLOG_ERR, "Trying to uninstall msi data for Vector %d\n",
-                vector);
+static int unset_irq_msi(int irq)
+{
+    ASSERT(spin_is_locked(&irq_desc[irq].lock));
+
+    if ( irq >= nr_irqs )
+    {
+        dprintk(XENLOG_ERR, "Trying to uninstall msi data for irq %d\n",
+                irq);
         return -EINVAL;
     }
 
-    irq_desc[vector].msi_desc = NULL;
+    irq_desc[irq].msi_desc = NULL;
 
     return 0;
 }
@@ -271,9 +272,9 @@ static void write_msi_msg(struct msi_des
     entry->msg = *msg;
 }
 
-void set_msi_affinity(unsigned int vector, cpumask_t mask)
-{
-    struct msi_desc *desc = irq_desc[vector].msi_desc;
+void set_msi_affinity(unsigned int irq, cpumask_t mask)
+{
+    struct msi_desc *desc = irq_desc[irq].msi_desc;
     struct msi_msg msg;
     unsigned int dest;
 
@@ -286,7 +287,7 @@ void set_msi_affinity(unsigned int vecto
     if ( !desc )
         return;
 
-    ASSERT(spin_is_locked(&irq_desc[vector].lock));
+    ASSERT(spin_is_locked(&irq_desc[irq].lock));
     read_msi_msg(desc, &msg);
 
     msg.address_lo &= ~MSI_ADDR_DEST_ID_MASK;
@@ -333,9 +334,9 @@ static void msix_set_enable(struct pci_d
     }
 }
 
-static void msix_flush_writes(unsigned int vector)
-{
-    struct msi_desc *entry = irq_desc[vector].msi_desc;
+static void msix_flush_writes(unsigned int irq)
+{
+    struct msi_desc *entry = irq_desc[irq].msi_desc;
 
     BUG_ON(!entry || !entry->dev);
     switch (entry->msi_attrib.type) {
@@ -361,11 +362,11 @@ int msi_maskable_irq(const struct msi_de
            || entry->msi_attrib.maskbit;
 }
 
-static void msi_set_mask_bit(unsigned int vector, int flag)
-{
-    struct msi_desc *entry = irq_desc[vector].msi_desc;
-
-    ASSERT(spin_is_locked(&irq_desc[vector].lock));
+static void msi_set_mask_bit(unsigned int irq, int flag)
+{
+    struct msi_desc *entry = irq_desc[irq].msi_desc;
+
+    ASSERT(spin_is_locked(&irq_desc[irq].lock));
     BUG_ON(!entry || !entry->dev);
     switch (entry->msi_attrib.type) {
     case PCI_CAP_ID_MSI:
@@ -397,16 +398,16 @@ static void msi_set_mask_bit(unsigned in
     entry->msi_attrib.masked = !!flag;
 }
 
-void mask_msi_vector(unsigned int vector)
-{
-    msi_set_mask_bit(vector, 1);
-    msix_flush_writes(vector);
-}
-
-void unmask_msi_vector(unsigned int vector)
-{
-    msi_set_mask_bit(vector, 0);
-    msix_flush_writes(vector);
+void mask_msi_irq(unsigned int irq)
+{
+    msi_set_mask_bit(irq, 1);
+    msix_flush_writes(irq);
+}
+
+void unmask_msi_irq(unsigned int irq)
+{
+    msi_set_mask_bit(irq, 0);
+    msix_flush_writes(irq);
 }
 
 static struct msi_desc* alloc_msi_entry(void)
@@ -424,23 +425,23 @@ static struct msi_desc* alloc_msi_entry(
     return entry;
 }
 
-int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
 {
     struct msi_msg msg;
 
-    msi_compose_msg(dev, desc->vector, &msg);
-    set_vector_msi(desc);
-    write_msi_msg(irq_desc[desc->vector].msi_desc, &msg);
+    msi_compose_msg(dev, irq, &msg);
+    set_irq_msi(msidesc);
+    write_msi_msg(irq_desc[irq].msi_desc, &msg);
 
     return 0;
 }
 
-void teardown_msi_vector(int vector)
-{
-    unset_vector_msi(vector);
-}
-
-int msi_free_vector(struct msi_desc *entry)
+void teardown_msi_irq(int irq)
+{
+    unset_irq_msi(irq);
+}
+
+int msi_free_irq(struct msi_desc *entry)
 {
     if ( entry->msi_attrib.type == PCI_CAP_ID_MSIX )
     {
@@ -452,19 +453,20 @@ int msi_free_vector(struct msi_desc *ent
         msix_put_fixmap(entry->dev, virt_to_fix(start));
     }
     list_del(&entry->list);
+    destroy_irq(entry->irq);
     xfree(entry);
     return 0;
 }
 
 static struct msi_desc *find_msi_entry(struct pci_dev *dev,
-                                       int vector, int cap_id)
+                                       int irq, int cap_id)
 {
     struct msi_desc *entry;
 
     list_for_each_entry( entry, &dev->msi_list, list )
     {
         if ( entry->msi_attrib.type == cap_id &&
-             (vector == -1 || entry->vector == vector) )
+             (irq == -1 || entry->irq == irq) )
             return entry;
     }
 
@@ -481,7 +483,7 @@ static struct msi_desc *find_msi_entry(s
  * of an entry zero with the new MSI irq or non-zero for otherwise.
  **/
 static int msi_capability_init(struct pci_dev *dev,
-                               int vector,
+                               int irq,
                                struct msi_desc **desc)
 {
     struct msi_desc *entry;
@@ -507,7 +509,7 @@ static int msi_capability_init(struct pc
     entry->msi_attrib.maskbit = is_mask_bit_support(control);
     entry->msi_attrib.masked = 1;
     entry->msi_attrib.pos = pos;
-    entry->vector = vector;
+    entry->irq = irq;
     if ( is_mask_bit_support(control) )
         entry->mask_base = (void __iomem *)(long)msi_mask_bits_reg(pos,
                                                                    
is_64bit_address(control));
@@ -594,7 +596,7 @@ static int msix_capability_init(struct p
     entry->msi_attrib.maskbit = 1;
     entry->msi_attrib.masked = 1;
     entry->msi_attrib.pos = pos;
-    entry->vector = msi->vector;
+    entry->irq = msi->irq;
     entry->dev = dev;
     entry->mask_base = base;
 
@@ -630,15 +632,15 @@ static int __pci_enable_msi(struct msi_i
     if ( !pdev )
         return -ENODEV;
 
-    if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSI) )
-    {
-        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSI on "
-                "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
+    if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSI) )
+    {
+        dprintk(XENLOG_WARNING, "irq %d has already mapped to MSI on "
+                "device %02x:%02x.%01x.\n", msi->irq, msi->bus,
                 PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
         return 0;
     }
 
-    status = msi_capability_init(pdev, msi->vector, desc);
+    status = msi_capability_init(pdev, msi->irq, desc);
     return status;
 }
 
@@ -696,10 +698,10 @@ static int __pci_enable_msix(struct msi_
     if (msi->entry_nr >= nr_entries)
         return -EINVAL;
 
-    if ( find_msi_entry(pdev, msi->vector, PCI_CAP_ID_MSIX) )
-    {
-        dprintk(XENLOG_WARNING, "vector %d has already mapped to MSIX on "
-                "device %02x:%02x.%01x.\n", msi->vector, msi->bus,
+    if ( find_msi_entry(pdev, msi->irq, PCI_CAP_ID_MSIX) )
+    {
+        dprintk(XENLOG_WARNING, "irq %d has already mapped to MSIX on "
+                "device %02x:%02x.%01x.\n", msi->irq, msi->bus,
                 PCI_SLOT(msi->devfn), PCI_FUNC(msi->devfn));
         return 0;
     }
@@ -754,21 +756,21 @@ void pci_disable_msi(struct msi_desc *ms
         __pci_disable_msix(msi_desc);
 }
 
-static void msi_free_vectors(struct pci_dev* dev)
+static void msi_free_irqs(struct pci_dev* dev)
 {
     struct msi_desc *entry, *tmp;
-    irq_desc_t *desc;
-    unsigned long flags, vector;
+    struct irq_desc *desc;
+    unsigned long flags, irq;
 
     list_for_each_entry_safe( entry, tmp, &dev->msi_list, list )
     {
-        vector = entry->vector;
-        desc = &irq_desc[vector];
+        irq = entry->irq;
+        desc = &irq_desc[irq];
         pci_disable_msi(entry);
 
         spin_lock_irqsave(&desc->lock, flags);
 
-        teardown_msi_vector(vector);
+        teardown_msi_irq(irq);
 
         if ( desc->handler == &pci_msi_type )
         {
@@ -778,7 +780,7 @@ static void msi_free_vectors(struct pci_
         }
 
         spin_unlock_irqrestore(&desc->lock, flags);
-        msi_free_vector(entry);
+        msi_free_irq(entry);
     }
 }
 
@@ -787,15 +789,15 @@ void pci_cleanup_msi(struct pci_dev *pde
     /* Disable MSI and/or MSI-X */
     msi_set_enable(pdev, 0);
     msix_set_enable(pdev, 0);
-    msi_free_vectors(pdev);
+    msi_free_irqs(pdev);
 }
 
 int pci_restore_msi_state(struct pci_dev *pdev)
 {
     unsigned long flags;
-    int vector;
+    int irq;
     struct msi_desc *entry, *tmp;
-    irq_desc_t *desc;
+    struct irq_desc *desc;
 
     ASSERT(spin_is_locked(&pcidevs_lock));
 
@@ -804,8 +806,8 @@ int pci_restore_msi_state(struct pci_dev
 
     list_for_each_entry_safe( entry, tmp, &pdev->msi_list, list )
     {
-        vector = entry->vector;
-        desc = &irq_desc[vector];
+        irq = entry->irq;
+        desc = &irq_desc[irq];
 
         spin_lock_irqsave(&desc->lock, flags);
 
@@ -826,7 +828,7 @@ int pci_restore_msi_state(struct pci_dev
 
         write_msi_msg(entry, &entry->msg);
 
-        msi_set_mask_bit(vector, entry->msi_attrib.masked);
+        msi_set_mask_bit(irq, entry->msi_attrib.masked);
 
         if ( entry->msi_attrib.type == PCI_CAP_ID_MSI )
             msi_set_enable(pdev, 1);
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/physdev.c    Wed Aug 19 12:53:04 2009 +0100
@@ -30,7 +30,7 @@ static int physdev_map_pirq(struct physd
 static int physdev_map_pirq(struct physdev_map_pirq *map)
 {
     struct domain *d;
-    int vector, pirq, ret = 0;
+    int pirq, irq, ret = 0;
     struct msi_info _msi;
     void *map_data = NULL;
 
@@ -51,7 +51,7 @@ static int physdev_map_pirq(struct physd
         goto free_domain;
     }
 
-    /* Verify or get vector. */
+    /* Verify or get irq. */
     switch ( map->type )
     {
         case MAP_PIRQ_TYPE_GSI:
@@ -62,25 +62,25 @@ static int physdev_map_pirq(struct physd
                 ret = -EINVAL;
                 goto free_domain;
             }
-            vector = domain_irq_to_vector(current->domain, map->index);
-            if ( !vector )
-            {
-                dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n",
-                        d->domain_id, vector);
+            irq = domain_pirq_to_irq(current->domain, map->index);
+            if ( !irq )
+            {
+                dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
+                        d->domain_id);
                 ret = -EINVAL;
                 goto free_domain;
             }
             break;
 
         case MAP_PIRQ_TYPE_MSI:
-            vector = map->index;
-            if ( vector == -1 )
-                vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
-
-            if ( vector < 0 || vector >= NR_VECTORS )
-            {
-                dprintk(XENLOG_G_ERR, "dom%d: map irq with wrong vector %d\n",
-                        d->domain_id, vector);
+            irq = map->index;
+            if ( irq == -1 )
+                irq = create_irq();
+
+            if ( irq < 0 || irq >= nr_irqs )
+            {
+                dprintk(XENLOG_G_ERR, "dom%d: can't create irq for msi!\n",
+                        d->domain_id);
                 ret = -EINVAL;
                 goto free_domain;
             }
@@ -89,7 +89,7 @@ static int physdev_map_pirq(struct physd
             _msi.devfn = map->devfn;
             _msi.entry_nr = map->entry_nr;
             _msi.table_base = map->table_base;
-            _msi.vector = vector;
+            _msi.irq = irq;
             map_data = &_msi;
             break;
 
@@ -103,7 +103,7 @@ static int physdev_map_pirq(struct physd
     spin_lock(&pcidevs_lock);
     /* Verify or get pirq. */
     spin_lock(&d->event_lock);
-    pirq = domain_vector_to_irq(d, vector);
+    pirq = domain_irq_to_pirq(d, irq);
     if ( map->pirq < 0 )
     {
         if ( pirq )
@@ -132,7 +132,7 @@ static int physdev_map_pirq(struct physd
     {
         if ( pirq && pirq != map->pirq )
         {
-            dprintk(XENLOG_G_ERR, "dom%d: vector %d conflicts with irq %d\n",
+            dprintk(XENLOG_G_ERR, "dom%d: pirq %d conflicts with irq %d\n",
                     d->domain_id, map->index, map->pirq);
             ret = -EEXIST;
             goto done;
@@ -141,7 +141,7 @@ static int physdev_map_pirq(struct physd
             pirq = map->pirq;
     }
 
-    ret = map_domain_pirq(d, pirq, vector, map->type, map_data);
+    ret = map_domain_pirq(d, pirq, irq, map->type, map_data);
     if ( ret == 0 )
         map->pirq = pirq;
 
@@ -149,7 +149,7 @@ done:
     spin_unlock(&d->event_lock);
     spin_unlock(&pcidevs_lock);
     if ( (ret != 0) && (map->type == MAP_PIRQ_TYPE_MSI) && (map->index == -1) )
-        free_irq_vector(vector);
+        destroy_irq(irq);
 free_domain:
     rcu_unlock_domain(d);
     return ret;
@@ -344,14 +344,12 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
 
         irq = irq_op.irq;
         ret = -EINVAL;
-        if ( (irq < 0) || (irq >= nr_irqs_gsi) )
-            break;
 
         irq_op.vector = assign_irq_vector(irq);
 
         spin_lock(&pcidevs_lock);
         spin_lock(&dom0->event_lock);
-        ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector,
+        ret = map_domain_pirq(dom0, irq_op.irq, irq,
                               MAP_PIRQ_TYPE_GSI, NULL);
         spin_unlock(&dom0->event_lock);
         spin_unlock(&pcidevs_lock);
diff -r 1afd9142eed3 -r 722c7e94e764 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c      Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/arch/x86/setup.c      Wed Aug 19 12:53:04 2009 +0100
@@ -922,7 +922,7 @@ void __init __start_xen(unsigned long mb
     init_apic_mappings();
 
     init_IRQ();
-
+    
     percpu_init_areas();
 
     xsm_init(&initrdidx, mbi, initial_images_start);
diff -r 1afd9142eed3 -r 722c7e94e764 xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c  Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c  Wed Aug 19 12:53:04 2009 +0100
@@ -27,7 +27,7 @@
 #include <asm/hvm/svm/amd-iommu-proto.h>
 #include <asm-x86/fixmap.h>
 
-static struct amd_iommu *vector_to_iommu[NR_VECTORS];
+static struct amd_iommu **irq_to_iommu;
 static int nr_amd_iommus;
 static long amd_iommu_cmd_buffer_entries = IOMMU_CMD_BUFFER_DEFAULT_ENTRIES;
 static long amd_iommu_event_log_entries = IOMMU_EVENT_LOG_DEFAULT_ENTRIES;
@@ -309,7 +309,7 @@ static void amd_iommu_msi_data_init(stru
     u8 bus = (iommu->bdf >> 8) & 0xff;
     u8 dev = PCI_SLOT(iommu->bdf & 0xff);
     u8 func = PCI_FUNC(iommu->bdf & 0xff);
-    int vector = iommu->vector;
+    int vector = irq_to_vector(iommu->irq);
 
     msi_data = MSI_DATA_TRIGGER_EDGE |
         MSI_DATA_LEVEL_ASSERT |
@@ -355,10 +355,10 @@ static void amd_iommu_msi_enable(struct 
         iommu->msi_cap + PCI_MSI_FLAGS, control);
 }
 
-static void iommu_msi_unmask(unsigned int vector)
+static void iommu_msi_unmask(unsigned int irq)
 {
     unsigned long flags;
-    struct amd_iommu *iommu = vector_to_iommu[vector];
+    struct amd_iommu *iommu = irq_to_iommu[irq];
 
     /* FIXME: do not support mask bits at the moment */
     if ( iommu->maskbit )
@@ -369,10 +369,10 @@ static void iommu_msi_unmask(unsigned in
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-static void iommu_msi_mask(unsigned int vector)
+static void iommu_msi_mask(unsigned int irq)
 {
     unsigned long flags;
-    struct amd_iommu *iommu = vector_to_iommu[vector];
+    struct amd_iommu *iommu = irq_to_iommu[irq];
 
     /* FIXME: do not support mask bits at the moment */
     if ( iommu->maskbit )
@@ -383,21 +383,21 @@ static void iommu_msi_mask(unsigned int 
     spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-static unsigned int iommu_msi_startup(unsigned int vector)
-{
-    iommu_msi_unmask(vector);
+static unsigned int iommu_msi_startup(unsigned int irq)
+{
+    iommu_msi_unmask(irq);
     return 0;
 }
 
-static void iommu_msi_end(unsigned int vector)
-{
-    iommu_msi_unmask(vector);
+static void iommu_msi_end(unsigned int irq)
+{
+    iommu_msi_unmask(irq);
     ack_APIC_irq();
 }
 
-static void iommu_msi_set_affinity(unsigned int vector, cpumask_t dest)
-{
-    struct amd_iommu *iommu = vector_to_iommu[vector];
+static void iommu_msi_set_affinity(unsigned int irq, cpumask_t dest)
+{
+    struct amd_iommu *iommu = irq_to_iommu[irq];
     amd_iommu_msi_addr_init(iommu, cpu_physical_id(first_cpu(dest)));
 }
 
@@ -451,7 +451,7 @@ static void parse_event_log_entry(u32 en
     }
 }
 
-static void amd_iommu_page_fault(int vector, void *dev_id,
+static void amd_iommu_page_fault(int irq, void *dev_id,
                              struct cpu_user_regs *regs)
 {
     u32 event[4];
@@ -477,32 +477,30 @@ static void amd_iommu_page_fault(int vec
 
 static int set_iommu_interrupt_handler(struct amd_iommu *iommu)
 {
-    int vector, ret;
-
-    vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
-    if ( vector <= 0 )
-    {
-        gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
+    int irq, ret;
+
+    irq = create_irq();
+    if ( irq <= 0 )
+    {
+        gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no irqs\n");
         return 0;
     }
 
-    irq_desc[vector].handler = &iommu_msi_type;
-    vector_to_iommu[vector] = iommu;
-    ret = request_irq_vector(vector, amd_iommu_page_fault, 0,
+    irq_desc[irq].handler = &iommu_msi_type;
+    irq_to_iommu[irq] = iommu;
+    ret = request_irq(irq, amd_iommu_page_fault, 0,
                              "amd_iommu", iommu);
     if ( ret )
     {
-        irq_desc[vector].handler = &no_irq_type;
-        vector_to_iommu[vector] = NULL;
-        free_irq_vector(vector);
+        irq_desc[irq].handler = &no_irq_type;
+        irq_to_iommu[irq] = NULL;
+        destroy_irq(irq);
         amd_iov_error("can't request irq\n");
         return 0;
     }
 
-    /* Make sure that vector is never re-used. */
-    vector_irq[vector] = NEVER_ASSIGN_IRQ;
-    iommu->vector = vector;
-    return vector;
+    iommu->irq = irq;
+    return irq;
 }
 
 void enable_iommu(struct amd_iommu *iommu)
@@ -510,6 +508,10 @@ void enable_iommu(struct amd_iommu *iomm
     unsigned long flags;
 
     spin_lock_irqsave(&iommu->lock, flags);
+
+    irq_to_iommu = xmalloc_array(struct amd_iommu *, nr_irqs);
+    BUG_ON(!irq_to_iommu);
+    memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*));
 
     if ( iommu->enabled )
     {
diff -r 1afd9142eed3 -r 722c7e94e764 xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/drivers/passthrough/io.c      Wed Aug 19 12:53:04 2009 +0100
@@ -35,7 +35,6 @@ static void pt_irq_time_out(void *data)
 {
     struct hvm_mirq_dpci_mapping *irq_map = data;
     unsigned int guest_gsi, machine_gsi = 0;
-    int vector;
     struct hvm_irq_dpci *dpci = NULL;
     struct dev_intx_gsi_link *digl;
     struct hvm_girq_dpci_mapping *girq;
@@ -68,7 +67,6 @@ static void pt_irq_time_out(void *data)
                                       machine_gsi + 1) )
     {
         clear_bit(machine_gsi, dpci->dirq_mask);
-        vector = domain_irq_to_vector(irq_map->dom, machine_gsi);
         dpci->mirq[machine_gsi].pending = 0;
     }
 
@@ -88,6 +86,7 @@ void free_hvm_irq_dpci(struct hvm_irq_dp
     xfree(dpci->mirq);
     xfree(dpci->dirq_mask);
     xfree(dpci->mapping);
+    xfree(dpci->hvm_timer);
     xfree(dpci);
 }
 
@@ -124,9 +123,11 @@ int pt_irq_create_bind_vtd(
                                                 BITS_TO_LONGS(d->nr_pirqs));
         hvm_irq_dpci->mapping = xmalloc_array(unsigned long,
                                               BITS_TO_LONGS(d->nr_pirqs));
+        hvm_irq_dpci->hvm_timer = xmalloc_array(struct timer, nr_irqs);
         if ( !hvm_irq_dpci->mirq ||
              !hvm_irq_dpci->dirq_mask ||
-             !hvm_irq_dpci->mapping )
+             !hvm_irq_dpci->mapping ||
+             !hvm_irq_dpci->hvm_timer)
         {
             spin_unlock(&d->event_lock);
             free_hvm_irq_dpci(hvm_irq_dpci);
@@ -136,6 +137,8 @@ int pt_irq_create_bind_vtd(
                d->nr_pirqs * sizeof(*hvm_irq_dpci->mirq));
         bitmap_zero(hvm_irq_dpci->dirq_mask, d->nr_pirqs);
         bitmap_zero(hvm_irq_dpci->mapping, d->nr_pirqs);
+        memset(hvm_irq_dpci->hvm_timer, 0, 
+                nr_irqs * sizeof(*hvm_irq_dpci->hvm_timer));
         for ( int i = 0; i < d->nr_pirqs; i++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->mirq[i].digl_list);
         for ( int i = 0; i < NR_HVM_IRQS; i++ )
@@ -236,7 +239,7 @@ int pt_irq_create_bind_vtd(
         /* Bind the same mirq once in the same domain */
         if ( !test_and_set_bit(machine_gsi, hvm_irq_dpci->mapping))
         {
-            unsigned int vector = domain_irq_to_vector(d, machine_gsi);
+            unsigned int irq = domain_pirq_to_irq(d, machine_gsi);
             unsigned int share;
 
             hvm_irq_dpci->mirq[machine_gsi].dom = d;
@@ -256,14 +259,14 @@ int pt_irq_create_bind_vtd(
 
             /* Init timer before binding */
             if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
-                init_timer(&hvm_irq_dpci->hvm_timer[vector],
+                init_timer(&hvm_irq_dpci->hvm_timer[irq],
                            pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 
0);
             /* Deal with gsi for legacy devices */
             rc = pirq_guest_bind(d->vcpu[0], machine_gsi, share);
             if ( unlikely(rc) )
             {
                 if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
-                    kill_timer(&hvm_irq_dpci->hvm_timer[vector]);
+                    kill_timer(&hvm_irq_dpci->hvm_timer[irq]);
                 hvm_irq_dpci->mirq[machine_gsi].dom = NULL;
                 clear_bit(machine_gsi, hvm_irq_dpci->mapping);
                 list_del(&girq->list);
@@ -349,7 +352,7 @@ int pt_irq_destroy_bind_vtd(
             pirq_guest_unbind(d, machine_gsi);
             msixtbl_pt_unregister(d, machine_gsi);
             if ( pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
-                kill_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, 
machine_gsi)]);
+                kill_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, 
machine_gsi)]);
             hvm_irq_dpci->mirq[machine_gsi].dom   = NULL;
             hvm_irq_dpci->mirq[machine_gsi].flags = 0;
             clear_bit(machine_gsi, hvm_irq_dpci->mapping);
@@ -357,7 +360,7 @@ int pt_irq_destroy_bind_vtd(
     }
     spin_unlock(&d->event_lock);
     gdprintk(XENLOG_INFO,
-             "XEN_DOMCTL_irq_unmapping: m_irq = %x device = %x intx = %x\n",
+             "XEN_DOMCTL_irq_unmapping: m_irq = 0x%x device = 0x%x intx = 
0x%x\n",
              machine_gsi, device, intx);
 
     return 0;
@@ -367,7 +370,7 @@ int hvm_do_IRQ_dpci(struct domain *d, un
 {
     struct hvm_irq_dpci *dpci = domain_get_irq_dpci(d);
 
-    ASSERT(spin_is_locked(&irq_desc[domain_irq_to_vector(d, mirq)].lock));
+    ASSERT(spin_is_locked(&irq_desc[domain_pirq_to_irq(d, mirq)].lock));
     if ( !iommu_enabled || (d == dom0) || !dpci ||
          !test_bit(mirq, dpci->mapping))
         return 0;
@@ -425,7 +428,7 @@ static int hvm_pci_msi_assert(struct dom
 
 static void hvm_dirq_assist(unsigned long _d)
 {
-    unsigned int irq;
+    unsigned int pirq;
     uint32_t device, intx;
     struct domain *d = (struct domain *)_d;
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
@@ -433,34 +436,34 @@ static void hvm_dirq_assist(unsigned lon
 
     ASSERT(hvm_irq_dpci);
 
-    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs);
-          irq < d->nr_pirqs;
-          irq = find_next_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs, irq + 1) )
-    {
-        if ( !test_and_clear_bit(irq, hvm_irq_dpci->dirq_mask) )
+    for ( pirq = find_first_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs);
+          pirq < d->nr_pirqs;
+          pirq = find_next_bit(hvm_irq_dpci->dirq_mask, d->nr_pirqs, pirq + 1) 
)
+    {
+        if ( !test_and_clear_bit(pirq, hvm_irq_dpci->dirq_mask) )
             continue;
 
         spin_lock(&d->event_lock);
 #ifdef SUPPORT_MSI_REMAPPING
-        if ( hvm_irq_dpci->mirq[irq].flags & HVM_IRQ_DPCI_GUEST_MSI )
-        {
-            hvm_pci_msi_assert(d, irq);
+        if ( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_GUEST_MSI )
+        {
+            hvm_pci_msi_assert(d, pirq);
             spin_unlock(&d->event_lock);
             continue;
         }
 #endif
-        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
+        list_for_each_entry ( digl, &hvm_irq_dpci->mirq[pirq].digl_list, list )
         {
             device = digl->device;
             intx = digl->intx;
             hvm_pci_intx_assert(d, device, intx);
-            hvm_irq_dpci->mirq[irq].pending++;
+            hvm_irq_dpci->mirq[pirq].pending++;
 
 #ifdef SUPPORT_MSI_REMAPPING
-            if ( hvm_irq_dpci->mirq[irq].flags & HVM_IRQ_DPCI_TRANSLATE )
+            if ( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_TRANSLATE )
             {
                 /* for translated MSI to INTx interrupt, eoi as early as 
possible */
-                __msi_pirq_eoi(d, irq);
+                __msi_pirq_eoi(d, pirq);
             }
 #endif
         }
@@ -472,8 +475,8 @@ static void hvm_dirq_assist(unsigned lon
          * guest will never deal with the irq, then the physical interrupt line
          * will never be deasserted.
          */
-        if ( pt_irq_need_timer(hvm_irq_dpci->mirq[irq].flags) )
-            set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
+        if ( pt_irq_need_timer(hvm_irq_dpci->mirq[pirq].flags) )
+            set_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, pirq)],
                       NOW() + PT_IRQ_TIME_OUT);
         spin_unlock(&d->event_lock);
     }
@@ -501,7 +504,7 @@ static void __hvm_dpci_eoi(struct domain
          ! pt_irq_need_timer(hvm_irq_dpci->mirq[machine_gsi].flags) )
         return;
 
-    stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, machine_gsi)]);
+    stop_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, machine_gsi)]);
     pirq_guest_eoi(d, machine_gsi);
 }
 
diff -r 1afd9142eed3 -r 722c7e94e764 xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/drivers/passthrough/pci.c     Wed Aug 19 12:53:04 2009 +0100
@@ -216,7 +216,7 @@ static void pci_clean_dpci_irqs(struct d
               i = find_next_bit(hvm_irq_dpci->mapping, d->nr_pirqs, i + 1) )
         {
             pirq_guest_unbind(d, i);
-            kill_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, i)]);
+            kill_timer(&hvm_irq_dpci->hvm_timer[domain_pirq_to_irq(d, i)]);
 
             list_for_each_safe ( digl_list, tmp,
                                  &hvm_irq_dpci->mirq[i].digl_list )
@@ -408,7 +408,7 @@ static void dump_pci_devices(unsigned ch
                pdev->bus, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn),
                pdev->domain ? pdev->domain->domain_id : -1);
         list_for_each_entry ( msi, &pdev->msi_list, list )
-               printk("%d ", msi->vector);
+               printk("%d ", msi->irq);
         printk(">\n");
     }
 
diff -r 1afd9142eed3 -r 722c7e94e764 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c       Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c       Wed Aug 19 12:53:04 2009 +0100
@@ -31,6 +31,8 @@
 #include <xen/pci_regs.h>
 #include <xen/keyhandler.h>
 #include <asm/msi.h>
+#include <asm/irq.h>
+#include <mach_apic.h>
 #include "iommu.h"
 #include "dmar.h"
 #include "extern.h"
@@ -659,7 +661,7 @@ static void iommu_disable_translation(st
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
-static struct iommu *vector_to_iommu[NR_VECTORS];
+static struct iommu **irq_to_iommu;
 static int iommu_page_fault_do_one(struct iommu *iommu, int type,
                                    u8 fault_reason, u16 source_id, u64 addr)
 {
@@ -705,7 +707,7 @@ static void iommu_fault_status(u32 fault
 }
 
 #define PRIMARY_FAULT_REG_LEN (16)
-static void iommu_page_fault(int vector, void *dev_id,
+static void iommu_page_fault(int irq, void *dev_id,
                              struct cpu_user_regs *regs)
 {
     struct iommu *iommu = dev_id;
@@ -777,9 +779,9 @@ clear_overflow:
     }
 }
 
-static void dma_msi_unmask(unsigned int vector)
-{
-    struct iommu *iommu = vector_to_iommu[vector];
+static void dma_msi_unmask(unsigned int irq)
+{
+    struct iommu *iommu = irq_to_iommu[irq];
     unsigned long flags;
 
     /* unmask it */
@@ -788,10 +790,10 @@ static void dma_msi_unmask(unsigned int 
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
-static void dma_msi_mask(unsigned int vector)
+static void dma_msi_mask(unsigned int irq)
 {
     unsigned long flags;
-    struct iommu *iommu = vector_to_iommu[vector];
+    struct iommu *iommu = irq_to_iommu[irq];
 
     /* mask it */
     spin_lock_irqsave(&iommu->register_lock, flags);
@@ -799,22 +801,23 @@ static void dma_msi_mask(unsigned int ve
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
-static unsigned int dma_msi_startup(unsigned int vector)
-{
-    dma_msi_unmask(vector);
+static unsigned int dma_msi_startup(unsigned int irq)
+{
+    dma_msi_unmask(irq);
     return 0;
 }
 
-static void dma_msi_end(unsigned int vector)
-{
-    dma_msi_unmask(vector);
+static void dma_msi_end(unsigned int irq)
+{
+    dma_msi_unmask(irq);
     ack_APIC_irq();
 }
 
-static void dma_msi_data_init(struct iommu *iommu, int vector)
+static void dma_msi_data_init(struct iommu *iommu, int irq)
 {
     u32 msi_data = 0;
     unsigned long flags;
+    int vector = irq_to_vector(irq);
 
     /* Fixed, edge, assert mode. Follow MSI setting */
     msi_data |= vector & 0xff;
@@ -842,9 +845,9 @@ static void dma_msi_addr_init(struct iom
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
 
-static void dma_msi_set_affinity(unsigned int vector, cpumask_t dest)
-{
-    struct iommu *iommu = vector_to_iommu[vector];
+static void dma_msi_set_affinity(unsigned int irq, cpumask_t dest)
+{
+    struct iommu *iommu = irq_to_iommu[irq];
     dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(dest)));
 }
 
@@ -861,31 +864,28 @@ static struct hw_interrupt_type dma_msi_
 
 static int iommu_set_interrupt(struct iommu *iommu)
 {
-    int vector, ret;
-
-    vector = assign_irq_vector(AUTO_ASSIGN_IRQ);
-    if ( vector <= 0 )
-    {
-        gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n");
+    int irq, ret;
+
+    irq = create_irq();
+    if ( irq <= 0 )
+    {
+        gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no irq available!\n");
         return -EINVAL;
     }
 
-    irq_desc[vector].handler = &dma_msi_type;
-    vector_to_iommu[vector] = iommu;
-    ret = request_irq_vector(vector, iommu_page_fault, 0, "dmar", iommu);
+    irq_desc[irq].handler = &dma_msi_type;
+    irq_to_iommu[irq] = iommu;
+    ret = request_irq(irq, iommu_page_fault, 0, "dmar", iommu);
     if ( ret )
     {
-        irq_desc[vector].handler = &no_irq_type;
-        vector_to_iommu[vector] = NULL;
-        free_irq_vector(vector);
+        irq_desc[irq].handler = &no_irq_type;
+        irq_to_iommu[irq] = NULL;
+        destroy_irq(irq);
         gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: can't request irq\n");
         return ret;
     }
 
-    /* Make sure that vector is never re-used. */
-    vector_irq[vector] = NEVER_ASSIGN_IRQ;
-
-    return vector;
+    return irq;
 }
 
 static int iommu_alloc(struct acpi_drhd_unit *drhd)
@@ -906,7 +906,7 @@ static int iommu_alloc(struct acpi_drhd_
         return -ENOMEM;
     memset(iommu, 0, sizeof(struct iommu));
 
-    iommu->vector = -1; /* No vector assigned yet. */
+    iommu->irq = -1; /* No irq assigned yet. */
 
     iommu->intel = alloc_intel_iommu();
     if ( iommu->intel == NULL )
@@ -966,7 +966,7 @@ static void iommu_free(struct acpi_drhd_
         iounmap(iommu->reg);
 
     free_intel_iommu(iommu->intel);
-    release_irq_vector(iommu->vector);
+    destroy_irq(iommu->irq);
     xfree(iommu);
 
     drhd->iommu = NULL;
@@ -1581,24 +1581,24 @@ static int init_vtd_hw(void)
     struct acpi_drhd_unit *drhd;
     struct iommu *iommu;
     struct iommu_flush *flush = NULL;
-    int vector;
+    int irq = -1;
     int ret;
     unsigned long flags;
 
     for_each_drhd_unit ( drhd )
     {
         iommu = drhd->iommu;
-        if ( iommu->vector < 0 )
-        {
-            vector = iommu_set_interrupt(iommu);
-            if ( vector < 0 )
+        if ( iommu->irq < 0 )
+        {
+            irq = iommu_set_interrupt(iommu);
+            if ( irq < 0 )
             {
                 gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup 
failed\n");
-                return vector;
+                return irq;
             }
-            iommu->vector = vector;
-        }
-        dma_msi_data_init(iommu, iommu->vector);
+            iommu->irq = irq;
+        }
+        dma_msi_data_init(iommu, iommu->irq);
         dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map)));
         clear_fault_bits(iommu);
 
@@ -1702,6 +1702,13 @@ int intel_vtd_setup(void)
 
     spin_lock_init(&domid_bitmap_lock);
     clflush_size = get_cache_line_size();
+
+    irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs);
+    BUG_ON(!irq_to_iommu);
+    memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*));
+
+    if(!irq_to_iommu)
+        return -ENOMEM;
 
     /* We enable the following features only if they are supported by all VT-d
      * engines: Snoop Control, DMA passthrough, Queued Invalidation and
diff -r 1afd9142eed3 -r 722c7e94e764 xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c     Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c     Wed Aug 19 12:53:04 2009 +0100
@@ -121,7 +121,7 @@ void hvm_dpci_isairq_eoi(struct domain *
                 hvm_pci_intx_deassert(d, digl->device, digl->intx);
                 if ( --dpci->mirq[i].pending == 0 )
                 {
-                    stop_timer(&dpci->hvm_timer[domain_irq_to_vector(d, i)]);
+                    stop_timer(&dpci->hvm_timer[domain_pirq_to_irq(d, i)]);
                     pirq_guest_eoi(d, i);
                 }
             }
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/asm-x86/amd-iommu.h
--- a/xen/include/asm-x86/amd-iommu.h   Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/asm-x86/amd-iommu.h   Wed Aug 19 12:53:04 2009 +0100
@@ -79,7 +79,7 @@ struct amd_iommu {
     int maskbit;
 
     int enabled;
-    int vector;
+    int irq;
 };
 
 struct ivrs_mappings {
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/asm-x86/domain.h      Wed Aug 19 12:53:04 2009 +0100
@@ -262,9 +262,9 @@ struct arch_domain
     /* Shadow translated domain: P2M mapping */
     pagetable_t phys_table;
 
-    /* NB. protected by d->event_lock and by irq_desc[vector].lock */
-    int vector_pirq[NR_VECTORS];
-    s16 *pirq_vector;
+    /* NB. protected by d->event_lock and by irq_desc[irq].lock */
+    int *irq_pirq;
+    int *pirq_irq;
 
     /* Shared page for notifying that explicit PIRQ EOI is required. */
     unsigned long *pirq_eoi_map;
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/asm-x86/irq.h Wed Aug 19 12:53:04 2009 +0100
@@ -7,19 +7,25 @@
 #include <asm/atomic.h>
 #include <irq_vectors.h>
 
-#define IO_APIC_IRQ(irq)    (((irq) >= 16) || ((1<<(irq)) & io_apic_irqs))
+#define IO_APIC_IRQ(irq)    (((irq) >= 16 && (irq) < nr_irqs_gsi) \
+        || (((irq) < 16) && (1<<(irq)) & io_apic_irqs))
 #define IO_APIC_VECTOR(irq) (irq_vector[irq])
+
+#define MSI_IRQ(irq)       ((irq) >= nr_irqs_gsi && (irq) < nr_irqs)
 
 #define LEGACY_VECTOR(irq)          ((irq) + FIRST_LEGACY_VECTOR)
 #define LEGACY_IRQ_FROM_VECTOR(vec) ((vec) - FIRST_LEGACY_VECTOR)
 
-#define irq_to_vector(irq)  \
-    (IO_APIC_IRQ(irq) ? IO_APIC_VECTOR(irq) : LEGACY_VECTOR(irq))
 #define vector_to_irq(vec)  (vector_irq[vec])
+#define irq_to_desc(irq)    &irq_desc[(irq)]
+
+#define MAX_GSI_IRQS PAGE_SIZE * 8
+#define MAX_NR_IRQS (2 * MAX_GSI_IRQS)
 
 extern int vector_irq[NR_VECTORS];
 extern u8 *irq_vector;
 
+extern int irq_to_vector(int irq);
 #define platform_legacy_irq(irq)       ((irq) < 16)
 
 fastcall void event_check_interrupt(void);
@@ -51,17 +57,21 @@ extern atomic_t irq_mis_count;
 
 int pirq_shared(struct domain *d , int irq);
 
-int map_domain_pirq(struct domain *d, int pirq, int vector, int type,
+int map_domain_pirq(struct domain *d, int pirq, int irq, int type,
                            void *data);
 int unmap_domain_pirq(struct domain *d, int pirq);
 int get_free_pirq(struct domain *d, int type, int index);
 void free_domain_pirqs(struct domain *d);
 
-#define domain_irq_to_vector(d, irq) ((d)->arch.pirq_vector[irq] ?: \
-                                      IO_APIC_IRQ(irq) ? 0 : 
LEGACY_VECTOR(irq))
-#define domain_vector_to_irq(d, vec) ((d)->arch.vector_pirq[vec] ?: \
-                                      ((vec) < FIRST_LEGACY_VECTOR || \
-                                       (vec) > LAST_LEGACY_VECTOR) ? \
-                                      0 : LEGACY_IRQ_FROM_VECTOR(vec))
+int  init_irq_data(void);
+
+void clear_irq_vector(int irq);
+int __assign_irq_vector(int irq);
+
+int create_irq(void);
+void destroy_irq(unsigned int irq);
+
+#define domain_pirq_to_irq(d, pirq) ((d)->arch.pirq_irq[pirq])
+#define domain_irq_to_pirq(d, irq) ((d)->arch.irq_pirq[irq])
 
 #endif /* _ASM_HW_IRQ_H */
diff -r 1afd9142eed3 -r 722c7e94e764 
xen/include/asm-x86/mach-default/irq_vectors.h
--- a/xen/include/asm-x86/mach-default/irq_vectors.h    Wed Aug 19 12:52:38 
2009 +0100
+++ b/xen/include/asm-x86/mach-default/irq_vectors.h    Wed Aug 19 12:53:04 
2009 +0100
@@ -23,6 +23,7 @@
 #define LAST_LEGACY_VECTOR      0xef
 
 #define HYPERCALL_VECTOR       0x82
+#define LEGACY_SYSCALL_VECTOR   0x80
 
 /* Dynamically-allocated vectors available to any driver. */
 #define FIRST_DYNAMIC_VECTOR   0x20
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/asm-x86/msi.h
--- a/xen/include/asm-x86/msi.h Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/asm-x86/msi.h Wed Aug 19 12:53:04 2009 +0100
@@ -2,7 +2,6 @@
 #define __ASM_MSI_H
 
 #include <xen/cpumask.h>
-#include <asm/irq.h>
 /*
  * Constants for Intel APIC based MSI messages.
  */
@@ -57,7 +56,7 @@ struct msi_info {
 struct msi_info {
     int bus;
     int devfn;
-    int vector;
+    int irq;
     int entry_nr;
     uint64_t table_base;
 };
@@ -70,14 +69,14 @@ struct msi_msg {
 
 struct msi_desc;
 /* Helper functions */
-extern void mask_msi_vector(unsigned int vector);
-extern void unmask_msi_vector(unsigned int vector);
+extern void mask_msi_irq(unsigned int irq);
+extern void unmask_msi_irq(unsigned int irq);
 extern void set_msi_affinity(unsigned int vector, cpumask_t mask);
 extern int pci_enable_msi(struct msi_info *msi, struct msi_desc **desc);
 extern void pci_disable_msi(struct msi_desc *desc);
 extern void pci_cleanup_msi(struct pci_dev *pdev);
-extern int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
-extern void teardown_msi_vector(int vector);
+extern int setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc, int irq);
+extern void teardown_msi_irq(int irq);
 extern int msi_free_vector(struct msi_desc *entry);
 extern int pci_restore_msi_state(struct pci_dev *pdev);
 
@@ -97,7 +96,7 @@ struct msi_desc {
 
        void __iomem *mask_base;        /* va for the entry in mask table */
        struct pci_dev *dev;
-       int vector;
+       int irq;
 
        struct msi_msg msg;             /* Last set MSI message */
 
@@ -105,6 +104,7 @@ struct msi_desc {
 };
 
 int msi_maskable_irq(const struct msi_desc *);
+int msi_free_irq(struct msi_desc *entry);
 
 /*
  * Assume the maximum number of hot plug slots supported by the system is about
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/xen/hvm/irq.h
--- a/xen/include/xen/hvm/irq.h Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/xen/hvm/irq.h Wed Aug 19 12:53:04 2009 +0100
@@ -88,7 +88,7 @@ struct hvm_irq_dpci {
     DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
     /* Record of mapped Links */
     uint8_t link_cnt[NR_LINK];
-    struct timer hvm_timer[NR_VECTORS];
+    struct timer *hvm_timer;
     struct tasklet dirq_tasklet;
 };
 
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h   Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/xen/iommu.h   Wed Aug 19 12:53:04 2009 +0100
@@ -53,7 +53,7 @@ struct iommu {
     spinlock_t lock; /* protect context, domain ids */
     spinlock_t register_lock; /* protect iommu register handling */
     u64 root_maddr; /* root entry machine address */
-    int vector;
+    int irq;
     struct intel_iommu *intel;
 };
 
diff -r 1afd9142eed3 -r 722c7e94e764 xen/include/xen/irq.h
--- a/xen/include/xen/irq.h     Wed Aug 19 12:52:38 2009 +0100
+++ b/xen/include/xen/irq.h     Wed Aug 19 12:53:04 2009 +0100
@@ -53,6 +53,7 @@ typedef struct hw_interrupt_type hw_irq_
 # define nr_irqs_gsi NR_IRQS
 #else
 extern unsigned int nr_irqs_gsi;
+extern unsigned int nr_irqs;
 #endif
 
 struct msi_desc;
@@ -63,23 +64,19 @@ struct msi_desc;
  *
  * Pad this out to 32 bytes for cache and indexing reasons.
  */
-typedef struct {
+typedef struct irq_desc{
     unsigned int status;               /* IRQ status */
     hw_irq_controller *handler;
     struct msi_desc   *msi_desc;
     struct irqaction *action;  /* IRQ action list */
     unsigned int depth;                /* nested irq disables */
+    int irq;
     spinlock_t lock;
     cpumask_t affinity;
 } __cacheline_aligned irq_desc_t;
 
+#ifndef CONFIG_X86
 extern irq_desc_t irq_desc[NR_VECTORS];
-
-extern int setup_irq_vector(unsigned int, struct irqaction *);
-extern void release_irq_vector(unsigned int);
-extern int request_irq_vector(unsigned int vector,
-               void (*handler)(int, void *, struct cpu_user_regs *),
-               unsigned long irqflags, const char * devname, void *dev_id);
 
 #define setup_irq(irq, action) \
     setup_irq_vector(irq_to_vector(irq), action)
@@ -89,6 +86,16 @@ extern int request_irq_vector(unsigned i
 
 #define request_irq(irq, handler, irqflags, devname, devid) \
     request_irq_vector(irq_to_vector(irq), handler, irqflags, devname, devid)
+
+#else
+extern struct irq_desc *irq_desc;
+
+extern int setup_irq(unsigned int irq, struct irqaction *);
+extern void release_irq(unsigned int irq);
+extern int request_irq(unsigned int irq,
+               void (*handler)(int, void *, struct cpu_user_regs *),
+               unsigned long irqflags, const char * devname, void *dev_id);
+#endif
 
 extern hw_irq_controller no_irq_type;
 extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs);
@@ -102,16 +109,18 @@ extern irq_desc_t *domain_spin_lock_irq_
 extern irq_desc_t *domain_spin_lock_irq_desc(
     struct domain *d, int irq, unsigned long *pflags);
 
-static inline void set_native_irq_info(unsigned int vector, cpumask_t mask)
+static inline void set_native_irq_info(unsigned int irq, cpumask_t mask)
 {
-    irq_desc[vector].affinity = mask;
+    irq_desc[irq].affinity = mask;
 }
 
-#ifdef irq_to_vector
 static inline void set_irq_info(int irq, cpumask_t mask)
 {
+#ifdef CONFIG_X86
+    set_native_irq_info(irq, mask);
+#else
     set_native_irq_info(irq_to_vector(irq), mask);
+#endif
 }
-#endif
 
 #endif /* __XEN_IRQ_H__ */

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.