diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 08:48:46 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-01-10 08:48:46 -0800 |
commit | 9f99a2f0e44663517b99b69a3e4a499d0ba877df (patch) | |
tree | 92bbe9f9c9c6687a49e13e4e1bfe2a29bc736476 /drivers/xen/events.c | |
parent | 8c8ae4e8cd5a67467192f3361eeec463694f8ed8 (diff) | |
parent | 110e7c7e4f8a61a34e0ab88fc9bdf4d5c6d220b2 (diff) |
Merge branch 'stable/bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen
* 'stable/bug-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/konrad/xen:
xen/event: validate irq before get evtchn by irq
xen/fb: fix potential memory leak
xen/fb: fix xenfb suspend/resume race.
xen: disable ACPI NUMA for PV guests
xen/irq: Cleanup the find_unbound_irq
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 65f8637d13c..74681478100 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -170,6 +170,9 @@ static struct irq_info *info_for_irq(unsigned irq) static unsigned int evtchn_from_irq(unsigned irq) { + if (unlikely(WARN(irq < 0 || irq >= nr_irqs, "Invalid irq %d!\n", irq))) + return 0; + return info_for_irq(irq)->evtchn; } @@ -405,15 +408,21 @@ static int find_unbound_irq(void) { struct irq_data *data; int irq, res; - int start = get_nr_hw_irqs(); + int bottom = get_nr_hw_irqs(); + int top = nr_irqs-1; - if (start == nr_irqs) + if (bottom == nr_irqs) goto no_irqs; - /* nr_irqs is a magic value. Must not use it.*/ - for (irq = nr_irqs-1; irq > start; irq--) { + /* This loop starts from the top of IRQ space and goes down. + * We need this b/c if we have a PCI device in a Xen PV guest + * we do not have an IO-APIC (though the backend might have them) + * mapped in. To not have a collision of physical IRQs with the Xen + * event channels start at the top of the IRQ space for virtual IRQs. + */ + for (irq = top; irq > bottom; irq--) { data = irq_get_irq_data(irq); - /* only 0->15 have init'd desc; handle irq > 16 */ + /* only 15->0 have init'd desc; handle irq > 16 */ if (!data) break; if (data->chip == &no_irq_chip) @@ -424,7 +433,7 @@ static int find_unbound_irq(void) return irq; } - if (irq == start) + if (irq == bottom) goto no_irqs; res = irq_alloc_desc_at(irq, -1); |