CVE-2026-46235
Description
In the Linux kernel, the following vulnerability has been resolved:
media: saa7164: add ioremap return checks and cleanups
Add checks for ioremap return values in saa7164_dev_setup(). If ioremap for BAR0 or BAR2 fails, release the already allocated PCI memory regions, remove the device from the global list, decrement the device count, and return -ENODEV.
This prevents potential null pointer dereferences and ensures proper cleanup on memory mapping failures.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing ioremap return checks in the Linux kernel's saa7164 driver could lead to null pointer dereference; a fix adds proper validation and cleanup.
Vulnerability
In the Linux kernel's saa7164 media driver, the saa7164_dev_setup() function did not check the return values of ioremap() calls for BAR0 and BAR2. If either memory mapping failed, the driver would proceed with a null pointer, leading to a potential null pointer dereference. The affected code is present in the kernel prior to the fix introduced by commit d51c60a498e8 [1].
Exploitation
An attacker would need to trigger a failure of ioremap() for the device's BAR0 or BAR2 regions. This could occur if the system runs out of I/O memory or if the PCI device is misconfigured. No special privileges are required beyond the ability to load or use the saa7164 driver; the vulnerability is reachable during normal device initialization.
Impact
If ioremap() fails and the return value is not checked, the driver may dereference a null pointer, causing a kernel crash (denial of service). The fix prevents this by returning -ENODEV and properly cleaning up allocated resources, avoiding the null dereference [1].
Mitigation
The fix is included in the Linux kernel as of commit d51c60a498e8 (stable) [1]. Users should update to a kernel version containing this commit. No workaround is available; the only mitigation is to apply the patch or upgrade the kernel.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
10d51c60a498e8media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
6047dc542fa4media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
6c22a6d8e4c1media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
3ce8f3057c51media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
a9b83f46e52cmedia: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
3ce8f3057c51media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
6c22a6d8e4c1media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
d51c60a498e8media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index 74406d5ea0a507..6bcde506adf506 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
a9b83f46e52cmedia: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
6047dc542fa4media: saa7164: add ioremap return checks and cleanups
2 files changed · +70 −26
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
drivers/media/pci/saa7164/saa7164-core.c+35 −13 modifieddiff --git a/drivers/media/pci/saa7164/saa7164-core.c b/drivers/media/pci/saa7164/saa7164-core.c index a8a004f28ca0e2..ac290f5464131b 100644 --- a/drivers/media/pci/saa7164/saa7164-core.c +++ b/drivers/media/pci/saa7164/saa7164-core.c @@ -888,6 +888,15 @@ static int get_resources(struct saa7164_dev *dev) return -EBUSY; } +static void release_resources(struct saa7164_dev *dev) +{ + release_mem_region(pci_resource_start(dev->pci, 0), + pci_resource_len(dev->pci, 0)); + + release_mem_region(pci_resource_start(dev->pci, 2), + pci_resource_len(dev->pci, 2)); +} + static int saa7164_port_init(struct saa7164_dev *dev, int portnr) { struct saa7164_port *port = NULL; @@ -947,9 +956,9 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) snprintf(dev->name, sizeof(dev->name), "saa7164[%d]", dev->nr); - mutex_lock(&devlist); - list_add_tail(&dev->devlist, &saa7164_devlist); - mutex_unlock(&devlist); + scoped_guard(mutex, &devlist) { + list_add_tail(&dev->devlist, &saa7164_devlist); + } /* board config */ dev->board = UNSET; @@ -996,11 +1005,17 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) } /* PCI/e allocations */ - dev->lmmio = ioremap(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); + dev->lmmio = pci_ioremap_bar(dev->pci, 0); + if (!dev->lmmio) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 0\n"); + goto err_ioremap_bar0; + } - dev->lmmio2 = ioremap(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + dev->lmmio2 = pci_ioremap_bar(dev->pci, 2); + if (!dev->lmmio2) { + dev_err(&dev->pci->dev, "Failed to remap MMIO BAR 2\n"); + goto err_ioremap_bar2; + } dev->bmmio = (u8 __iomem *)dev->lmmio; dev->bmmio2 = (u8 __iomem *)dev->lmmio2; @@ -1019,17 +1034,25 @@ static int saa7164_dev_setup(struct saa7164_dev *dev) saa7164_pci_quirks(dev); return 0; + +err_ioremap_bar2: + iounmap(dev->lmmio); +err_ioremap_bar0: + release_resources(dev); + + scoped_guard(mutex, &devlist) { + list_del(&dev->devlist); + } + saa7164_devcount--; + + return -ENODEV; } static void saa7164_dev_unregister(struct saa7164_dev *dev) { dprintk(1, "%s()\n", __func__); - release_mem_region(pci_resource_start(dev->pci, 0), - pci_resource_len(dev->pci, 0)); - - release_mem_region(pci_resource_start(dev->pci, 2), - pci_resource_len(dev->pci, 2)); + release_resources(dev); if (!atomic_dec_and_test(&dev->refcount)) return; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing return-value check on ioremap (pci_ioremap_bar) calls in saa7164_dev_setup() allows a null pointer to be stored and later dereferenced."
Attack vector
An attacker with physical or local PCIe access to a system using the saa7164 driver could trigger a failure of pci_ioremap_bar for BAR0 or BAR2 (e.g., by causing a memory-mapping error). Because the original code did not check the return value of ioremap, a NULL pointer would be stored in dev->lmmio or dev->lmmio2. Subsequent MMIO accesses through those pointers would cause a null pointer dereference, leading to a kernel crash or denial of service [patch_id=2897527].
Affected code
The vulnerable code is in drivers/media/pci/saa7164/saa7164-core.c, in the function saa7164_dev_setup(), specifically the ioremap calls for BAR0 and BAR2 (lines ~996-1002 in the original file) [patch_id=2897527]. The patch also introduces a new helper function release_resources() and refactors the error-unregister path in saa7164_dev_unregister() to use it.
What the fix does
The patch adds explicit NULL checks after each pci_ioremap_bar call in saa7164_dev_setup() [patch_id=2897527]. If BAR0 mapping fails, the code jumps to err_ioremap_bar0, which calls the new release_resources() helper to release the PCI memory regions, removes the device from the global list, decrements the device count, and returns -ENODEV. If BAR2 mapping fails after BAR0 succeeded, it jumps to err_ioremap_bar2, which first unmaps BAR0 via iounmap, then falls through to the same cleanup path. This ensures proper rollback and prevents use of a NULL iomem pointer.
Preconditions
- configThe system must have a saa7164-based PCI device present and the driver must be loaded.
- inputThe ioremap/pci_ioremap_bar call for BAR0 or BAR2 must fail (e.g., due to memory pressure or hardware misconfiguration).
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/3ce8f3057c51bb0a66aa3fab0862be74e9f88684nvd
- git.kernel.org/stable/c/6047dc542fa404b5c187cc2c7906aaaaec6d11ednvd
- git.kernel.org/stable/c/6c22a6d8e4c1507bba504aeebe80476144a373ebnvd
- git.kernel.org/stable/c/a9b83f46e52cf1239d780920d1a7a3e415f7b5d9nvd
- git.kernel.org/stable/c/d51c60a498e83c9a79884c8e420f97e3885c9583nvd
News mentions
0No linked articles in our index yet.