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: eliminate hard-coded NR_IRQS

To: xen-changelog@xxxxxxxxxxxxxxxxxxx
Subject: [Xen-changelog] [xen-unstable] x86: eliminate hard-coded NR_IRQS
From: Xen patchbot-unstable <patchbot-unstable@xxxxxxxxxxxxxxxxxxx>
Date: Wed, 27 May 2009 04:30:47 -0700
Delivery-date: Wed, 27 May 2009 04:32:22 -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 1243417131 -3600
# Node ID 6705898f768d57fa44588cc061ac88e8045fb434
# Parent  fcc71d02340809901b656eb4134383f36a7c7875
x86: eliminate hard-coded NR_IRQS

... splitting it into global nr_irqs (determined at boot time) and
per- domain nr_pirqs (derived from nr_irqs and a possibly command line
specified value, which probably should later become a per-domain
config setting).

This has the (desirable imo) side effect of reducing the size of
struct hvm_irq_dpci from requiring an order-3 page to order-2 (on
x86-64), which nevertheless still is too large.

However, there is now a variable size bit array on the stack in
pt_irq_time_out() - while for the moment this probably is okay, it
certainly doesn't look nice. However, replacing this with a static
(pre-)allocation also seems less than ideal, because that would
require at least min(d->nr_pirqs, NR_VECTORS) bit arrays of
d->nr_pirqs bits, since this bit array is used outside of the
serialized code region in that function, and keeping the domain's
event lock acquired across pirq_guest_eoi() doesn't look like a good
idea either.

The IRQ- and vector-indexed arrays hanging off struct hvm_irq_dpci
could in fact be changed further to dynamically use the smaller of the
two ranges for indexing, since there are other assumptions about a
one-to-one relationship between IRQs and vectors here and elsewhere.

Additionally, it seems to me that struct hvm_mirq_dpci_mapping's
digl_list and gmsi fields could really be overlayed, which would yield
significant savings since this structure gets always instanciated in
form of d->nr_pirqs (as per the above could also be the smaller of
this and NR_VECTORS) dimensioned arrays.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxxxx>
---
 xen/arch/x86/apic.c                   |   30 ------------
 xen/arch/x86/domain.c                 |    8 +++
 xen/arch/x86/domain_build.c           |    2 
 xen/arch/x86/i8259.c                  |    3 +
 xen/arch/x86/io_apic.c                |   85 +++++++++++++++++++++++++---------
 xen/arch/x86/irq.c                    |   27 +++++-----
 xen/arch/x86/physdev.c                |   10 +---
 xen/common/domain.c                   |   25 ++++++++++
 xen/common/domctl.c                   |    8 +--
 xen/common/event_channel.c            |    2 
 xen/drivers/passthrough/io.c          |   62 +++++++++++++++++-------
 xen/drivers/passthrough/pci.c         |    8 +--
 xen/drivers/passthrough/vtd/x86/vtd.c |    6 +-
 xen/include/asm-x86/config.h          |    6 --
 xen/include/asm-x86/domain.h          |    2 
 xen/include/asm-x86/io_apic.h         |    3 +
 xen/include/asm-x86/irq.h             |    2 
 xen/include/xen/hvm/irq.h             |   17 ++++--
 xen/include/xen/iommu.h               |    1 
 xen/include/xen/irq.h                 |    6 ++
 xen/include/xen/sched.h               |    5 +-
 21 files changed, 201 insertions(+), 117 deletions(-)

diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/apic.c       Wed May 27 10:38:51 2009 +0100
@@ -890,35 +890,7 @@ __next:
     if (boot_cpu_physical_apicid == -1U)
         boot_cpu_physical_apicid = get_apic_id();
 
