On Sat, 11 Apr 2026, Krzysztof Wilczyński wrote:

> Currently, when the sysfs attributes for PCI resources are added
> dynamically, the resource access callbacks are only set when the
> underlying BAR type matches, using .read and .write for IORESOURCE_IO,
> and .mmap for IORESOURCE_MEM or IORESOURCE_IO with arch_can_pci_mmap_io()
> support.  As such, when the callback is not set, the operation inherently
> fails.
> 
> After the conversion to static attributes, visibility callbacks will
> control which resource files appear for each BAR, but the callbacks
> themselves will always be set.
> 
> Thus, add a type check to pci_resource_io() and pci_mmap_resource()
> to return -EIO for an unsupported resource type.
> 
> Use the new pci_resource_is_io() and pci_resource_is_mem() helpers
> for the type checks, replacing the open-coded bitwise flag tests and
> also drop the local struct resource pointer in pci_mmap_resource().
> 
> Signed-off-by: Krzysztof Wilczyński <[email protected]>
> ---
>  drivers/pci/pci-sysfs.c | 13 ++++++++++---
>  1 file changed, 10 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index ad3c17f86c7f..6783c6168445 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -1108,20 +1108,24 @@ static int pci_mmap_resource(struct kobject *kobj, 
> const struct bin_attribute *a
>       struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
>       int bar = (unsigned long)attr->private;
>       enum pci_mmap_state mmap_type;
> -     struct resource *res = pci_resource_n(pdev, bar);
>       int ret;
>  
>       ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
>       if (ret)
>               return ret;
>  
> -     if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
> +     if (!pci_resource_is_mem(pdev, bar) &&
> +         !(pci_resource_is_io(pdev, bar) && arch_can_pci_mmap_io()))
> +             return -EIO;
> +
> +     if (pci_resource_is_mem(pdev, bar) &&
> +         iomem_is_exclusive(pci_resource_start(pdev, bar)))
>               return -EINVAL;
>  
>       if (!pci_mmap_fits(pdev, bar, vma, PCI_MMAP_SYSFS))
>               return -EINVAL;
>  
> -     mmap_type = res->flags & IORESOURCE_MEM ? pci_mmap_mem : pci_mmap_io;
> +     mmap_type = pci_resource_is_mem(pdev, bar) ? pci_mmap_mem : pci_mmap_io;
>  
>       return pci_mmap_resource_range(pdev, bar, vma, mmap_type, 
> write_combine);
>  }
> @@ -1149,6 +1153,9 @@ static ssize_t pci_resource_io(struct file *filp, 
> struct kobject *kobj,
>       int bar = (unsigned long)attr->private;
>       unsigned long port = off;
>  
> +     if (!pci_resource_is_io(pdev, bar))
> +             return -EIO;
> +
>       port += pci_resource_start(pdev, bar);
>  
>       if (port > pci_resource_end(pdev, bar))
> 

Reviewed-by: Ilpo Järvinen <[email protected]>

-- 
 i.

Reply via email to