x86/IO-APIC: don't create pIRQ mapping from masked RTE

While moving our XenoLinux patches to 4.2-rc I noticed bogus "already
mapped" messages resulting from Linux (legitimately) writing RTEs with
only the mask bit set. Clearly we shouldn't even attempt to create a
pIRQ <-> IRQ mapping from such RTEs.

In the course of this I also found that the respective message isn't
really useful without also printing the pre-existing mapping. And I
noticed that map_domain_pirq() allowed IRQ0 to get through, despite us
never allowing a domain to control that interrupt.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
master commit: 669d4b85c4
master date: 2015-08-25 16:18:31 +0200
This commit is contained in:
Jan Beulich committed 2015-09-10 15:51:56 +02:00
1 parent 6657f1b596
commit 9a00f96bb0
2 files changed
+20 -12

No files matched your search

+16 -9
View File
@@ -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. */
+4 -3
View File
@@ -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;
}
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.