-#ifdef CONFIG_X86_IO_APIC
-    {
-        unsigned long ioapic_phys, idx = FIX_IO_APIC_BASE_0;
-        int i;
-
-        for (i = 0; i < nr_ioapics; i++) {
-            if (smp_found_config) {
-                ioapic_phys = mp_ioapics[i].mpc_apicaddr;
-                if (!ioapic_phys) {
-                    printk(KERN_ERR
-                           "WARNING: bogus zero IO-APIC "
-                           "address found in MPTABLE, "
-                           "disabling IO/APIC support!\n");
-                    smp_found_config = 0;
-                    skip_ioapic_setup = 1;
-                    goto fake_ioapic_page;
-                }
-            } else {
-fake_ioapic_page:
-                ioapic_phys = __pa(alloc_xenheap_page());
-                clear_page(__va(ioapic_phys));
-            }
-            set_fixmap_nocache(idx, ioapic_phys);
-            apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
-                        __fix_to_virt(idx), ioapic_phys);
-            idx++;
-        }
-    }
-#endif
+    init_ioapic_mappings();
 }
 
 /*****************************************************************************
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/domain.c
--- a/xen/arch/x86/domain.c     Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/domain.c     Wed May 27 10:38:51 2009 +0100
@@ -454,6 +454,12 @@ 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 )
+            goto fail;
+        memset(d->arch.pirq_vector, 0,
+               d->nr_pirqs * sizeof(*d->arch.pirq_vector));
+
         if ( (rc = iommu_domain_init(d)) != 0 )
             goto fail;
 
@@ -488,6 +494,7 @@ int arch_domain_create(struct domain *d,
 
  fail:
     d->is_dying = DOMDYING_dead;
+    xfree(d->arch.pirq_vector);
     free_xenheap_page(d->shared_info);
     if ( paging_initialised )
         paging_final_teardown(d);
@@ -523,6 +530,7 @@ void arch_domain_destroy(struct domain *
 #endif
 
     free_xenheap_page(d->shared_info);
+    xfree(d->arch.pirq_vector);
 }
 
 unsigned long pv_guest_cr4_fixup(unsigned long guest_cr4)
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/domain_build.c
--- a/xen/arch/x86/domain_build.c       Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/domain_build.c       Wed May 27 10:38:51 2009 +0100
@@ -1000,7 +1000,7 @@ int __init construct_dom0(
     /* DOM0 is permitted full I/O capabilities. */
     rc |= ioports_permit_access(dom0, 0, 0xFFFF);
     rc |= iomem_permit_access(dom0, 0UL, ~0UL);
-    rc |= irqs_permit_access(dom0, 0, NR_IRQS-1);
+    rc |= irqs_permit_access(dom0, 0, d->nr_pirqs - 1);
 
     /*
      * Modify I/O port access permissions.
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c      Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/i8259.c      Wed May 27 10:38:51 2009 +0100
@@ -403,6 +403,9 @@ void __init init_IRQ(void)
             set_intr_gate(i, interrupt[i]);
     }
 
+    irq_vector = xmalloc_array(u8, nr_irqs);
+    memset(irq_vector, 0, nr_irqs * sizeof(*irq_vector));
+
     for ( i = 0; i < 16; i++ )
     {
         vector_irq[LEGACY_VECTOR(i)] = i;
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c    Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/io_apic.c    Wed May 27 10:38:51 2009 +0100
@@ -71,8 +71,8 @@ int disable_timer_pin_1 __initdata;
  * Rough estimation of how many shared IRQs there are, can
  * be changed anytime.
  */
-#define MAX_PLUS_SHARED_IRQS NR_IRQS
-#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + NR_IRQS)
+#define MAX_PLUS_SHARED_IRQS nr_irqs
+#define PIN_MAP_SIZE (MAX_PLUS_SHARED_IRQS + nr_irqs)
 
 /*
  * This is performance-critical, we want to do it O(1)
@@ -82,11 +82,10 @@ int disable_timer_pin_1 __initdata;
  */
 
 static struct irq_pin_list {
-    int apic, pin, next;
-} irq_2_pin[PIN_MAP_SIZE] = {
-    [0 ... PIN_MAP_SIZE-1].pin = -1
-};
-static int irq_2_pin_free_entry = NR_IRQS;
+    int apic, pin;
+    unsigned int next;
+} *irq_2_pin;
+static unsigned int irq_2_pin_free_entry;
 
 /*
  * The common case is 1:1 IRQ<->pin mappings. Sometimes there are
@@ -663,7 +662,7 @@ static inline int IO_APIC_irq_trigger(in
 }
 
 /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQS] __read_mostly;
+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;
@@ -929,7 +928,7 @@ void /*__init*/ __print_IO_APIC(void)
     }
     printk(KERN_INFO "Using vector-based indexing\n");
     printk(KERN_DEBUG "IRQ to pin mappings:\n");
