[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.9] x86/IRQ: conditionally preserve irq <-> pirq mapping on map error paths
commit ae454429648edfa2d3c17082fcded405a6cc4dcc Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Thu Oct 12 15:03:53 2017 +0200 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Thu Oct 12 15:03:53 2017 +0200 x86/IRQ: conditionally preserve irq <-> pirq mapping on map error paths Mappings that had been set up before should not be torn down when handling unrelated errors. This is part of XSA-237. Reported-by: HW42 <hw42@xxxxxxxxx> Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: George Dunlap <george.dunlap@xxxxxxxxxx> master commit: 573ac7b22aba9e5b8d40d9cdccd744af57cd5928 master date: 2017-10-12 14:37:26 +0200 --- xen/arch/x86/irq.c | 25 ++++++++++++++++++------- xen/arch/x86/physdev.c | 2 +- xen/include/asm-x86/msi.h | 2 ++ 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 3e94571..9c1556c 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1251,7 +1251,8 @@ static int prepare_domain_irq_pirq(struct domain *d, int irq, int pirq, return -ENOMEM; } *pinfo = info; - return 0; + + return !!err; } static void set_domain_irq_pirq(struct domain *d, int irq, struct pirq *pirq) @@ -1294,7 +1295,10 @@ int init_domain_irq_mapping(struct domain *d) continue; err = prepare_domain_irq_pirq(d, i, i, &info); if ( err ) + { + ASSERT(err < 0); break; + } set_domain_irq_pirq(d, i, info); } @@ -1902,6 +1906,7 @@ int map_domain_pirq( struct pirq *info; struct irq_desc *desc; unsigned long flags; + DECLARE_BITMAP(prepared, MAX_MSI_IRQS) = {}; ASSERT(spin_is_locked(&d->event_lock)); @@ -1945,8 +1950,10 @@ int map_domain_pirq( } ret = prepare_domain_irq_pirq(d, irq, pirq, &info); - if ( ret ) + if ( ret < 0 ) goto revoke; + if ( !ret ) + __set_bit(0, prepared); desc = irq_to_desc(irq); @@ -2018,8 +2025,10 @@ int map_domain_pirq( irq = create_irq(NUMA_NO_NODE); ret = irq >= 0 ? prepare_domain_irq_pirq(d, irq, pirq + nr, &info) : irq; - if ( ret ) + if ( ret < 0 ) break; + if ( !ret ) + __set_bit(nr, prepared); msi_desc[nr].irq = irq; if ( irq_permit_access(d, irq) != 0 ) @@ -2052,15 +2061,15 @@ int map_domain_pirq( desc->msi_desc = NULL; spin_unlock_irqrestore(&desc->lock, flags); } - while ( nr-- ) + while ( nr ) { if ( irq >= 0 && irq_deny_access(d, irq) ) printk(XENLOG_G_ERR "dom%d: could not revoke access to IRQ%d (pirq %d)\n", d->domain_id, irq, pirq); - if ( info ) + if ( info && test_bit(nr, prepared) ) cleanup_domain_irq_pirq(d, irq, info); - info = pirq_info(d, pirq + nr); + info = pirq_info(d, pirq + --nr); irq = info->arch.irq; } msi_desc->irq = -1; @@ -2076,12 +2085,14 @@ int map_domain_pirq( spin_lock_irqsave(&desc->lock, flags); set_domain_irq_pirq(d, irq, info); spin_unlock_irqrestore(&desc->lock, flags); + ret = 0; } done: if ( ret ) { - cleanup_domain_irq_pirq(d, irq, info); + if ( test_bit(0, prepared) ) + cleanup_domain_irq_pirq(d, irq, info); revoke: if ( irq_deny_access(d, irq) ) printk(XENLOG_G_ERR diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 76a197a..82f59d7 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -186,7 +186,7 @@ int physdev_map_pirq(domid_t domid, int type, int *index, int *pirq_p, } else if ( type == MAP_PIRQ_TYPE_MULTI_MSI ) { - if ( msi->entry_nr <= 0 || msi->entry_nr > 32 ) + if ( msi->entry_nr <= 0 || msi->entry_nr > MAX_MSI_IRQS ) ret = -EDOM; else if ( msi->entry_nr != 1 && !iommu_intremap ) ret = -EOPNOTSUPP; diff --git a/xen/include/asm-x86/msi.h b/xen/include/asm-x86/msi.h index a5de6a1..434173d 100644 --- a/xen/include/asm-x86/msi.h +++ b/xen/include/asm-x86/msi.h @@ -56,6 +56,8 @@ /* MAX fixed pages reserved for mapping MSIX tables. */ #define FIX_MSIX_MAX_PAGES 512 +#define MAX_MSI_IRQS 32 /* limited by MSI capability struct properties */ + struct msi_info { u16 seg; u8 bus; -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.9 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |