diff options
author | Marc Zyngier <maz@kernel.org> | 2021-01-23 12:27:59 +0000 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2021-01-30 01:22:31 +0100 |
commit | 4c457e8cb75eda91906a4f89fc39bde3f9a43922 (patch) | |
tree | b67981767bff8adf88f41e9759944f894a2187eb /include/linux/msi.h | |
parent | 13391c60da3308ed9980de0168f74cce6c62ac1d (diff) | |
download | linux-4c457e8cb75eda91906a4f89fc39bde3f9a43922.tar.gz linux-4c457e8cb75eda91906a4f89fc39bde3f9a43922.tar.bz2 linux-4c457e8cb75eda91906a4f89fc39bde3f9a43922.zip |
genirq/msi: Activate Multi-MSI early when MSI_FLAG_ACTIVATE_EARLY is set
When MSI_FLAG_ACTIVATE_EARLY is set (which is the case for PCI),
__msi_domain_alloc_irqs() performs the activation of the interrupt (which
in the case of PCI results in the endpoint being programmed) as soon as the
interrupt is allocated.
But it appears that this is only done for the first vector, introducing an
inconsistent behaviour for PCI Multi-MSI.
Fix it by iterating over the number of vectors allocated to each MSI
descriptor. This is easily achieved by introducing a new
"for_each_msi_vector" iterator, together with a tiny bit of refactoring.
Fixes: f3b0946d629c ("genirq/msi: Make sure PCI MSIs are activated early")
Reported-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Tested-by: Shameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/20210123122759.1781359-1-maz@kernel.org
Diffstat (limited to 'include/linux/msi.h')
-rw-r--r-- | include/linux/msi.h | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/include/linux/msi.h b/include/linux/msi.h index 360a0a7e7341..aef35fd1cf11 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -178,6 +178,12 @@ struct msi_desc { list_for_each_entry((desc), dev_to_msi_list((dev)), list) #define for_each_msi_entry_safe(desc, tmp, dev) \ list_for_each_entry_safe((desc), (tmp), dev_to_msi_list((dev)), list) +#define for_each_msi_vector(desc, __irq, dev) \ + for_each_msi_entry((desc), (dev)) \ + if ((desc)->irq) \ + for (__irq = (desc)->irq; \ + __irq < ((desc)->irq + (desc)->nvec_used); \ + __irq++) #ifdef CONFIG_IRQ_MSI_IOMMU static inline const void *msi_desc_get_iommu_cookie(struct msi_desc *desc) |