Consider the following scenario: A dom0 driver registers a number of MSI vectors with Xen. However, it does not bind to the pirqs. dom0 then maps the interrupts to different domUs which in turn bind to them. Such a scenario is very useful when you, e.g., have a multi-queue NIC with MSI-X and each queue has its own MSI-X entry. It enables frontend drivers (for different queues) in domUs to have the MSI interupts delivered to them directly. However, mapping single MSI vectors to guests does not currently work in Xen. Mapping of single pirqs is only allowd for vectors which are registered in the global irq_vector[] array. MSI interrupts are not registered here. The patch below fixes the problem by getting the vector from the per-domain pirq_to_vector array instead of the global array. This works perfectly fine. An alternative solution would be to register MSIs in the global irq_vector[] array (but only if the MSI mapping is done in the dom0 space). More generally speaking, the current state of affairs with regards to interrupt management in Xen can be a bit confusing from the source code point of view. Essentially, all irqs except some legacy interrupts are assumed to be IOAPIC irqs. This assumption breaks down with the introduction of MSIs and per-domain pirq tables. It might therefore be worthwile to rename a few things and slightly restructure the Xen code to make the distinction between IOAPIC irqs and other interrupts clearer. I could volunteer to have a stab at such a cleanup if this is something people want. Comments? eSk -- Use per-domain irq-to-vector array when mapping GSIs Using the per-domain array enables single MSI vectors to be mapped. Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> -- diff -r 2269079b8d09 xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Tue Feb 03 16:02:59 2009 +0000 +++ b/xen/arch/x86/physdev.c Wed Feb 04 15:39:53 2009 +0000 @@ -62,7 +62,7 @@ static int physdev_map_pirq(struct physd ret = -EINVAL; goto free_domain; } - vector = IO_APIC_VECTOR(map->index); + vector = domain_irq_to_vector(current->domain, map->index), if ( !vector ) { dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n", _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 04/02/2009 17:47, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:> More generally speaking, the current state of affairs with regards to > interrupt management in Xen can be a bit confusing from the source > code point of view. Essentially, all irqs except some legacy > interrupts are assumed to be IOAPIC irqs. This assumption breaks down > with the introduction of MSIs and per-domain pirq tables. It might > therefore be worthwile to rename a few things and slightly restructure > the Xen code to make the distinction between IOAPIC irqs and other > interrupts clearer. I could volunteer to have a stab at such a > cleanup if this is something people want. > > Comments?Sketch out what you mean in a bit more detail and I''ll think about it. The stuff in arch/x86/irq.c at least makes reasonable sense to me right now (of course ;-). -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-04 18:20 UTC
Re: [Xen-devel] [PATCH] [RFC] MSI and interrupt mapping
[Keir Fraser]> On 04/02/2009 17:47, "Espen Skoglund" <espen.skoglund@netronome.com> wrote: >> More generally speaking, the current state of affairs with regards >> to interrupt management in Xen can be a bit confusing from the >> source code point of view. Essentially, all irqs except some >> legacy interrupts are assumed to be IOAPIC irqs. This assumption >> breaks down with the introduction of MSIs and per-domain pirq >> tables. It might therefore be worthwile to rename a few things and >> slightly restructure the Xen code to make the distinction between >> IOAPIC irqs and other interrupts clearer. I could volunteer to >> have a stab at such a cleanup if this is something people want. >> >> Comments?> Sketch out what you mean in a bit more detail and I''ll think about > it. The stuff in arch/x86/irq.c at least makes reasonable sense to > me right now (of course ;-).Get rid of the global irq_vector[] and vector_irq[] arrays. Where needed (e.g., in the IOAPIC code) use the dom0 pirq arrays instead.>From a quick glance, the stuff in arch/x86/irq.c makes sense as it is;the exception perhaps being the dump_irqs() function which does not take MSIs into account. eSk _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
On 04/02/2009 18:20, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:>> Sketch out what you mean in a bit more detail and I''ll think about >> it. The stuff in arch/x86/irq.c at least makes reasonable sense to >> me right now (of course ;-). > > Get rid of the global irq_vector[] and vector_irq[] arrays. Where > needed (e.g., in the IOAPIC code) use the dom0 pirq arrays instead. > From a quick glance, the stuff in arch/x86/irq.c makes sense as it is; > the exception perhaps being the dump_irqs() function which does not > take MSIs into account.Yeah, okay, I think that might make sense. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:18 UTC
[Xen-devel] [PATCH 0/5] Mapping MSI vectors and other interrupt cleanups
Here''s a patch series for cleaning up some of the interrupt management. The first patch adds some (essential) extra functionality, the second patch adds some error checking, and the latter three patches are cleanups to the IOAPIC/vector/MSI management. [1] Enable single MSI vectors to be mapped to guests [2] Do some sanity checking when allocing IOMMU interrupts [3] Make some irq functions take vector param rather than IRQ param [4] Move interrupt vector management from io_apic.c to irq.c [5] Better separation of IOAPIC management eSk _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:19 UTC
[Xen-devel] [PATCH 1/5] Use per-domain irq-to-vector array when mapping GSIs
Use per-domain irq-to-vector array when mapping GSIs Using the per-domain array enables single MSI vectors to be mapped. Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> diff -r f3870189c530 xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Thu Feb 05 14:20:45 2009 +0000 +++ b/xen/arch/x86/physdev.c Thu Feb 05 14:29:01 2009 +0000 @@ -62,7 +62,7 @@ static int physdev_map_pirq(struct physd ret = -EINVAL; goto free_domain; } - vector = IO_APIC_VECTOR(map->index); + vector = domain_irq_to_vector(current->domain, map->index); if ( !vector ) { dprintk(XENLOG_G_ERR, "dom%d: map irq with no vector %d\n", _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:19 UTC
[Xen-devel] [PATCH 2/5] Cleanup IOMMU interrupt setup
Cleanup IOMMU interrupt setup - Check for errors when allocating interrupt vectors - Clean up if interrupt allocation failed - Make sure that the allocated vector is not reused Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> diff -r 39a154721acb xen/drivers/passthrough/amd/iommu_init.c --- a/xen/drivers/passthrough/amd/iommu_init.c Thu Feb 05 14:29:02 2009 +0000 +++ b/xen/drivers/passthrough/amd/iommu_init.c Thu Feb 05 18:42:00 2009 +0000 @@ -480,15 +480,9 @@ static int set_iommu_interrupt_handler(s int vector, ret; vector = assign_irq_vector(AUTO_ASSIGN); - vector_to_iommu[vector] = iommu; - - /* make irq == vector */ - irq_vector[vector] = vector; - vector_irq[vector] = vector; - - if ( !vector ) + if ( vector <= 0 ) { - amd_iov_error("no vectors\n"); + gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n"); return 0; } @@ -496,9 +490,15 @@ static int set_iommu_interrupt_handler(s ret = request_irq(vector, amd_iommu_page_fault, 0, "amd_iommu", iommu); if ( ret ) { + irq_desc[vector].handler = &no_irq_type; + free_irq_vector(vector); amd_iov_error("can''t request irq\n"); return 0; } + + /* Make sure that vector is never re-used. */ + vector_irq[vector] = NEVER_ASSIGN; + vector_to_iommu[vector] = iommu; iommu->vector = vector; return vector; } diff -r 39a154721acb xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Thu Feb 05 14:29:02 2009 +0000 +++ b/xen/drivers/passthrough/vtd/iommu.c Thu Feb 05 18:42:00 2009 +0000 @@ -875,13 +875,7 @@ int iommu_set_interrupt(struct iommu *io int vector, ret; vector = assign_irq_vector(AUTO_ASSIGN); - vector_to_iommu[vector] = iommu; - - /* VT-d fault is a MSI, make irq == vector */ - irq_vector[vector] = vector; - vector_irq[vector] = vector; - - if ( !vector ) + if ( vector <= 0 ) { gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n"); return -EINVAL; @@ -890,7 +884,17 @@ int iommu_set_interrupt(struct iommu *io irq_desc[vector].handler = &dma_msi_type; ret = request_irq(vector, iommu_page_fault, 0, "dmar", iommu); if ( ret ) + { + irq_desc[vector].handler = &no_irq_type; + free_irq_vector(vector); 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; + vector_to_iommu[vector] = iommu; + return vector; } @@ -1677,6 +1681,11 @@ static int init_vtd_hw(void) } vector = iommu_set_interrupt(iommu); + if ( vector < 0 ) + { + gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: interrupt setup failed\n"); + return vector; + } dma_msi_data_init(iommu, vector); dma_msi_addr_init(iommu, cpu_physical_id(first_cpu(cpu_online_map))); iommu->vector = vector; _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:21 UTC
[Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
Make setup_irq/request_irq/free_irq take vector param instead of irq param Also make sure that shutdown() in free_irq() is called with vector param. Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> diff -r a0f0ce00232a xen/arch/x86/i8259.c --- a/xen/arch/x86/i8259.c Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/arch/x86/i8259.c Thu Feb 05 18:58:19 2009 +0000 @@ -422,6 +422,6 @@ void __init init_IRQ(void) outb_p(LATCH & 0xff, PIT_CH0); /* LSB */ outb(LATCH >> 8, PIT_CH0); /* MSB */ - setup_irq(2, &cascade); + setup_irq(irq_to_vector(2), &cascade); } diff -r a0f0ce00232a xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/arch/x86/irq.c Thu Feb 05 18:58:19 2009 +0000 @@ -104,7 +104,7 @@ asmlinkage void do_IRQ(struct cpu_user_r spin_unlock(&desc->lock); } -int request_irq(unsigned int irq, +int request_irq(unsigned int vector, void (*handler)(int, void *, struct cpu_user_regs *), unsigned long irqflags, const char * devname, void *dev_id) { @@ -117,7 +117,7 @@ int request_irq(unsigned int irq, * which interrupt is which (messes up the interrupt freeing * logic etc). */ - if (irq >= NR_IRQS) + if (vector >= NR_VECTORS) return -EINVAL; if (!handler) return -EINVAL; @@ -130,34 +130,32 @@ int request_irq(unsigned int irq, action->name = devname; action->dev_id = dev_id; - retval = setup_irq(irq, action); + retval = setup_irq(vector, action); if (retval) xfree(action); return retval; } -void free_irq(unsigned int irq) +void free_irq(unsigned int vector) { - unsigned int vector = irq_to_vector(irq); - irq_desc_t *desc = &irq_desc[vector]; + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); desc->action = NULL; desc->depth = 1; desc->status |= IRQ_DISABLED; - desc->handler->shutdown(irq); + desc->handler->shutdown(vector); 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(unsigned int irq, struct irqaction *new) +int setup_irq(unsigned int vector, struct irqaction *new) { - unsigned int vector = irq_to_vector(irq); - irq_desc_t *desc = &irq_desc[vector]; + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); diff -r a0f0ce00232a xen/arch/x86/time.c --- a/xen/arch/x86/time.c Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/arch/x86/time.c Thu Feb 05 18:58:19 2009 +0000 @@ -1196,7 +1196,7 @@ void __init early_time_init(void) printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000); - setup_irq(0, &irq0); + setup_irq(irq_to_vector(0), &irq0); } /* force_hpet_broadcast: if true, force using hpet_broadcast to fix lapic stop diff -r a0f0ce00232a xen/drivers/char/ns16550.c --- a/xen/drivers/char/ns16550.c Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/drivers/char/ns16550.c Thu Feb 05 18:58:19 2009 +0000 @@ -242,7 +242,7 @@ static void __devinit ns16550_init_posti uart->irqaction.handler = ns16550_interrupt; uart->irqaction.name = "ns16550"; uart->irqaction.dev_id = port; - if ( (rc = setup_irq(uart->irq, &uart->irqaction)) != 0 ) + if ( (rc = setup_irq(irq_to_vector(uart->irq), &uart->irqaction)) != 0 ) printk("ERROR: Failed to allocate ns16550 IRQ %d\n", uart->irq); /* Master interrupt enable; also keep DTR/RTS asserted. */ diff -r a0f0ce00232a xen/drivers/char/serial.c --- a/xen/drivers/char/serial.c Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/drivers/char/serial.c Thu Feb 05 18:58:19 2009 +0000 @@ -471,7 +471,7 @@ void serial_suspend(void) int i, irq; for ( i = 0; i < ARRAY_SIZE(com); i++ ) if ( (irq = serial_irq(i)) >= 0 ) - free_irq(irq); + free_irq(irq_to_vector(irq)); } void serial_resume(void) diff -r a0f0ce00232a xen/include/xen/irq.h --- a/xen/include/xen/irq.h Thu Feb 05 18:42:00 2009 +0000 +++ b/xen/include/xen/irq.h Thu Feb 05 18:58:19 2009 +0000 @@ -66,7 +66,7 @@ extern irq_desc_t irq_desc[NR_VECTORS]; extern int setup_irq(unsigned int, struct irqaction *); extern void free_irq(unsigned int); -extern int request_irq(unsigned int irq, +extern int request_irq(unsigned int vector, void (*handler)(int, void *, struct cpu_user_regs *), unsigned long irqflags, const char * devname, void *dev_id); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:21 UTC
[Xen-devel] [PATCH 4/5] Move interrupt vector management from io_apic.c to irq.c
Move interrupt vector management from io_apic.c to irq.c Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> diff -r ddb2b7e0e94e xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Thu Feb 05 18:58:20 2009 +0000 +++ b/xen/arch/x86/io_apic.c Thu Feb 05 19:07:13 2009 +0000 @@ -49,7 +49,6 @@ static struct { int pin, apic; } ioapic_ static struct { int pin, apic; } ioapic_i8259 = { -1, -1 }; static DEFINE_SPINLOCK(ioapic_lock); -static DEFINE_SPINLOCK(vector_lock); int skip_ioapic_setup; @@ -88,9 +87,6 @@ static struct irq_pin_list { [0 ... PIN_MAP_SIZE-1].pin = -1 }; static int irq_2_pin_free_entry = NR_IRQS; - -int vector_irq[NR_VECTORS] __read_mostly = { - [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN}; /* * The common case is 1:1 IRQ<->pin mappings. Sometimes there are @@ -668,56 +664,6 @@ 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; - -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) - vector_irq[vector] = FREE_TO_ASSIGN; - spin_unlock(&vector_lock); - - return (irq == AUTO_ASSIGN) ? 0 : -EINVAL; -} - -int assign_irq_vector(int irq) -{ - static unsigned current_vector = FIRST_DYNAMIC_VECTOR; - unsigned vector; - - BUG_ON(irq >= NR_IRQS); - - spin_lock(&vector_lock); - - if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) { - spin_unlock(&vector_lock); - return IO_APIC_VECTOR(irq); - } - - vector = current_vector; - while (vector_irq[vector] != FREE_TO_ASSIGN) { - vector += 8; - if (vector > LAST_DYNAMIC_VECTOR) - vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7); - - if (vector == current_vector) { - spin_unlock(&vector_lock); - return -ENOSPC; - } - } - - current_vector = vector; - vector_irq[vector] = irq; - if (irq != AUTO_ASSIGN) - IO_APIC_VECTOR(irq) = vector; - - spin_unlock(&vector_lock); - - return vector; -} static struct hw_interrupt_type ioapic_level_type; static struct hw_interrupt_type ioapic_edge_type; diff -r ddb2b7e0e94e xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Thu Feb 05 18:58:20 2009 +0000 +++ b/xen/arch/x86/irq.c Thu Feb 05 19:07:13 2009 +0000 @@ -27,6 +27,11 @@ boolean_param("noirqbalance", opt_noirqb irq_desc_t irq_desc[NR_VECTORS]; +static DEFINE_SPINLOCK(vector_lock); +int vector_irq[NR_VECTORS] __read_mostly = { + [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN +}; + static void __do_IRQ_guest(int vector); void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs) { } @@ -53,6 +58,56 @@ 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) + vector_irq[vector] = FREE_TO_ASSIGN; + spin_unlock(&vector_lock); + + return (irq == AUTO_ASSIGN) ? 0 : -EINVAL; +} + +int assign_irq_vector(int irq) +{ + static unsigned current_vector = FIRST_DYNAMIC_VECTOR; + unsigned vector; + + BUG_ON(irq >= NR_IRQS); + + spin_lock(&vector_lock); + + if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) { + spin_unlock(&vector_lock); + return IO_APIC_VECTOR(irq); + } + + vector = current_vector; + while (vector_irq[vector] != FREE_TO_ASSIGN) { + vector += 8; + if (vector > LAST_DYNAMIC_VECTOR) + vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7); + + if (vector == current_vector) { + spin_unlock(&vector_lock); + return -ENOSPC; + } + } + + current_vector = vector; + vector_irq[vector] = irq; + if (irq != AUTO_ASSIGN) + IO_APIC_VECTOR(irq) = vector; + + spin_unlock(&vector_lock); + + return vector; +} asmlinkage void do_IRQ(struct cpu_user_regs *regs) { _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-05 20:21 UTC
[Xen-devel] [PATCH 5/5] Better separation of IOAPIC management
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> diff -r 99e1b00ef639 xen/arch/x86/io_apic.c --- a/xen/arch/x86/io_apic.c Thu Feb 05 19:07:13 2009 +0000 +++ b/xen/arch/x86/io_apic.c Thu Feb 05 19:31:09 2009 +0000 @@ -38,6 +38,10 @@ #include <mach_apic.h> #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(in 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(vo 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, 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 -r 99e1b00ef639 xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Thu Feb 05 19:07:13 2009 +0000 +++ b/xen/arch/x86/irq.c Thu Feb 05 19:31:09 2009 +0000 @@ -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 -r 99e1b00ef639 xen/arch/x86/smpboot.c --- a/xen/arch/x86/smpboot.c Thu Feb 05 19:07:13 2009 +0000 +++ b/xen/arch/x86/smpboot.c Thu Feb 05 19:31:09 2009 +0000 @@ -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 -r 99e1b00ef639 xen/include/asm-x86/irq.h --- a/xen/include/asm-x86/irq.h Thu Feb 05 19:07:13 2009 +0000 +++ b/xen/include/asm-x86/irq.h Thu Feb 05 19:31:09 2009 +0000 @@ -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 get_free_pirq(struct domain *d, int 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); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Feb-05 21:31 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
On 05/02/2009 20:21, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:> Make setup_irq/request_irq/free_irq take vector param instead of irq paramDo you really think that''s an improvement? -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-06 11:24 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
[Keir Fraser]> On 05/02/2009 20:21, "Espen Skoglund" <espen.skoglund@netronome.com> wrote: >> Make setup_irq/request_irq/free_irq take vector param instead of >> irq param> Do you really think that''s an improvement?Yes. Some interrupts, e.g., for handling IOMMU faults, do not need to be associated with a pirq. They just need to have a vector allocated to them. The way this used to work, the caller would have to invent a IRQ to go with the vector (typically irq := vector) befor calling the function. eSk _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Feb-06 11:34 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
On 06/02/2009 11:24, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:>>> Make setup_irq/request_irq/free_irq take vector param instead of >>> irq param > >> Do you really think that''s an improvement? > > Yes. Some interrupts, e.g., for handling IOMMU faults, do not need to > be associated with a pirq. They just need to have a vector allocated > to them. The way this used to work, the caller would have to invent a > IRQ to go with the vector (typically irq := vector) befor calling the > function.My reading of the patch was that you simply pushed irq_to_vector() out into every caller. I therefore just took the ->shutdown() fix for free_irq() and dropped the rest. I checked in the rest of your patches. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-06 11:44 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
[Keir Fraser]> On 06/02/2009 11:24, "Espen Skoglund" <espen.skoglund@netronome.com> wrote: >>>> Make setup_irq/request_irq/free_irq take vector param instead of >>>> irq param >> >>> Do you really think that''s an improvement? >> >> Yes. Some interrupts, e.g., for handling IOMMU faults, do not need >> to be associated with a pirq. They just need to have a vector >> allocated to them. The way this used to work, the caller would >> have to invent a IRQ to go with the vector (typically irq :>> vector) befor calling the function.> My reading of the patch was that you simply pushed irq_to_vector() > out into every caller. I therefore just took the ->shutdown() fix > for free_irq() and dropped the rest. I checked in the rest of your > patches.Hmmm... yeah. The patch probably didn''t make this very clear since some of the callers just invoke the function with the vector as the parameter (and hence these callers were not included in the patch). Anyhow, if you drop the vector parameter the IOMMU related interrupts will most certainly not work since we no longer update the irq_to_vector() array with those entries. eSk _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Feb-06 12:00 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
On 06/02/2009 11:44, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:>> My reading of the patch was that you simply pushed irq_to_vector() >> out into every caller. I therefore just took the ->shutdown() fix >> for free_irq() and dropped the rest. I checked in the rest of your >> patches. > > Hmmm... yeah. The patch probably didn''t make this very clear since > some of the callers just invoke the function with the vector as the > parameter (and hence these callers were not included in the patch). > > Anyhow, if you drop the vector parameter the IOMMU related interrupts > will most certainly not work since we no longer update the > irq_to_vector() array with those entries.Oh yes, also your patch would certainly have broken IA64, since you did not update its irq.c, nor does IA64 even have an irq_to_vector() macro. I suggest you do something like: * Rename the functions to {setup,request,free}_irq_vector(). * Make {setup,request,free}_irq() be simple wrappers around the above. * Only use the new function names for the IOMMU callers for now. * Think about how to not break IA64. And make a new patch, against c/s 19180 or later. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-06 13:53 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
[Keir Fraser]> On 06/02/2009 11:44, "Espen Skoglund" <espen.skoglund@netronome.com> wrote: >>> My reading of the patch was that you simply pushed irq_to_vector() >>> out into every caller. I therefore just took the ->shutdown() fix >>> for free_irq() and dropped the rest. I checked in the rest of your >>> patches. >> >> Hmmm... yeah. The patch probably didn''t make this very clear since >> some of the callers just invoke the function with the vector as the >> parameter (and hence these callers were not included in the patch). >> >> Anyhow, if you drop the vector parameter the IOMMU related >> interrupts will most certainly not work since we no longer update >> the irq_to_vector() array with those entries.> Oh yes, also your patch would certainly have broken IA64, since you > did not update its irq.c, nor does IA64 even have an irq_to_vector() > macro.> I suggest you do something like: > * Rename the functions to {setup,request,free}_irq_vector(). > * Make {setup,request,free}_irq() be simple wrappers around the above. > * Only use the new function names for the IOMMU callers for now. > * Think about how to not break IA64.> And make a new patch, against c/s 19180 or later.Whoops. Completely forgot about ia64 (my source grep command by default filters out non-x86 stuff). Your suggestions make perfect sense. Will post a new patch once c/s 19180 has been propagated to xen-unstable then. eSk _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Espen Skoglund
2009-Feb-09 17:46 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
[Espen Skoglund]> [Keir Fraser] >> I suggest you do something like: >> * Rename the functions to {setup,request,free}_irq_vector(). >> * Make {setup,request,free}_irq() be simple wrappers around the above. >> * Only use the new function names for the IOMMU callers for now. >> * Think about how to not break IA64.>> And make a new patch, against c/s 19180 or later.> Whoops. Completely forgot about ia64 (my source grep command by > default filters out non-x86 stuff). Your suggestions make perfect > sense. Will post a new patch once c/s 19180 has been propagated to > xen-unstable then.Here''s a patch which implements your suggestions. I''ve renamed free_irq() to release_irq() to avoid conflicts with the current free_irq_vector() function. I have not had a chance to actually test the ia64 related changes. Hopefully someone else can do that. The current ia64 code seems to be a bit inconsistent with the whole irq and vector numbering scheme. Sometimes an irq number is used in place of a vector number or vice versa, and sometimes an irq number is translated before being used as a vector. In order to avoid breaking anything I have tried to keep with the current way of using these numbers (even though in some cases it looks wrong). Somebody with better knowledge of the ia64 code had better take a look this. [Sorry about the size of this patch. It grew a bit larger than anticipated.] eSk -- Cleanup naming for ia64 and x86 interrupt handling functions - Append ''_IRQ'' to AUTO_ASSIGN, NEVER_ASSIGN, and FREE_TO_ASSIGN - Rename {request,setup}_irq to {request,setup}_irq_vector - Rename free_irq to release_irq_vector - Add {request,setup,release}_irq wrappers for their {request,setup,release}_irq_vector counterparts - Added generic irq_to_vector inline for ia64 - Changed ia64 to use the new naming scheme Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> -- diff -r 54db59753f3d xen/arch/ia64/linux-xen/iosapic.c --- a/xen/arch/ia64/linux-xen/iosapic.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/ia64/linux-xen/iosapic.c Mon Feb 09 17:36:08 2009 +0000 @@ -93,6 +93,13 @@ #include <asm/ptrace.h> #include <asm/system.h> +static inline int iosapic_irq_to_vector (int irq) +{ + return irq; +} + +#undef irq_to_vector +#define irq_to_vector(irq) iosapic_irq_to_vector(irq) #undef DEBUG_INTERRUPT_ROUTING @@ -528,7 +535,7 @@ iosapic_reassign_vector (int vector) int new_vector; if (!list_empty(&iosapic_intr_info[vector].rtes)) { - new_vector = assign_irq_vector(AUTO_ASSIGN); + new_vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); @@ -764,7 +771,7 @@ again: spin_unlock_irqrestore(&iosapic_lock, flags); /* If vector is running out, we try to find a sharable vector */ - vector = assign_irq_vector(AUTO_ASSIGN); + vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if (vector < 0) { vector = iosapic_find_sharable_vector(trigger, polarity); if (vector < 0) @@ -919,7 +926,7 @@ iosapic_register_platform_intr (u32 int_ delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: - vector = assign_irq_vector(AUTO_ASSIGN); + vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if (vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); delivery = IOSAPIC_INIT; diff -r 54db59753f3d xen/arch/ia64/linux-xen/irq_ia64.c --- a/xen/arch/ia64/linux-xen/irq_ia64.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/ia64/linux-xen/irq_ia64.c Mon Feb 09 17:36:08 2009 +0000 @@ -261,13 +261,13 @@ register_percpu_irq (ia64_vector vec, st #ifdef XEN setup_vector(irq, action); #else - setup_irq(irq, action); + setup_irq_vector(irq, action); #endif } } #ifdef XEN -int request_irq(unsigned int irq, +int request_irq_vector(unsigned int vector, void (*handler)(int, void *, struct cpu_user_regs *), unsigned long irqflags, const char * devname, void *dev_id) { @@ -279,7 +279,7 @@ int request_irq(unsigned int irq, * otherwise we''ll have trouble later trying to figure out * which interrupt is which (messes up the interrupt freeing logic etc). * */ - if (irq >= NR_IRQS) + if (vector >= NR_VECTORS) return -EINVAL; if (!handler) return -EINVAL; @@ -291,7 +291,7 @@ int request_irq(unsigned int irq, action->handler = handler; action->name = devname; action->dev_id = dev_id; - setup_vector(irq, action); + setup_vector(vector, action); if (retval) xfree(action); diff -r 54db59753f3d xen/arch/ia64/linux-xen/mca.c --- a/xen/arch/ia64/linux-xen/mca.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/ia64/linux-xen/mca.c Mon Feb 09 17:36:08 2009 +0000 @@ -114,7 +114,6 @@ extern void ia64_slave_init_handler (v extern void ia64_slave_init_handler (void); #ifdef XEN extern void setup_vector (unsigned int vec, struct irqaction *action); -#define setup_irq(irq, action) setup_vector(irq, action) #endif static ia64_mc_info_t ia64_mc_info; @@ -1926,7 +1925,7 @@ ia64_mca_late_init(void) if (irq_to_vector(irq) == cpe_vector) { desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; - setup_irq(irq, &mca_cpe_irqaction); + setup_vector(irq, &mca_cpe_irqaction); } ia64_mca_register_cpev(cpe_vector); IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__); diff -r 54db59753f3d xen/arch/ia64/xen/irq.c --- a/xen/arch/ia64/xen/irq.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/ia64/xen/irq.c Mon Feb 09 17:36:08 2009 +0000 @@ -228,11 +228,11 @@ out: * disabled. */ -int setup_vector(unsigned int irq, struct irqaction * new) +int setup_vector(unsigned int vector, struct irqaction * new) { unsigned long flags; struct irqaction *old, **p; - irq_desc_t *desc = irq_descp(irq); + irq_desc_t *desc = irq_descp(vector); /* * The following block of code has to be executed atomically @@ -248,8 +248,8 @@ int setup_vector(unsigned int irq, struc desc->depth = 0; desc->status &= ~(IRQ_DISABLED | IRQ_INPROGRESS | IRQ_GUEST); - desc->handler->startup(irq); - desc->handler->enable(irq); + desc->handler->startup(vector); + desc->handler->enable(vector); spin_unlock_irqrestore(&desc->lock,flags); return 0; @@ -258,13 +258,11 @@ int setup_vector(unsigned int irq, struc /* Vectors reserved by xen (and thus not sharable with domains). */ unsigned long ia64_xen_vector[BITS_TO_LONGS(NR_IRQS)]; -int setup_irq(unsigned int irq, struct irqaction * new) +int setup_irq_vector(unsigned int vec, struct irqaction * new) { - unsigned int vec; int res; - /* Get vector for IRQ. */ - if (acpi_gsi_to_irq (irq, &vec) < 0) + if ( !vec ) return -ENOSYS; /* Reserve the vector (and thus the irq). */ if (test_and_set_bit(vec, ia64_xen_vector)) @@ -273,14 +271,12 @@ int setup_irq(unsigned int irq, struct i return res; } -void free_irq(unsigned int irq) +void release_irq_vector(unsigned int vec) { - unsigned int vec; unsigned long flags; irq_desc_t *desc; - /* Get vector for IRQ. */ - if (acpi_gsi_to_irq(irq, &vec) < 0) + if ( !vec ) return; desc = irq_descp(vec); diff -r 54db59753f3d xen/arch/x86/i8259.c --- a/xen/arch/x86/i8259.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/x86/i8259.c Mon Feb 09 17:36:08 2009 +0000 @@ -410,8 +410,8 @@ void __init init_IRQ(void) } /* Never allocate the hypercall vector or Linux/BSD fast-trap vector. */ - vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN; - vector_irq[0x80] = NEVER_ASSIGN; + vector_irq[HYPERCALL_VECTOR] = NEVER_ASSIGN_IRQ; + vector_irq[0x80] = NEVER_ASSIGN_IRQ; apic_intr_init(); diff -r 54db59753f3d xen/arch/x86/irq.c --- a/xen/arch/x86/irq.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/x86/irq.c Mon Feb 09 17:36:08 2009 +0000 @@ -29,7 +29,7 @@ irq_desc_t irq_desc[NR_VECTORS]; static DEFINE_SPINLOCK(vector_lock); int vector_irq[NR_VECTORS] __read_mostly = { - [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN + [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN_IRQ }; static void __do_IRQ_guest(int vector); @@ -66,11 +66,11 @@ int free_irq_vector(int vector) BUG_ON((vector > LAST_DYNAMIC_VECTOR) || (vector < FIRST_DYNAMIC_VECTOR)); spin_lock(&vector_lock); - if ((irq = vector_irq[vector]) == AUTO_ASSIGN) - vector_irq[vector] = FREE_TO_ASSIGN; + if ((irq = vector_irq[vector]) == AUTO_ASSIGN_IRQ) + vector_irq[vector] = FREE_TO_ASSIGN_IRQ; spin_unlock(&vector_lock); - return (irq == AUTO_ASSIGN) ? 0 : -EINVAL; + return (irq == AUTO_ASSIGN_IRQ) ? 0 : -EINVAL; } int assign_irq_vector(int irq) @@ -82,13 +82,13 @@ int assign_irq_vector(int irq) spin_lock(&vector_lock); - if ((irq != AUTO_ASSIGN) && (IO_APIC_VECTOR(irq) > 0)) { + if ((irq != AUTO_ASSIGN_IRQ) && (IO_APIC_VECTOR(irq) > 0)) { spin_unlock(&vector_lock); return IO_APIC_VECTOR(irq); } vector = current_vector; - while (vector_irq[vector] != FREE_TO_ASSIGN) { + while (vector_irq[vector] != FREE_TO_ASSIGN_IRQ) { vector += 8; if (vector > LAST_DYNAMIC_VECTOR) vector = FIRST_DYNAMIC_VECTOR + ((vector + 1) & 7); @@ -101,7 +101,7 @@ int assign_irq_vector(int irq) current_vector = vector; vector_irq[vector] = irq; - if (irq != AUTO_ASSIGN) + if (irq != AUTO_ASSIGN_IRQ) IO_APIC_VECTOR(irq) = vector; spin_unlock(&vector_lock); @@ -159,7 +159,7 @@ asmlinkage void do_IRQ(struct cpu_user_r spin_unlock(&desc->lock); } -int request_irq(unsigned int irq, +int request_irq_vector(unsigned int vector, void (*handler)(int, void *, struct cpu_user_regs *), unsigned long irqflags, const char * devname, void *dev_id) { @@ -172,7 +172,7 @@ int request_irq(unsigned int irq, * which interrupt is which (messes up the interrupt freeing * logic etc). */ - if (irq >= NR_IRQS) + if (vector >= NR_VECTORS) return -EINVAL; if (!handler) return -EINVAL; @@ -185,17 +185,16 @@ int request_irq(unsigned int irq, action->name = devname; action->dev_id = dev_id; - retval = setup_irq(irq, action); + retval = setup_irq_vector(vector, action); if (retval) xfree(action); return retval; } -void free_irq(unsigned int irq) +void release_irq_vector(unsigned int vector) { - unsigned int vector = irq_to_vector(irq); - irq_desc_t *desc = &irq_desc[vector]; + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); @@ -209,10 +208,9 @@ void free_irq(unsigned int irq) do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS ); } -int setup_irq(unsigned int irq, struct irqaction *new) +int setup_irq_vector(unsigned int vector, struct irqaction *new) { - unsigned int vector = irq_to_vector(irq); - irq_desc_t *desc = &irq_desc[vector]; + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); diff -r 54db59753f3d xen/arch/x86/physdev.c --- a/xen/arch/x86/physdev.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/arch/x86/physdev.c Mon Feb 09 17:36:08 2009 +0000 @@ -75,7 +75,7 @@ static int physdev_map_pirq(struct physd case MAP_PIRQ_TYPE_MSI: vector = map->index; if ( vector == -1 ) - vector = assign_irq_vector(AUTO_ASSIGN); + vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if ( vector < 0 || vector >= NR_VECTORS ) { diff -r 54db59753f3d xen/drivers/char/serial.c --- a/xen/drivers/char/serial.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/drivers/char/serial.c Mon Feb 09 17:36:08 2009 +0000 @@ -471,7 +471,7 @@ void serial_suspend(void) int i, irq; for ( i = 0; i < ARRAY_SIZE(com); i++ ) if ( (irq = serial_irq(i)) >= 0 ) - free_irq(irq); + release_irq(irq); } void serial_resume(void) diff -r 54db59753f3d xen/drivers/passthrough/amd/iommu_init.c --- a/xen/drivers/passthrough/amd/iommu_init.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/drivers/passthrough/amd/iommu_init.c Mon Feb 09 17:36:08 2009 +0000 @@ -479,7 +479,7 @@ static int set_iommu_interrupt_handler(s { int vector, ret; - vector = assign_irq_vector(AUTO_ASSIGN); + vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if ( vector <= 0 ) { gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n"); @@ -487,7 +487,8 @@ static int set_iommu_interrupt_handler(s } irq_desc[vector].handler = &iommu_msi_type; - ret = request_irq(vector, amd_iommu_page_fault, 0, "amd_iommu", iommu); + ret = request_irq_vector(vector, amd_iommu_page_fault, 0, + "amd_iommu", iommu); if ( ret ) { irq_desc[vector].handler = &no_irq_type; @@ -497,7 +498,7 @@ static int set_iommu_interrupt_handler(s } /* Make sure that vector is never re-used. */ - vector_irq[vector] = NEVER_ASSIGN; + vector_irq[vector] = NEVER_ASSIGN_IRQ; vector_to_iommu[vector] = iommu; iommu->vector = vector; return vector; diff -r 54db59753f3d xen/drivers/passthrough/vtd/ia64/vtd.c --- a/xen/drivers/passthrough/vtd/ia64/vtd.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/drivers/passthrough/vtd/ia64/vtd.c Mon Feb 09 17:36:08 2009 +0000 @@ -29,7 +29,9 @@ #include "../vtd.h" -int vector_irq[NR_VECTORS] __read_mostly = { [0 ... NR_VECTORS - 1] = -1}; +int vector_irq[NR_VECTORS] __read_mostly = { + [0 ... NR_VECTORS - 1] = FREE_TO_ASSIGN_IRQ +}; /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ u8 irq_vector[NR_IRQS] __read_mostly; diff -r 54db59753f3d xen/drivers/passthrough/vtd/iommu.c --- a/xen/drivers/passthrough/vtd/iommu.c Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/drivers/passthrough/vtd/iommu.c Mon Feb 09 17:36:08 2009 +0000 @@ -874,7 +874,7 @@ int iommu_set_interrupt(struct iommu *io { int vector, ret; - vector = assign_irq_vector(AUTO_ASSIGN); + vector = assign_irq_vector(AUTO_ASSIGN_IRQ); if ( vector <= 0 ) { gdprintk(XENLOG_ERR VTDPREFIX, "IOMMU: no vectors\n"); @@ -882,7 +882,7 @@ int iommu_set_interrupt(struct iommu *io } irq_desc[vector].handler = &dma_msi_type; - ret = request_irq(vector, iommu_page_fault, 0, "dmar", iommu); + ret = request_irq_vector(vector, iommu_page_fault, 0, "dmar", iommu); if ( ret ) { irq_desc[vector].handler = &no_irq_type; @@ -892,7 +892,7 @@ int iommu_set_interrupt(struct iommu *io } /* Make sure that vector is never re-used. */ - vector_irq[vector] = NEVER_ASSIGN; + vector_irq[vector] = NEVER_ASSIGN_IRQ; vector_to_iommu[vector] = iommu; return vector; @@ -970,7 +970,7 @@ static void iommu_free(struct acpi_drhd_ iounmap(iommu->reg); free_intel_iommu(iommu->intel); - free_irq(iommu->vector); + release_irq_vector(iommu->vector); xfree(iommu); drhd->iommu = NULL; diff -r 54db59753f3d xen/include/asm-ia64/hvm/iommu.h --- a/xen/include/asm-ia64/hvm/iommu.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/asm-ia64/hvm/iommu.h Mon Feb 09 17:36:08 2009 +0000 @@ -28,10 +28,6 @@ static inline void pci_cleanup_msi(struc /* TODO */ } -/* Special IRQ numbers */ -#define AUTO_ASSIGN (-1) -#define NEVER_ASSIGN (-2) -#define FREE_TO_ASSIGN (-3) extern int assign_irq_vector (int irq); diff -r 54db59753f3d xen/include/asm-ia64/hvm/irq.h --- a/xen/include/asm-ia64/hvm/irq.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/asm-ia64/hvm/irq.h Mon Feb 09 17:36:08 2009 +0000 @@ -90,13 +90,16 @@ struct hvm_irq { #define hvm_pci_intx_link(dev, intx) \ (((dev) + (intx)) & 3) -/* Extract the IA-64 vector that corresponds to IRQ. */ -static inline int -irq_to_vector (int irq) +static inlint int irq_to_vector(int irq) { - return irq; + int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); + int vector; + + if ( acpi_gsi_to_irq(irq, &vector) < 0) + return 0; + + return vector; } - extern u8 irq_vector[NR_IRQS]; extern int vector_irq[NR_VECTORS]; diff -r 54db59753f3d xen/include/asm-ia64/linux-xen/linux/interrupt.h --- a/xen/include/asm-ia64/linux-xen/linux/interrupt.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/asm-ia64/linux-xen/linux/interrupt.h Mon Feb 09 17:36:08 2009 +0000 @@ -52,10 +52,10 @@ struct irqaction { }; extern irqreturn_t no_action(int cpl, void *dev_id, struct pt_regs *regs); -extern int request_irq(unsigned int, +extern int request_irq_vector(unsigned int, irqreturn_t (*handler)(int, void *, struct pt_regs *), unsigned long, const char *, void *); -extern void free_irq(unsigned int, void *); +extern void release_irq_vector(unsigned int, void *); #endif diff -r 54db59753f3d xen/include/asm-ia64/linux/asm/hw_irq.h --- a/xen/include/asm-ia64/linux/asm/hw_irq.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/asm-ia64/linux/asm/hw_irq.h Mon Feb 09 17:36:08 2009 +0000 @@ -34,7 +34,7 @@ typedef u8 ia64_vector; #define IA64_MAX_VECTORED_IRQ 255 #define IA64_NUM_VECTORS 256 -#define AUTO_ASSIGN -1 +#define AUTO_ASSIGN_IRQ (-1) #define IA64_SPURIOUS_INT_VECTOR 0x0f diff -r 54db59753f3d xen/include/asm-x86/irq.h --- a/xen/include/asm-x86/irq.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/asm-x86/irq.h Mon Feb 09 17:36:08 2009 +0000 @@ -19,9 +19,6 @@ extern int vector_irq[NR_VECTORS]; extern u8 irq_vector[NR_IRQS]; -#define AUTO_ASSIGN -1 -#define NEVER_ASSIGN -2 -#define FREE_TO_ASSIGN -3 #define platform_legacy_irq(irq) ((irq) < 16) diff -r 54db59753f3d xen/include/xen/irq.h --- a/xen/include/xen/irq.h Mon Feb 09 14:54:54 2009 +0000 +++ b/xen/include/xen/irq.h Mon Feb 09 17:36:08 2009 +0000 @@ -24,6 +24,11 @@ struct irqaction #define IRQ_GUEST 16 /* IRQ is handled by guest OS(es) */ #define IRQ_GUEST_EOI_PENDING 32 /* IRQ was disabled, pending a guest EOI */ #define IRQ_PER_CPU 256 /* IRQ is per CPU */ + +/* Special IRQ numbers. */ +#define AUTO_ASSIGN_IRQ (-1) +#define NEVER_ASSIGN_IRQ (-2) +#define FREE_TO_ASSIGN_IRQ (-3) /* * Interrupt controller descriptor. This is all we need @@ -64,11 +69,20 @@ typedef struct { extern irq_desc_t irq_desc[NR_VECTORS]; -extern int setup_irq(unsigned int, struct irqaction *); -extern void free_irq(unsigned int); -extern int request_irq(unsigned int irq, +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) + +#define release_irq(irq) \ + release_irq_vector(irq_to_vector(irq)) + +#define request_irq(irq, handler, irqflags, devname, devid) \ + request_irq_vector(irq_to_vector(irq), handler, irqflags, defname, devid) extern hw_irq_controller no_irq_type; extern void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs); _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2009-Feb-10 05:41 UTC
Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
On 09/02/2009 17:46, "Espen Skoglund" <espen.skoglund@netronome.com> wrote:> Cleanup naming for ia64 and x86 interrupt handling functions > > - Append ''_IRQ'' to AUTO_ASSIGN, NEVER_ASSIGN, and FREE_TO_ASSIGN > - Rename {request,setup}_irq to {request,setup}_irq_vector > - Rename free_irq to release_irq_vector > - Add {request,setup,release}_irq wrappers for their > {request,setup,release}_irq_vector counterparts > - Added generic irq_to_vector inline for ia64 > - Changed ia64 to use the new naming scheme > > Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>This needs an ack on the IA64 side. And perhaps a fixup patch since it probably breaks their build if you couldn''t test that. I cc''ed Isaku. -- Keir _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Isaku Yamahata
2009-Feb-12 07:25 UTC
[Xen-ia64-devel] Re: [Xen-devel] [PATCH 3/5] setup_irq/request_irq/free_irq fixups
On Tue, Feb 10, 2009 at 05:41:18AM +0000, Keir Fraser wrote:> On 09/02/2009 17:46, "Espen Skoglund" <espen.skoglund@netronome.com> wrote: > > > Cleanup naming for ia64 and x86 interrupt handling functions > > > > - Append ''_IRQ'' to AUTO_ASSIGN, NEVER_ASSIGN, and FREE_TO_ASSIGN > > - Rename {request,setup}_irq to {request,setup}_irq_vector > > - Rename free_irq to release_irq_vector > > - Add {request,setup,release}_irq wrappers for their > > {request,setup,release}_irq_vector counterparts > > - Added generic irq_to_vector inline for ia64 > > - Changed ia64 to use the new naming scheme > > > > Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com> > > This needs an ack on the IA64 side. And perhaps a fixup patch since it > probably breaks their build if you couldn''t test that. I cc''ed Isaku.Here is the additional patch to boot xen on ia64. [IA64] more fix tirivial compliation fix and fixes to boot xen on ia64. Signed-off-by: Isaku Yamahata <yamahata@valinux.co.jp> diff --git a/xen/arch/ia64/linux-xen/iosapic.c b/xen/arch/ia64/linux-xen/iosapic.c --- a/xen/arch/ia64/linux-xen/iosapic.c +++ b/xen/arch/ia64/linux-xen/iosapic.c @@ -93,6 +93,7 @@ #include <asm/ptrace.h> #include <asm/system.h> +#ifdef XEN static inline int iosapic_irq_to_vector (int irq) { return irq; @@ -100,6 +101,8 @@ static inline int iosapic_irq_to_vector #undef irq_to_vector #define irq_to_vector(irq) iosapic_irq_to_vector(irq) +#define AUTO_ASSIGN AUTO_ASSIGN_IRQ +#endif #undef DEBUG_INTERRUPT_ROUTING @@ -535,7 +538,7 @@ iosapic_reassign_vector (int vector) int new_vector; if (!list_empty(&iosapic_intr_info[vector].rtes)) { - new_vector = assign_irq_vector(AUTO_ASSIGN_IRQ); + new_vector = assign_irq_vector(AUTO_ASSIGN); if (new_vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); printk(KERN_INFO "Reassigning vector %d to %d\n", vector, new_vector); @@ -771,7 +774,7 @@ again: spin_unlock_irqrestore(&iosapic_lock, flags); /* If vector is running out, we try to find a sharable vector */ - vector = assign_irq_vector(AUTO_ASSIGN_IRQ); + vector = assign_irq_vector(AUTO_ASSIGN); if (vector < 0) { vector = iosapic_find_sharable_vector(trigger, polarity); if (vector < 0) @@ -926,7 +929,7 @@ iosapic_register_platform_intr (u32 int_ delivery = IOSAPIC_PMI; break; case ACPI_INTERRUPT_INIT: - vector = assign_irq_vector(AUTO_ASSIGN_IRQ); + vector = assign_irq_vector(AUTO_ASSIGN); if (vector < 0) panic("%s: out of interrupt vectors!\n", __FUNCTION__); delivery = IOSAPIC_INIT; diff --git a/xen/arch/ia64/linux-xen/irq_ia64.c b/xen/arch/ia64/linux-xen/irq_ia64.c --- a/xen/arch/ia64/linux-xen/irq_ia64.c +++ b/xen/arch/ia64/linux-xen/irq_ia64.c @@ -250,6 +250,7 @@ void register_percpu_irq (ia64_vector vec, struct irqaction *action) { irq_desc_t *desc; +#ifndef XEN unsigned int irq; for (irq = 0; irq < NR_IRQS; ++irq) @@ -258,12 +259,15 @@ register_percpu_irq (ia64_vector vec, st desc->status |= IRQ_PER_CPU; desc->handler = &irq_type_ia64_lsapic; if (action) -#ifdef XEN - setup_vector(irq, action); + setup_irq(irq, action); + } #else - setup_irq_vector(irq, action); + desc = irq_descp(vec); + desc->status |= IRQ_PER_CPU; + desc->handler = &irq_type_ia64_lsapic; + if (action) + setup_vector(vec, action); #endif - } } #ifdef XEN diff --git a/xen/arch/ia64/linux-xen/mca.c b/xen/arch/ia64/linux-xen/mca.c --- a/xen/arch/ia64/linux-xen/mca.c +++ b/xen/arch/ia64/linux-xen/mca.c @@ -1930,12 +1930,18 @@ ia64_mca_late_init(void) if (cpe_vector >= 0) { /* If platform supports CPEI, enable the irq. */ cpe_poll_enabled = 0; +#ifndef XEN for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == cpe_vector) { desc = irq_descp(irq); desc->status |= IRQ_PER_CPU; setup_vector(irq, &mca_cpe_irqaction); } +#else + desc = irq_descp(cpe_vector); + desc->status |= IRQ_PER_CPU; + setup_vector(cpe_vector, &mca_cpe_irqaction); +#endif ia64_mca_register_cpev(cpe_vector); IA64_MCA_DEBUG("%s: CPEI/P setup and enabled.\n", __FUNCTION__); } else { diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -543,7 +543,7 @@ long do_physdev_op(int cmd, XEN_GUEST_HA break; irq_status_query.flags = 0; /* Edge-triggered interrupts don''t need an explicit unmask downcall. */ - if ( !strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") ) + if ( !strstr(irq_descp(irq)->handler->typename, "edge") ) irq_status_query.flags |= XENIRQSTAT_needs_eoi; ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0; break; diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c --- a/xen/arch/ia64/xen/irq.c +++ b/xen/arch/ia64/xen/irq.c @@ -262,7 +262,7 @@ int setup_irq_vector(unsigned int vec, s { int res; - if ( !vec ) + if ( vec == IA64_INVALID_VECTOR ) return -ENOSYS; /* Reserve the vector (and thus the irq). */ if (test_and_set_bit(vec, ia64_xen_vector)) @@ -276,7 +276,7 @@ void release_irq_vector(unsigned int vec unsigned long flags; irq_desc_t *desc; - if ( !vec ) + if ( vec == IA64_INVALID_VECTOR ) return; desc = irq_descp(vec); diff --git a/xen/include/asm-ia64/hvm/irq.h b/xen/include/asm-ia64/hvm/irq.h --- a/xen/include/asm-ia64/hvm/irq.h +++ b/xen/include/asm-ia64/hvm/irq.h @@ -90,10 +90,11 @@ struct hvm_irq { #define hvm_pci_intx_link(dev, intx) \ (((dev) + (intx)) & 3) -static inlint int irq_to_vector(int irq) +#define IA64_INVALID_VECTOR ((unsigned int)((int)-1)) +static inline unsigned int irq_to_vector(int irq) { int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); - int vector; + unsigned int vector; if ( acpi_gsi_to_irq(irq, &vector) < 0) return 0; -- yamahata _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@lists.xensource.com http://lists.xensource.com/xen-ia64-devel