aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeir Fraser <keir.fraser@citrix.com>2009-02-06 10:42:26 +0000
committerKeir Fraser <keir.fraser@citrix.com>2009-02-06 10:42:26 +0000
commit81e91a22e4a27a90a2b8e050ac386b47cf38eb63 (patch)
treec656d673b01aedc875f42a6f120daa7689aa4fba
parent48a535073130ce4063ca4a15f510a5122f7f9fb7 (diff)
downloadxen-81e91a22e4a27a90a2b8e050ac386b47cf38eb63.tar.gz
xen-81e91a22e4a27a90a2b8e050ac386b47cf38eb63.tar.bz2
xen-81e91a22e4a27a90a2b8e050ac386b47cf38eb63.zip
Better separate IOAPIC management from interrupt vector management
Don't automatically update ioapic_irq array when allocating vectors. Only do so when actually allocating IOAPIC irqs. Also move some IOAPIC specific defines to io_apic.c. Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
-rw-r--r--xen/arch/x86/io_apic.c15
-rw-r--r--xen/arch/x86/irq.c6
-rw-r--r--xen/arch/x86/smpboot.c2
-rw-r--r--xen/include/asm-x86/irq.h31
4 files changed, 29 insertions, 25 deletions
diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c
index c767d175bb..ede0998667 100644
--- a/xen/arch/x86/io_apic.c
+++ b/xen/arch/x86/io_apic.c
@@ -39,6 +39,10 @@
#include <io_ports.h>
#include <public/physdev.h>
+
+#define IO_APIC_IRQ(irq) (!IS_LEGACY_IRQ(irq))
+#define IO_APIC_VECTOR(irq) (ioapic_irq_vector[irq])
+
/* Different to Linux: our implementation can be simpler. */
#define make_8259A_irq(irq) (io_apic_irqs &= ~(1<<(irq)))
@@ -662,8 +666,8 @@ static inline int IO_APIC_irq_trigger(int irq)
return 0;
}
-/* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */
-u8 irq_vector[NR_IRQS] __read_mostly;
+/* irq vectors are indexed by the sum of all RTEs in all I/O APICs. */
+u8 ioapic_irq_vector[NR_IRQS] __read_mostly;
static struct hw_interrupt_type ioapic_level_type;
static struct hw_interrupt_type ioapic_edge_type;
@@ -740,6 +744,7 @@ static void __init setup_IO_APIC_irqs(void)
if (IO_APIC_IRQ(irq)) {
vector = assign_irq_vector(irq);
+ ioapic_irq_vector[irq] = vector;
entry.vector = vector;
ioapic_register_intr(irq, vector, IOAPIC_AUTO);
@@ -933,9 +938,9 @@ void /*__init*/ __print_IO_APIC(void)
struct irq_pin_list *entry = irq_2_pin + i;
if (entry->pin < 0)
continue;
- printk(KERN_DEBUG "IRQ%d ", IO_APIC_VECTOR(i));
+ printk(KERN_DEBUG "IRQ%-3d (vec %3d)", i, IO_APIC_VECTOR(i));
for (;;) {
- printk("-> %d:%d", entry->apic, entry->pin);
+ printk(" -> %d:%d", entry->apic, entry->pin);
if (!entry->next)
break;
entry = irq_2_pin + entry->next;
@@ -1662,6 +1667,7 @@ static inline void check_timer(void)
*/
disable_8259A_irq(0);
vector = assign_irq_vector(0);
+ ioapic_irq_vector[0] = vector;
irq_desc[IO_APIC_VECTOR(0)].action = irq_desc[LEGACY_VECTOR(0)].action;
irq_desc[IO_APIC_VECTOR(0)].depth = 0;
@@ -2019,6 +2025,7 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a
add_pin_to_irq(irq, ioapic, pin);
entry.vector = assign_irq_vector(irq);
+ ioapic_irq_vector[irq] = entry.vector;
apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
"(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c
index 2587b0736c..7def87b50e 100644
--- a/xen/arch/x86/irq.c
+++ b/xen/arch/x86/irq.c
@@ -82,9 +82,9 @@ int assign_irq_vector(int irq)
spin_lock(&vector_lock);
- if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) {
+ if ((irq != AUTO_ASSIGN) && (ioapic_irq_vector[irq] > 0)) {
spin_unlock(&vector_lock);
- return IO_APIC_VECTOR(irq);
+ return ioapic_irq_vector[irq];
}
vector = current_vector;
@@ -101,8 +101,6 @@ int assign_irq_vector(int irq)
current_vector = vector;
vector_irq[vector] = irq;
- if (irq != AUTO_ASSIGN)
- IO_APIC_VECTOR(irq) = vector;
spin_unlock(&vector_lock);
diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c
index 1f96ed6d50..3c9a78a497 100644
--- a/xen/arch/x86/smpboot.c
+++ b/xen/arch/x86/smpboot.c
@@ -1477,7 +1477,6 @@ void __init smp_intr_init(void)
* IRQ0 must be given a fixed assignment and initialized,
* because it's used before the IO-APIC is set up.
*/
- irq_vector[0] = FIRST_HIPRIORITY_VECTOR;
vector_irq[FIRST_HIPRIORITY_VECTOR] = 0;
/*
@@ -1487,7 +1486,6 @@ void __init smp_intr_init(void)
for (seridx = 0; seridx < 2; seridx++) {
if ((irq = serial_irq(seridx)) < 0)
continue;
- irq_vector[irq] = FIRST_HIPRIORITY_VECTOR + seridx + 1;
vector_irq[FIRST_HIPRIORITY_VECTOR + seridx + 1] = irq;
}
diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h
index 2f1e59f148..cc9604fe25 100644
--- a/xen/include/asm-x86/irq.h
+++ b/xen/include/asm-x86/irq.h
@@ -7,21 +7,20 @@
#include <asm/atomic.h>
#include <irq_vectors.h>
-#define IO_APIC_IRQ(irq) (((irq) >= 16) || ((1<<(irq)) & io_apic_irqs))
-#define IO_APIC_VECTOR(irq) (irq_vector[irq])
-
+#define IS_LEGACY_IRQ(irq) (((irq) < 16) && !((1 << (irq)) & io_apic_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])
-
-extern int vector_irq[NR_VECTORS];
-extern u8 irq_vector[NR_IRQS];
+/* Special IRQ numbers */
#define AUTO_ASSIGN -1
#define NEVER_ASSIGN -2
#define FREE_TO_ASSIGN -3
+extern int vector_irq[NR_VECTORS];
+extern u8 ioapic_irq_vector[NR_IRQS];
+
+#define vector_to_irq(vec) (vector_irq[vec])
+#define irq_to_vector(irq) \
+ (IS_LEGACY_IRQ(irq) ? LEGACY_VECTOR(irq) : ioapic_irq_vector[irq])
#define platform_legacy_irq(irq) ((irq) < 16)
@@ -60,12 +59,14 @@ 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))
+#define domain_irq_to_vector(d, irq) \
+ ((d)->arch.pirq_vector[irq] ? (d)->arch.pirq_vector[irq] : \
+ IS_LEGACY_IRQ(irq) ? LEGACY_VECTOR(irq) : 0)
+
+#define domain_vector_to_irq(d, vec) \
+ ((d)->arch.vector_pirq[vec] ? (d)->arch.vector_pirq[vec] : \
+ ((vec) < FIRST_LEGACY_VECTOR || (vec) > LAST_LEGACY_VECTOR) ? \
+ 0 : LEGACY_IRQ_FROM_VECTOR(vec))
int pirq_guest_force_unbind(struct domain *d, int irq);