-    for (i = 0; i < NR_IRQS; i++) {
+    for (i = 0; i < nr_irqs; i++) {
         struct irq_pin_list *entry = irq_2_pin + i;
         if (entry->pin < 0)
             continue;
@@ -961,24 +960,16 @@ void print_IO_APIC_keyhandler(unsigned c
 
 static void __init enable_IO_APIC(void)
 {
-    union IO_APIC_reg_01 reg_01;
     int i8259_apic, i8259_pin;
     int i, apic;
     unsigned long flags;
 
     /* Initialise dynamic irq_2_pin free list. */
-    for (i = NR_IRQS; i < PIN_MAP_SIZE; i++)
+    irq_2_pin = xmalloc_array(struct irq_pin_list, PIN_MAP_SIZE);
+    memset(irq_2_pin, 0, nr_irqs * sizeof(*irq_2_pin));
+    for (i = irq_2_pin_free_entry = nr_irqs; i < PIN_MAP_SIZE; i++)
         irq_2_pin[i].next = i + 1;
 
-    /*
-     * The number of IO-APIC IRQ registers (== #pins):
-     */
-    for (apic = 0; apic < nr_ioapics; apic++) {
-        spin_lock_irqsave(&ioapic_lock, flags);
-        reg_01.raw = io_apic_read(apic, 1);
-        spin_unlock_irqrestore(&ioapic_lock, flags);
-        nr_ioapic_registers[apic] = reg_01.bits.entries+1;
-    }
     for(apic = 0; apic < nr_ioapics; apic++) {
         int pin;
         /* See if any of the pins is in ExtINT mode */
@@ -2174,7 +2165,7 @@ void dump_ioapic_irq_info(void)
     unsigned int irq, pin, printed = 0;
     unsigned long flags;
 
-    for ( irq = 0; irq < NR_IRQS; irq++ )
+    for ( irq = 0; irq < nr_irqs; irq++ )
     {
         entry = &irq_2_pin[irq];
         if ( entry->pin == -1 )
@@ -2210,3 +2201,55 @@ void dump_ioapic_irq_info(void)
         }
     }
 }
+
+void __init init_ioapic_mappings(void)
+{
+    unsigned long ioapic_phys;
+    unsigned int i, idx = FIX_IO_APIC_BASE_0;
+    union IO_APIC_reg_01 reg_01;
+
+    if ( smp_found_config )
+        nr_irqs = 0;
+    for ( i = 0; i < nr_ioapics; i++ )
+    {
+        if ( smp_found_config )
+        {
+            ioapic_phys = mp_ioapics[i].mpc_apicaddr;
+            if ( !ioapic_phys )
+            {
+                printk(KERN_ERR "WARNING: bogus zero IO-APIC address "
+                       "found in MPTABLE, disabling IO/APIC support!\n");
+                smp_found_config = 0;
+                skip_ioapic_setup = 1;
+                goto fake_ioapic_page;
+            }
+        }
+        else
+        {
+ fake_ioapic_page:
+            ioapic_phys = __pa(alloc_xenheap_page());
+            clear_page(__va(ioapic_phys));
+        }
+        set_fixmap_nocache(idx, ioapic_phys);
+        apic_printk(APIC_VERBOSE, "mapped IOAPIC to %08lx (%08lx)\n",
+                    __fix_to_virt(idx), ioapic_phys);
+        idx++;
+
+        if ( smp_found_config )
+        {
+            /* The number of IO-APIC IRQ registers (== #pins): */
+            reg_01.raw = io_apic_read(i, 1);
+            nr_ioapic_registers[i] = reg_01.bits.entries + 1;
+            nr_irqs += nr_ioapic_registers[i];
+        }
+    }
+    if ( !smp_found_config || skip_ioapic_setup || nr_irqs < 16 )
+        nr_irqs = 16;
+    else if ( nr_irqs > PAGE_SIZE * 8 )
+    {
+        /* for PHYSDEVOP_pirq_eoi_gmfn guest assumptions */
+        printk(KERN_WARNING "Limiting number of IRQs found (%u) to %lu\n",
+               nr_irqs, PAGE_SIZE * 8);
+        nr_irqs = PAGE_SIZE * 8;
+    }
+}
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/irq.c
--- a/xen/arch/x86/irq.c        Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/irq.c        Wed May 27 10:38:51 2009 +0100
@@ -26,6 +26,7 @@ int opt_noirqbalance = 0;
 int opt_noirqbalance = 0;
 boolean_param("noirqbalance", opt_noirqbalance);
 
+unsigned int __read_mostly nr_irqs = 16;
 irq_desc_t irq_desc[NR_VECTORS];
 
 static DEFINE_SPINLOCK(vector_lock);
@@ -79,7 +80,7 @@ int assign_irq_vector(int irq)
     static unsigned current_vector = FIRST_DYNAMIC_VECTOR;
     unsigned vector;
 
-    BUG_ON(irq >= NR_IRQS);
+    BUG_ON(irq >= nr_irqs && irq != AUTO_ASSIGN_IRQ);
 
     spin_lock(&vector_lock);
 
@@ -526,7 +527,7 @@ static void __pirq_guest_eoi(struct doma
 
 int pirq_guest_eoi(struct domain *d, int irq)
 {
-    if ( (irq < 0) || (irq >= NR_IRQS) )
+    if ( (irq < 0) || (irq >= d->nr_pirqs) )
         return -EINVAL;
 
     __pirq_guest_eoi(d, irq);
@@ -536,11 +537,11 @@ int pirq_guest_eoi(struct domain *d, int
 
 int pirq_guest_unmask(struct domain *d)
 {
-    unsigned int   irq;
-
-    for ( irq = find_first_bit(d->pirq_mask, NR_IRQS);
-          irq < NR_IRQS;
-          irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) )
+    unsigned int irq, nr = d->nr_pirqs;
+
+    for ( irq = find_first_bit(d->pirq_mask, nr);
+          irq < nr;
+          irq = find_next_bit(d->pirq_mask, nr, irq+1) )
     {
         if ( !test_bit(d->pirq_to_evtchn[irq], &shared_info(d, evtchn_mask)) )
             __pirq_guest_eoi(d, irq);
@@ -885,15 +886,15 @@ int get_free_pirq(struct domain *d, int 
 
     if ( type == MAP_PIRQ_TYPE_GSI )
     {
-        for ( i = 16; i < NR_IRQS; i++ )
+        for ( i = 16; i < nr_irqs; i++ )
             if ( !d->arch.pirq_vector[i] )
                 break;
-        if ( i == NR_IRQS )
+        if ( i == nr_irqs )
             return -ENOSPC;
     }
     else
     {
-        for ( i = NR_IRQS - 1; i >= 16; i-- )
+        for ( i = d->nr_pirqs - 1; i >= 16; i-- )
             if ( !d->arch.pirq_vector[i] )
                 break;
         if ( i == 16 )
@@ -919,7 +920,7 @@ int map_domain_pirq(
     if ( !IS_PRIV(current->domain) )
         return -EPERM;
 
-    if ( pirq < 0 || pirq >= NR_IRQS || vector < 0 || vector >= NR_VECTORS )
+    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);
@@ -991,7 +992,7 @@ int unmap_domain_pirq(struct domain *d, 
     bool_t forced_unbind;
     struct msi_desc *msi_desc = NULL;
 
-    if ( (pirq < 0) || (pirq >= NR_IRQS) )
+    if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
 
     if ( !IS_PRIV(current->domain) )
@@ -1063,7 +1064,7 @@ void free_domain_pirqs(struct domain *d)
     spin_lock(&pcidevs_lock);
     spin_lock(&d->event_lock);
 
-    for ( i = 0; i < NR_IRQS; i++ )
+    for ( i = 0; i < d->nr_pirqs; i++ )
         if ( d->arch.pirq_vector[i] > 0 )
             unmap_domain_pirq(d, i);
 
diff -r fcc71d023408 -r 6705898f768d xen/arch/x86/physdev.c
--- a/xen/arch/x86/physdev.c    Wed May 27 08:19:30 2009 +0100
+++ b/xen/arch/x86/physdev.c    Wed May 27 10:38:51 2009 +0100
@@ -55,7 +55,7 @@ static int physdev_map_pirq(struct physd
     switch ( map->type )
     {
         case MAP_PIRQ_TYPE_GSI:
-            if ( map->index < 0 || map->index >= NR_IRQS )
+            if ( map->index < 0 || map->index >= nr_irqs )
             {
                 dprintk(XENLOG_G_ERR, "dom%d: map invalid irq %d\n",
                         d->domain_id, map->index);
@@ -196,7 +196,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
         if ( copy_from_guest(&eoi, arg, 1) != 0 )
             break;
         ret = -EINVAL;
-        if ( eoi.irq < 0 || eoi.irq >= NR_IRQS )
+        if ( eoi.irq < 0 || eoi.irq >= v->domain->nr_pirqs )
             break;
         if ( v->domain->arch.pirq_eoi_map )
             evtchn_unmask(v->domain->pirq_to_evtchn[eoi.irq]);
@@ -207,8 +207,6 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
     case PHYSDEVOP_pirq_eoi_gmfn: {
         struct physdev_pirq_eoi_gmfn info;
         unsigned long mfn;
-
-        BUILD_BUG_ON(NR_IRQS > (PAGE_SIZE * 8));
 
         ret = -EFAULT;
         if ( copy_from_guest(&info, arg, 1) != 0 )
@@ -254,7 +252,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
             break;
         irq = irq_status_query.irq;
         ret = -EINVAL;
-        if ( (irq < 0) || (irq >= NR_IRQS) )
+        if ( (irq < 0) || (irq >= v->domain->nr_pirqs) )
             break;
         irq_status_query.flags = 0;
         /*
@@ -346,7 +344,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_H
 
         irq = irq_op.irq;
         ret = -EINVAL;
-        if ( (irq < 0) || (irq >= NR_IRQS) )
+        if ( (irq < 0) || (irq >= nr_irqs) )
             break;
 
         irq_op.vector = assign_irq_vector(irq);
diff -r fcc71d023408 -r 6705898f768d xen/common/domain.c
--- a/xen/common/domain.c       Wed May 27 08:19:30 2009 +0100
+++ b/xen/common/domain.c       Wed May 27 10:38:51 2009 +0100
@@ -8,6 +8,7 @@
 #include <xen/compat.h>
 #include <xen/init.h>
 #include <xen/lib.h>
+#include <xen/ctype.h>
 #include <xen/errno.h>
 #include <xen/sched.h>
 #include <xen/domain.h>
@@ -198,6 +199,16 @@ struct vcpu *alloc_idle_vcpu(unsigned in
     return v;
 }
 
+static unsigned int extra_dom0_irqs, extra_domU_irqs = 8;
+static void __init parse_extra_guest_irqs(const char *s)
+{
+    if ( isdigit(*s) )
+        extra_domU_irqs = simple_strtoul(s, &s, 0);
+    if ( *s == ',' && isdigit(*++s) )
+        extra_dom0_irqs = simple_strtoul(s, &s, 0);
+}
+custom_param("extra_guest_irqs", parse_extra_guest_irqs);
+
 struct domain *domain_create(
     domid_t domid, unsigned int domcr_flags, ssidref_t ssidref)
 {
@@ -244,9 +255,19 @@ struct domain *domain_create(
         d->is_paused_by_controller = 1;
         atomic_inc(&d->pause_count);
 
+        d->nr_pirqs = nr_irqs +
+                      (domid ? extra_domU_irqs :
+                               extra_dom0_irqs ?: nr_irqs);
         if ( evtchn_init(d) != 0 )
             goto fail;
         init_status |= INIT_evtchn;
+        d->pirq_to_evtchn = xmalloc_array(u16, d->nr_pirqs);
+        d->pirq_mask = xmalloc_array(unsigned long,
+                                     BITS_TO_LONGS(d->nr_pirqs));
+        if ( !d->pirq_to_evtchn || !d->pirq_mask )
+            goto fail;
+        memset(d->pirq_to_evtchn, 0, d->nr_pirqs * sizeof(*d->pirq_to_evtchn));
+        bitmap_zero(d->pirq_mask, d->nr_pirqs);
 
         if ( grant_table_create(d) != 0 )
             goto fail;
@@ -289,7 +310,11 @@ struct domain *domain_create(
     if ( init_status & INIT_gnttab )
         grant_table_destroy(d);
     if ( init_status & INIT_evtchn )
+    {
+        xfree(d->pirq_mask);
+        xfree(d->pirq_to_evtchn);
         evtchn_destroy(d);
+    }
     if ( init_status & INIT_rangeset )
         rangeset_domain_destroy(d);
     if ( init_status & INIT_xsm )
diff -r fcc71d023408 -r 6705898f768d xen/common/domctl.c
--- a/xen/common/domctl.c       Wed May 27 08:19:30 2009 +0100
+++ b/xen/common/domctl.c       Wed May 27 10:38:51 2009 +0100
@@ -774,16 +774,14 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domc
         struct domain *d;
         unsigned int pirq = op->u.irq_permission.pirq;
 
-        ret = -EINVAL;
-        if ( pirq >= NR_IRQS )
-            break;
-
         ret = -ESRCH;
         d = rcu_lock_domain_by_id(op->domain);
         if ( d == NULL )
             break;
 
-        if ( op->u.irq_permission.allow_access )
+        if ( pirq >= d->nr_pirqs )
+            ret = -EINVAL;
+        else if ( op->u.irq_permission.allow_access )
             ret = irq_permit_access(d, pirq);
         else
             ret = irq_deny_access(d, pirq);
diff -r fcc71d023408 -r 6705898f768d xen/common/event_channel.c
--- a/xen/common/event_channel.c        Wed May 27 08:19:30 2009 +0100
+++ b/xen/common/event_channel.c        Wed May 27 10:38:51 2009 +0100
@@ -302,7 +302,7 @@ static long evtchn_bind_pirq(evtchn_bind
     int            port, pirq = bind->pirq;
     long           rc;
 
-    if ( (pirq < 0) || (pirq >= ARRAY_SIZE(d->pirq_to_evtchn)) )
+    if ( (pirq < 0) || (pirq >= d->nr_pirqs) )
         return -EINVAL;
 
     if ( !irq_access_permitted(d, pirq) )
diff -r fcc71d023408 -r 6705898f768d xen/drivers/passthrough/io.c
--- a/xen/drivers/passthrough/io.c      Wed May 27 08:19:30 2009 +0100
+++ b/xen/drivers/passthrough/io.c      Wed May 27 10:38:51 2009 +0100
@@ -38,9 +38,10 @@ static void pt_irq_time_out(void *data)
     struct dev_intx_gsi_link *digl;
     struct hvm_girq_dpci_mapping *girq;
     uint32_t device, intx;
-    DECLARE_BITMAP(machine_gsi_map, NR_IRQS);
-
-    bitmap_zero(machine_gsi_map, NR_IRQS);
+    unsigned int nr_pirqs = irq_map->dom->nr_pirqs;
+    DECLARE_BITMAP(machine_gsi_map, nr_pirqs);
+
+    bitmap_zero(machine_gsi_map, nr_pirqs);
 
     spin_lock(&irq_map->dom->event_lock);
 
@@ -59,9 +60,9 @@ static void pt_irq_time_out(void *data)
         hvm_pci_intx_deassert(irq_map->dom, device, intx);
     }
 
-    for ( machine_gsi = find_first_bit(machine_gsi_map, NR_IRQS);
-          machine_gsi < NR_IRQS;
-          machine_gsi = find_next_bit(machine_gsi_map, NR_IRQS,
+    for ( machine_gsi = find_first_bit(machine_gsi_map, nr_pirqs);
+          machine_gsi < nr_pirqs;
+          machine_gsi = find_next_bit(machine_gsi_map, nr_pirqs,
                                       machine_gsi + 1) )
     {
         clear_bit(machine_gsi, dpci->dirq_mask);
@@ -71,13 +72,21 @@ static void pt_irq_time_out(void *data)
 
     spin_unlock(&irq_map->dom->event_lock);
 
-    for ( machine_gsi = find_first_bit(machine_gsi_map, NR_IRQS);
-          machine_gsi < NR_IRQS;
-          machine_gsi = find_next_bit(machine_gsi_map, NR_IRQS,
+    for ( machine_gsi = find_first_bit(machine_gsi_map, nr_pirqs);
+          machine_gsi < nr_pirqs;
+          machine_gsi = find_next_bit(machine_gsi_map, nr_pirqs,
                                       machine_gsi + 1) )
     {
         pirq_guest_eoi(irq_map->dom, machine_gsi);
     }
+}
+
+void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci)
+{
+    xfree(dpci->mirq);
+    xfree(dpci->dirq_mask);
+    xfree(dpci->mapping);
+    xfree(dpci);
 }
 
 int pt_irq_create_bind_vtd(
@@ -90,7 +99,7 @@ int pt_irq_create_bind_vtd(
     struct hvm_girq_dpci_mapping *girq;
     int rc, pirq = pt_irq_bind->machine_irq;
 
-    if ( pirq < 0 || pirq >= NR_IRQS )
+    if ( pirq < 0 || pirq >= d->nr_pirqs )
         return -EINVAL;
 
     spin_lock(&d->event_lock);
@@ -105,16 +114,33 @@ int pt_irq_create_bind_vtd(
             return -ENOMEM;
         }
         memset(hvm_irq_dpci, 0, sizeof(*hvm_irq_dpci));
-        for ( int i = 0; i < NR_IRQS; i++ )
-        {
+        hvm_irq_dpci->mirq = xmalloc_array(struct hvm_mirq_dpci_mapping,
+                                           d->nr_pirqs);
+        hvm_irq_dpci->dirq_mask = xmalloc_array(unsigned long,
+                                                BITS_TO_LONGS(d->nr_pirqs));
+        hvm_irq_dpci->mapping = xmalloc_array(unsigned long,
+                                              BITS_TO_LONGS(d->nr_pirqs));
+        if ( !hvm_irq_dpci->mirq ||
+             !hvm_irq_dpci->dirq_mask ||
+             !hvm_irq_dpci->mapping )
+        {
+            spin_unlock(&d->event_lock);
+            free_hvm_irq_dpci(hvm_irq_dpci);
+            return -ENOMEM;
+        }
+        memset(hvm_irq_dpci->mirq, 0,
+               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);
+        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++ )
             INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]);
-        }
 
         if ( domain_set_irq_dpci(d, hvm_irq_dpci) == 0 )
         {
             spin_unlock(&d->event_lock);
-            xfree(hvm_irq_dpci);
+            free_hvm_irq_dpci(hvm_irq_dpci);
             return -EINVAL;
         }
     }
@@ -364,7 +390,7 @@ static void __msi_pirq_eoi(struct domain
     struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci;
     irq_desc_t *desc;
 
-    if ( ( pirq >= 0 ) && ( pirq < NR_IRQS ) &&
+    if ( ( pirq >= 0 ) && ( pirq < d->nr_pirqs ) &&
          test_bit(pirq, hvm_irq_dpci->mapping) &&
          ( hvm_irq_dpci->mirq[pirq].flags & HVM_IRQ_DPCI_MACH_MSI) )
     {
@@ -414,9 +440,9 @@ void hvm_dirq_assist(struct vcpu *v)
     if ( !iommu_enabled || (v->vcpu_id != 0) || (hvm_irq_dpci == NULL) )
         return;
 
-    for ( irq = find_first_bit(hvm_irq_dpci->dirq_mask, NR_IRQS);
-          irq < NR_IRQS;
-          irq = find_next_bit(hvm_irq_dpci->dirq_mask, NR_IRQS, irq + 1) )
+    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) )
             continue;
diff -r fcc71d023408 -r 6705898f768d xen/drivers/passthrough/pci.c
--- a/xen/drivers/passthrough/pci.c     Wed May 27 08:19:30 2009 +0100
+++ b/xen/drivers/passthrough/pci.c     Wed May 27 10:38:51 2009 +0100
@@ -201,9 +201,9 @@ static void pci_clean_dpci_irqs(struct d
     hvm_irq_dpci = domain_get_irq_dpci(d);
     if ( hvm_irq_dpci != NULL )
     {
-        for ( i = find_first_bit(hvm_irq_dpci->mapping, NR_IRQS);
-              i < NR_IRQS;
-              i = find_next_bit(hvm_irq_dpci->mapping, NR_IRQS, i + 1) )
+        for ( i = find_first_bit(hvm_irq_dpci->mapping, d->nr_pirqs);
+              i < d->nr_pirqs;
+              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[irq_to_vector(i)]);
@@ -219,7 +219,7 @@ static void pci_clean_dpci_irqs(struct d
         }
 
         d->arch.hvm_domain.irq.dpci = NULL;
-        xfree(hvm_irq_dpci);
+        free_hvm_irq_dpci(hvm_irq_dpci);
     }
     spin_unlock(&d->event_lock);
 }
diff -r fcc71d023408 -r 6705898f768d xen/drivers/passthrough/vtd/x86/vtd.c
--- a/xen/drivers/passthrough/vtd/x86/vtd.c     Wed May 27 08:19:30 2009 +0100
+++ b/xen/drivers/passthrough/vtd/x86/vtd.c     Wed May 27 10:38:51 2009 +0100
@@ -130,9 +130,9 @@ void hvm_dpci_isairq_eoi(struct domain *
         return;
     }
     /* Multiple mirq may be mapped to one isa irq */
-    for ( i = find_first_bit(dpci->mapping, NR_IRQS);
-          i < NR_IRQS;
-          i = find_next_bit(dpci->mapping, NR_IRQS, i + 1) )
+    for ( i = find_first_bit(dpci->mapping, d->nr_pirqs);
+          i < d->nr_pirqs;
+          i = find_next_bit(dpci->mapping, d->nr_pirqs, i + 1) )
     {
         list_for_each_entry_safe ( digl, tmp,
             &dpci->mirq[i].digl_list, list )
diff -r fcc71d023408 -r 6705898f768d xen/include/asm-x86/config.h
--- a/xen/include/asm-x86/config.h      Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/asm-x86/config.h      Wed May 27 10:38:51 2009 +0100
@@ -50,12 +50,6 @@
 #define NR_CPUS MAX_PHYS_CPUS
 #else
 #define NR_CPUS 32
-#endif
-
-#ifdef MAX_PHYS_IRQS
-#define NR_IRQS MAX_PHYS_IRQS
-#else
-#define NR_IRQS 256
 #endif
 
 #if defined(__i386__) && (NR_CPUS > 32)
diff -r fcc71d023408 -r 6705898f768d xen/include/asm-x86/domain.h
--- a/xen/include/asm-x86/domain.h      Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/asm-x86/domain.h      Wed May 27 10:38:51 2009 +0100
@@ -263,7 +263,7 @@ struct arch_domain
 
     /* NB. protected by d->event_lock and by irq_desc[vector].lock */
     int vector_pirq[NR_VECTORS];
-    s16 pirq_vector[NR_IRQS];
+    s16 *pirq_vector;
 
     /* Shared page for notifying that explicit PIRQ EOI is required. */
     unsigned long *pirq_eoi_map;
diff -r fcc71d023408 -r 6705898f768d xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h     Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/asm-x86/io_apic.h     Wed May 27 10:38:51 2009 +0100
@@ -175,11 +175,14 @@ extern int timer_uses_ioapic_pin_0;
 extern int timer_uses_ioapic_pin_0;
 #endif /*CONFIG_ACPI_BOOT*/
 
+extern void init_ioapic_mappings(void);
+
 extern int (*ioapic_renumber_irq)(int ioapic, int irq);
 extern void ioapic_suspend(void);
 extern void ioapic_resume(void);
 
 #else  /* !CONFIG_X86_IO_APIC */
+static inline void init_ioapic_mappings(void) {}
 static inline void ioapic_suspend(void) {}
 static inline void ioapic_resume(void) {}
 #endif
diff -r fcc71d023408 -r 6705898f768d xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/asm-x86/irq.h Wed May 27 10:38:51 2009 +0100
@@ -18,7 +18,7 @@
 #define vector_to_irq(vec)  (vector_irq[vec])
 
 extern int vector_irq[NR_VECTORS];
-extern u8 irq_vector[NR_IRQS];
+extern u8 *irq_vector;
 
 #define platform_legacy_irq(irq)       ((irq) < 16)
 
diff -r fcc71d023408 -r 6705898f768d xen/include/xen/hvm/irq.h
--- a/xen/include/xen/hvm/irq.h Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/xen/hvm/irq.h Wed May 27 10:38:51 2009 +0100
@@ -68,21 +68,26 @@ struct hvm_girq_dpci_mapping {
 
 #define NR_ISAIRQS  16
 #define NR_LINK     4
+#if defined(__i386__) || defined(__x86_64__)
+# define NR_HVM_IRQS VIOAPIC_NUM_PINS
+#elif defined(__ia64__)
+# define NR_HVM_IRQS VIOSAPIC_NUM_PINS
+#endif
 
 /* Protected by domain's event_lock */
 struct hvm_irq_dpci {
     /* Machine IRQ to guest device/intx mapping. */
-    DECLARE_BITMAP(mapping, NR_IRQS);
-    struct hvm_mirq_dpci_mapping mirq[NR_IRQS];
+    unsigned long *mapping;
+    struct hvm_mirq_dpci_mapping *mirq;
+    unsigned long *dirq_mask;
     /* Guest IRQ to guest device/intx mapping. */
-    struct list_head girq[NR_IRQS];
-    uint8_t msi_gvec_pirq[NR_VECTORS];
-    DECLARE_BITMAP(dirq_mask, NR_IRQS);
+    struct list_head girq[NR_HVM_IRQS];
+    uint8_t msi_gvec_pirq[0x100];
     /* Record of mapped ISA IRQs */
     DECLARE_BITMAP(isairq_map, NR_ISAIRQS);
     /* Record of mapped Links */
     uint8_t link_cnt[NR_LINK];
-    struct timer hvm_timer[NR_IRQS];
+    struct timer hvm_timer[NR_VECTORS];
 };
 
 /* Modify state of a PCI INTx wire. */
diff -r fcc71d023408 -r 6705898f768d xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h   Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/xen/iommu.h   Wed May 27 10:38:51 2009 +0100
@@ -91,6 +91,7 @@ void hvm_dpci_isairq_eoi(struct domain *
 void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq);
 struct hvm_irq_dpci *domain_get_irq_dpci(struct domain *domain);
 int domain_set_irq_dpci(struct domain *domain, struct hvm_irq_dpci *dpci);
+void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci);
 
 #define PT_IRQ_TIME_OUT MILLISECS(8)
 #define VTDPREFIX "[VT-D]"
diff -r fcc71d023408 -r 6705898f768d xen/include/xen/irq.h
--- a/xen/include/xen/irq.h     Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/xen/irq.h     Wed May 27 10:38:51 2009 +0100
@@ -48,6 +48,12 @@ typedef struct hw_interrupt_type hw_irq_
 typedef struct hw_interrupt_type hw_irq_controller;
 
 #include <asm/irq.h>
+
+#ifdef NR_IRQS
+# define nr_irqs NR_IRQS
+#else
+extern unsigned int nr_irqs;
+#endif
 
 struct msi_desc;
 /*
diff -r fcc71d023408 -r 6705898f768d xen/include/xen/sched.h
--- a/xen/include/xen/sched.h   Wed May 27 08:19:30 2009 +0100
+++ b/xen/include/xen/sched.h   Wed May 27 10:38:51 2009 +0100
@@ -200,8 +200,9 @@ struct domain
      * domain's event-channel spinlock. Read accesses can also synchronise on 
      * the lock, but races don't usually matter.
      */
-    u16              pirq_to_evtchn[NR_IRQS];
-    DECLARE_BITMAP(pirq_mask, NR_IRQS);
+    unsigned int     nr_pirqs;
+    u16             *pirq_to_evtchn;
+    unsigned long   *pirq_mask;
 
     /* I/O capabilities (access to IRQs and memory-mapped I/O). */
     struct rangeset *iomem_caps;

_______________________________________________
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: eliminate hard-coded NR_IRQS, Xen patchbot-unstable <=