mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-29 05:44:11 +00:00
PCI/MSI: Warn and return error if driver enables MSI/MSI-X twice
[ Upstream commit 4c1ef72e9b
]
It is a serious driver defect to enable MSI or MSI-X more than once. Doing
so may panic the kernel as in the stack trace below:
Call Trace:
sysfs_add_one+0xa5/0xd0
create_dir+0x7c/0xe0
sysfs_create_subdir+0x1c/0x20
internal_create_group+0x6d/0x290
sysfs_create_groups+0x4a/0xa0
populate_msi_sysfs+0x1cd/0x210
pci_enable_msix+0x31c/0x3e0
igbuio_pci_open+0x72/0x300 [igb_uio]
uio_open+0xcc/0x120 [uio]
chrdev_open+0xa1/0x1e0
[...]
do_sys_open+0xf3/0x1f0
SyS_open+0x1e/0x20
system_call_fastpath+0x16/0x1b
---[ end trace 11042e2848880209 ]---
Kernel panic - not syncing: stack-protector: Kernel stack is corrupted in: ffffffffa056b4fa
We want to keep the WARN_ON() and stack trace so the driver can be fixed,
but we can avoid the kernel panic by returning an error. We may still get
warnings like this:
Call Trace:
pci_enable_msix+0x3c9/0x3e0
igbuio_pci_open+0x72/0x300 [igb_uio]
uio_open+0xcc/0x120 [uio]
chrdev_open+0xa1/0x1e0
[...]
do_sys_open+0xf3/0x1f0
SyS_open+0x1e/0x20
system_call_fastpath+0x16/0x1b
------------[ cut here ]------------
WARNING: at fs/sysfs/dir.c:526 sysfs_add_one+0xa5/0xd0()
sysfs: cannot create duplicate filename '/devices/pci0000:00/0000:00:03.0/0000:01:00.1/msi_irqs'
Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com>
[bhelgaas: changelog, fix patch whitespace, remove !!]
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
4e1fabddcf
commit
a8433138c4
1 changed files with 6 additions and 3 deletions
|
@ -981,7 +981,6 @@ static int __pci_enable_msix(struct pci_dev *dev, struct msix_entry *entries,
|
|||
}
|
||||
}
|
||||
}
|
||||
WARN_ON(!!dev->msix_enabled);
|
||||
|
||||
/* Check whether driver already requested for MSI irq */
|
||||
if (dev->msi_enabled) {
|
||||
|
@ -1068,8 +1067,6 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
|||
if (!pci_msi_supported(dev, minvec))
|
||||
return -EINVAL;
|
||||
|
||||
WARN_ON(!!dev->msi_enabled);
|
||||
|
||||
/* Check whether driver already requested MSI-X irqs */
|
||||
if (dev->msix_enabled) {
|
||||
dev_info(&dev->dev,
|
||||
|
@ -1080,6 +1077,9 @@ static int __pci_enable_msi_range(struct pci_dev *dev, int minvec, int maxvec,
|
|||
if (maxvec < minvec)
|
||||
return -ERANGE;
|
||||
|
||||
if (WARN_ON_ONCE(dev->msi_enabled))
|
||||
return -EINVAL;
|
||||
|
||||
nvec = pci_msi_vec_count(dev);
|
||||
if (nvec < 0)
|
||||
return nvec;
|
||||
|
@ -1138,6 +1138,9 @@ static int __pci_enable_msix_range(struct pci_dev *dev,
|
|||
if (maxvec < minvec)
|
||||
return -ERANGE;
|
||||
|
||||
if (WARN_ON_ONCE(dev->msix_enabled))
|
||||
return -EINVAL;
|
||||
|
||||
for (;;) {
|
||||
if (affinity) {
|
||||
nvec = irq_calc_affinity_vectors(dev->irq_affinity,
|
||||
|
|
Loading…
Reference in a new issue