WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-changelog

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

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: Change Xen hypervisor's interrupt infrastructure
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 19 Aug 2009 07:40:12 -0700
Delivery-date: Wed, 19 Aug 2009 07:43:07 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-changelog-request@lists.xensource.com?subject=help>
List-id: BK change log <xen-changelog.lists.xensource.com>
List-post: <mailto:xen-changelog@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-changelog>, <mailto:xen-changelog-request@lists.xensource.com?subject=unsubscribe>
Reply-to: xen-devel@xxxxxxxxxxxxxxxxxxx
Sender: xen-changelog-bounces@xxxxxxxxxxxxxxxxxxx
# 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

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-changelog] [xen-unstable] x86: Change Xen hypervisor's interrupt infrastructure, Xen patchbot-unstable <=