diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 8f41a06b93..3ab29b03ac 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -2370,9 +2370,14 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) * pirq and irq mapping. Where the GSI is greater than 256, we assume * that dom0 pirq == irq. */ - pirq = (irq >= 256) ? irq : rte.vector; - if ( (pirq < 0) || (pirq >= dom0->nr_pirqs) ) - return -EINVAL; + if ( !rte.mask ) + { + pirq = (irq >= 256) ? irq : rte.vector; + if ( pirq >= dom0->nr_pirqs ) + return -EINVAL; + } + else + pirq = -1; if ( desc->action ) { @@ -2407,12 +2412,14 @@ int ioapic_guest_write(unsigned long physbase, unsigned int reg, u32 val) printk(XENLOG_INFO "allocated vector %02x for irq %d\n", ret, irq); } - spin_lock(&dom0->event_lock); - ret = map_domain_pirq(dom0, pirq, irq, - MAP_PIRQ_TYPE_GSI, NULL); - spin_unlock(&dom0->event_lock); - if ( ret < 0 ) - return ret; + if ( pirq >= 0 ) + { + spin_lock(&dom0->event_lock); + ret = map_domain_pirq(dom0, pirq, irq, MAP_PIRQ_TYPE_GSI, NULL); + spin_unlock(&dom0->event_lock); + if ( ret < 0 ) + return ret; + } spin_lock_irqsave(&ioapic_lock, flags); /* Set the correct irq-handling type. */ diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 194d508143..77aded76c3 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1897,7 +1897,7 @@ int map_domain_pirq( if ( !irq_access_permitted(current->domain, irq)) return -EPERM; - if ( pirq < 0 || pirq >= d->nr_pirqs || irq < 0 || irq >= nr_irqs ) + if ( pirq < 0 || pirq >= d->nr_pirqs || irq <= 0 || irq >= nr_irqs ) { dprintk(XENLOG_G_ERR, "dom%d: invalid pirq %d or irq %d\n", d->domain_id, pirq, irq); @@ -1910,8 +1910,9 @@ int map_domain_pirq( if ( (old_irq > 0 && (old_irq != irq) ) || (old_pirq && (old_pirq != pirq)) ) { - dprintk(XENLOG_G_WARNING, "dom%d: pirq %d or irq %d already mapped\n", - d->domain_id, pirq, irq); + dprintk(XENLOG_G_WARNING, + "dom%d: pirq %d or irq %d already mapped (%d,%d)\n", + d->domain_id, pirq, irq, old_pirq, old_irq); return 0; }