Re: [PATCH] PCI: Fix pcim_iomap_regions() error path rollback and leak
From: Bjorn Helgaas
Date: Mon Nov 09 2026 - 18:39:10 EST
On Mon, Nov 09, 2026 at 07:31:36PM +0800, lirongqing wrote:
> From: Li RongQing <lirongqing@xxxxxxxxx>
>
> pcim_iomap_regions() has two problems in its error path.
>
> First, the rollback loop walks every bar index below the failing one
> and unmaps it, regardless of whether that bar is in the mask this call
> was asked to map. pcim_iounmap_region() matches devres entries by
> (type, bar) only, so it can release a mapping that an earlier
> pcim_iomap_region()/pcim_iomap_regions() call made. The driver is then
> left with an __iomem pointer that has been unmapped and a legacy table
> entry cleared. Restrict the rollback to bars in mask.
>
> Second, when pcim_add_mapping_to_legacy_table() fails, the current
> bar's mapping is not released: the rollback loop starts at --bar, so
> the failing bar itself is skipped, and the mapping stays registered
> until the driver detaches. Release it on this path as well.
>
> Fixes: bbaff68bf4a4 ("PCI: Add managed partial-BAR request and map infrastructure")
> Signed-off-by: Li RongQing <lirongqing@xxxxxxxxx>
Hoping for a Reviewed-by from Philipp.
If there's a v2, s/bar/BAR/ above to match other usage. If no v2,
I'll tweak that when applying.
> ---
> drivers/pci/devres.c | 6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/pci/devres.c b/drivers/pci/devres.c
> index f075e78..9bdb4de 100644
> --- a/drivers/pci/devres.c
> +++ b/drivers/pci/devres.c
> @@ -689,14 +689,18 @@ int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name)
> goto err;
> }
> ret = pcim_add_mapping_to_legacy_table(pdev, mapping, bar);
> - if (ret != 0)
> + if (ret != 0) {
> + pcim_iounmap_region(pdev, bar);
> goto err;
> + }
> }
>
> return 0;
>
> err:
> while (--bar >= 0) {
> + if (!mask_contains_bar(mask, bar))
> + continue;
> pcim_iounmap_region(pdev, bar);
> pcim_remove_bar_from_legacy_table(pdev, bar);
> }
> --
> 2.9.4
>