diff options
Diffstat (limited to 'drivers/xen/events.c')
-rw-r--r-- | drivers/xen/events.c | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 31af0ac31a98..4d4a23d4c9f6 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c | |||
@@ -405,15 +405,21 @@ static int find_unbound_irq(void) | |||
405 | { | 405 | { |
406 | struct irq_data *data; | 406 | struct irq_data *data; |
407 | int irq, res; | 407 | int irq, res; |
408 | int start = get_nr_hw_irqs(); | 408 | int bottom = get_nr_hw_irqs(); |
409 | int top = nr_irqs-1; | ||
409 | 410 | ||
410 | if (start == nr_irqs) | 411 | if (bottom == nr_irqs) |
411 | goto no_irqs; | 412 | goto no_irqs; |
412 | 413 | ||
413 | /* nr_irqs is a magic value. Must not use it.*/ | 414 | /* This loop starts from the top of IRQ space and goes down. |
414 | for (irq = nr_irqs-1; irq > start; irq--) { | 415 | * We need this b/c if we have a PCI device in a Xen PV guest |
416 | * we do not have an IO-APIC (though the backend might have them) | ||
417 | * mapped in. To not have a collision of physical IRQs with the Xen | ||
418 | * event channels start at the top of the IRQ space for virtual IRQs. | ||
419 | */ | ||
420 | for (irq = top; irq > bottom; irq--) { | ||
415 | data = irq_get_irq_data(irq); | 421 | data = irq_get_irq_data(irq); |
416 | /* only 0->15 have init'd desc; handle irq > 16 */ | 422 | /* only 15->0 have init'd desc; handle irq > 16 */ |
417 | if (!data) | 423 | if (!data) |
418 | break; | 424 | break; |
419 | if (data->chip == &no_irq_chip) | 425 | if (data->chip == &no_irq_chip) |
@@ -424,7 +430,7 @@ static int find_unbound_irq(void) | |||
424 | return irq; | 430 | return irq; |
425 | } | 431 | } |
426 | 432 | ||
427 | if (irq == start) | 433 | if (irq == bottom) |
428 | goto no_irqs; | 434 | goto no_irqs; |
429 | 435 | ||
430 | res = irq_alloc_desc_at(irq, -1); | 436 | res = irq_alloc_desc_at(irq, -1); |