aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-driver.c
diff options
context:
space:
mode:
authorZhenzhong Duan <zhenzhong.duan@gmail.com>2020-11-17 13:44:09 +0800
committerBjorn Helgaas <bhelgaas@google.com>2020-11-20 17:23:35 -0600
commit3853f9123c185eb4018f5ccd3cdda5968efb5e10 (patch)
tree8f0d75dbb850b947ff1fe13012c670e6aa0e8004 /drivers/pci/pci-driver.c
parentPCI: Move pci_match_device() ahead of new_id_store() (diff)
downloadlinux-dev-3853f9123c185eb4018f5ccd3cdda5968efb5e10.tar.xz
linux-dev-3853f9123c185eb4018f5ccd3cdda5968efb5e10.zip
PCI: Avoid duplicate IDs in driver dynamic IDs list
When a device ID is written to /sys/bus/pci/drivers/.../new_id, we previously only checked the driver's static ID table for duplicates. Writing the same ID several times added it to the dynamic IDs list several times. This doesn't cause user-visible broken behavior, but remove_id_store() only removes one of the duplicate IDs, so if we add an ID several times, we would have to remove it the same number of times before it's completely gone. Fix it by calling pci_match_device(), which checks both dynamic and static IDs to avoid inserting duplicate IDs in dynamic IDs list. After fix, attempts to add an ID more than once cause an error: # echo "1af4 1041" > /sys/bus/pci/drivers/vfio-pci/new_id # echo "1af4 1041" > /sys/bus/pci/drivers/vfio-pci/new_id bash: echo: write error: File exists Link: https://lore.kernel.org/r/20201117054409.3428-3-zhenzhong.duan@gmail.com Signed-off-by: Zhenzhong Duan <zhenzhong.duan@gmail.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci-driver.c')
-rw-r--r--drivers/pci/pci-driver.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 965b3d772cdf..60b452ae6631 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -198,7 +198,7 @@ static ssize_t new_id_store(struct device_driver *driver, const char *buf,
pdev->subsystem_device = subdevice;
pdev->class = class;
- if (pci_match_id(pdrv->id_table, pdev))
+ if (pci_match_device(pdrv, pdev))
retval = -EEXIST;
kfree(pdev);