Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
xen.787
5513dd4d-x86-MSI-fix-error-handling.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 5513dd4d-x86-MSI-fix-error-handling.patch of Package xen.787
# Commit 29c1b7886c36d4e6aa03a779b2251b829d9689c3 # Date 2015-03-26 11:19:57 +0100 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> x86/MSI: fix error handling __setup_msi_irq() needs to undo what it did before calling write_msi_msg() in case that returned an error. map_domain_pirq() needs to get rid of the MSI descriptor it (implicitly) allocated. The case of a setup_msi_irq() failure on a non-initial multi-vector-MSI interrupt needs special handling: While the initial IRQ will get freed by the caller (who also passed it to us), we need to undo the effect setup_msi_irq() had on it. (As a benefit from the added call to msi_free_irq() we no longer need to explicitly call destroy_irq() on the non-initial slots.) Signed-off-by: Jan Beulich <jbeulich@suse.com> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -1971,6 +1971,8 @@ int map_domain_pirq( dprintk(XENLOG_G_ERR, "dom%d: irq %d in use\n", d->domain_id, irq); pci_disable_msi(msi_desc); + msi_desc->irq = -1; + msi_free_irq(msi_desc); ret = -EBUSY; goto done; } @@ -2025,22 +2027,29 @@ int map_domain_pirq( if ( ret ) { spin_unlock_irqrestore(&desc->lock, flags); + pci_disable_msi(msi_desc); + if ( nr ) + { + ASSERT(msi_desc->irq >= 0); + desc = irq_to_desc(msi_desc->irq); + spin_lock_irqsave(&desc->lock, flags); + desc->handler = &no_irq_type; + desc->msi_desc = NULL; + spin_unlock_irqrestore(&desc->lock, flags); + } while ( nr-- ) { - if ( irq >= 0 ) - { - if ( 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); - destroy_irq(irq); - } + 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 ) cleanup_domain_irq_pirq(d, irq, info); info = pirq_info(d, pirq + nr); irq = info->arch.irq; } - pci_disable_msi(msi_desc); + msi_desc->irq = -1; + msi_free_irq(msi_desc); goto done; } --- a/xen/arch/x86/msi.c +++ b/xen/arch/x86/msi.c @@ -470,6 +470,7 @@ static struct msi_desc *alloc_msi_entry( while ( nr-- ) { entry[nr].dev = NULL; + entry[nr].irq = -1; entry[nr].remap_index = -1; } @@ -487,11 +488,19 @@ int __setup_msi_irq(struct irq_desc *des hw_irq_controller *handler) { struct msi_msg msg; + int ret; desc->msi_desc = msidesc; desc->handler = handler; msi_compose_msg(desc->arch.vector, desc->arch.cpu_mask, &msg); - return write_msi_msg(msidesc, &msg); + ret = write_msi_msg(msidesc, &msg); + if ( unlikely(ret) ) + { + desc->handler = &no_irq_type; + desc->msi_desc = NULL; + } + + return ret; } int msi_free_irq(struct msi_desc *entry) @@ -501,7 +510,8 @@ int msi_free_irq(struct msi_desc *entry) while ( nr-- ) { - destroy_irq(entry[nr].irq); + if ( entry[nr].irq >= 0 ) + destroy_irq(entry[nr].irq); /* Free the unused IRTE if intr remap enabled */ if ( iommu_intremap )
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor