* [PATCH 01/20] PCI/sysfs: Use PCI resource accessor macros
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 10:20 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 02/20] PCI/sysfs: Only allow supported resource types in I/O and MMIO helpers Krzysztof Wilczyński
` (19 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Replace direct pdev->resource[] accesses with pci_resource_n(),
and pdev->resource[].flags accesses with pci_resource_flags().
No functional changes intended.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 16eaaf749ba9..ad3c17f86c7f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -177,7 +177,7 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
max = PCI_BRIDGE_RESOURCES;
for (i = 0; i < max; i++) {
- struct resource *res = &pci_dev->resource[i];
+ struct resource *res = pci_resource_n(pci_dev, i);
struct resource zerores = {};
/* For backwards compatibility */
@@ -715,7 +715,7 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
return sysfs_emit(buf, "%u\n", (pdev == vga_dev));
return sysfs_emit(buf, "%u\n",
- !!(pdev->resource[PCI_ROM_RESOURCE].flags &
+ !!(pci_resource_flags(pdev, PCI_ROM_RESOURCE) &
IORESOURCE_ROM_SHADOW));
}
static DEVICE_ATTR_RO(boot_vga);
@@ -1108,7 +1108,7 @@ 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 = &pdev->resource[bar];
+ struct resource *res = pci_resource_n(pdev, bar);
int ret;
ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
@@ -1312,7 +1312,7 @@ static int pci_create_resource_files(struct pci_dev *pdev)
retval = pci_create_attr(pdev, i, 0);
/* for prefetchable resources, create a WC mappable file */
if (!retval && arch_can_pci_mmap_wc() &&
- pdev->resource[i].flags & IORESOURCE_PREFETCH)
+ pci_resource_flags(pdev, i) & IORESOURCE_PREFETCH)
retval = pci_create_attr(pdev, i, 1);
if (retval) {
pci_remove_resource_files(pdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 01/20] PCI/sysfs: Use PCI resource accessor macros
2026-04-10 5:50 ` [PATCH 01/20] PCI/sysfs: Use PCI resource accessor macros Krzysztof Wilczyński
@ 2026-04-10 10:20 ` Ilpo Järvinen
0 siblings, 0 replies; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 10:20 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2297 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Replace direct pdev->resource[] accesses with pci_resource_n(),
> and pdev->resource[].flags accesses with pci_resource_flags().
>
> No functional changes intended.
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> drivers/pci/pci-sysfs.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index 16eaaf749ba9..ad3c17f86c7f 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -177,7 +177,7 @@ static ssize_t resource_show(struct device *dev, struct device_attribute *attr,
> max = PCI_BRIDGE_RESOURCES;
>
> for (i = 0; i < max; i++) {
> - struct resource *res = &pci_dev->resource[i];
> + struct resource *res = pci_resource_n(pci_dev, i);
> struct resource zerores = {};
>
> /* For backwards compatibility */
> @@ -715,7 +715,7 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
> return sysfs_emit(buf, "%u\n", (pdev == vga_dev));
>
> return sysfs_emit(buf, "%u\n",
> - !!(pdev->resource[PCI_ROM_RESOURCE].flags &
> + !!(pci_resource_flags(pdev, PCI_ROM_RESOURCE) &
> IORESOURCE_ROM_SHADOW));
> }
> static DEVICE_ATTR_RO(boot_vga);
> @@ -1108,7 +1108,7 @@ 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 = &pdev->resource[bar];
> + struct resource *res = pci_resource_n(pdev, bar);
> int ret;
>
> ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
> @@ -1312,7 +1312,7 @@ static int pci_create_resource_files(struct pci_dev *pdev)
> retval = pci_create_attr(pdev, i, 0);
> /* for prefetchable resources, create a WC mappable file */
> if (!retval && arch_can_pci_mmap_wc() &&
> - pdev->resource[i].flags & IORESOURCE_PREFETCH)
> + pci_resource_flags(pdev, i) & IORESOURCE_PREFETCH)
> retval = pci_create_attr(pdev, i, 1);
> if (retval) {
> pci_remove_resource_files(pdev);
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 02/20] PCI/sysfs: Only allow supported resource types in I/O and MMIO helpers
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 01/20] PCI/sysfs: Use PCI resource accessor macros Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 03/20] PCI/sysfs: Use BAR length in pci_llseek_resource() when attr->size is zero Krzysztof Wilczyński
` (18 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
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.
While at it, add parentheses around the bitwise flag test in
pci_mmap_resource() to make the precedence explicit, and to
match the preferred style.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ad3c17f86c7f..008e0dd0de36 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1115,13 +1115,17 @@ static int pci_mmap_resource(struct kobject *kobj, const struct bin_attribute *a
if (ret)
return ret;
- if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+ if (!(res->flags & IORESOURCE_MEM) &&
+ !((res->flags & IORESOURCE_IO) && arch_can_pci_mmap_io()))
+ return -EIO;
+
+ if ((res->flags & IORESOURCE_MEM) && iomem_is_exclusive(res->start))
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 = (res->flags & IORESOURCE_MEM) ? 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_flags(pdev, bar) & IORESOURCE_IO))
+ return -EIO;
+
port += pci_resource_start(pdev, bar);
if (port > pci_resource_end(pdev, bar))
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 03/20] PCI/sysfs: Use BAR length in pci_llseek_resource() when attr->size is zero
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 01/20] PCI/sysfs: Use PCI resource accessor macros Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 02/20] PCI/sysfs: Only allow supported resource types in I/O and MMIO helpers Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 04/20] PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store() Krzysztof Wilczyński
` (17 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Both legacy and resource attributes set .f_mapping = iomem_get_mapping,
so the default generic_file_llseek() would consult iomem_inode for the
file size, which knows nothing about the attribute. That is why this
custom llseek callback exists.
Currently, the legacy and resource attributes have .size set at creation
time, as such, using the attr->size is sufficient. However, the upcoming
static resource attributes will have .size == 0 set, since they are const,
and the .bin_size callback will be used to provide the real size to kernfs
instead.
Thus, update pci_llseek_resource() to derive the file size from the
BAR using pci_resource_len() instead of reading the attr->size directly.
The custom pci_llseek_resource() helper has been added in commit
24de09c16f97 ("PCI: Implement custom llseek for sysfs resource
entries").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 008e0dd0de36..ac4e7c516e78 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -909,11 +909,21 @@ static const struct attribute_group pci_dev_config_attr_group = {
*/
static __maybe_unused loff_t
pci_llseek_resource(struct file *filep,
- struct kobject *kobj __always_unused,
+ struct kobject *kobj,
const struct bin_attribute *attr,
loff_t offset, int whence)
{
- return fixed_size_llseek(filep, offset, whence, attr->size);
+ struct pci_dev *pdev;
+ int bar;
+
+ if (attr->size)
+ return fixed_size_llseek(filep, offset, whence, attr->size);
+
+ pdev = to_pci_dev(kobj_to_dev(kobj));
+ bar = (unsigned long)attr->private;
+
+ return fixed_size_llseek(filep, offset, whence,
+ pci_resource_len(pdev, bar));
}
#ifdef HAVE_PCI_LEGACY
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 04/20] PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (2 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 03/20] PCI/sysfs: Use BAR length in pci_llseek_resource() when attr->size is zero Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 10:18 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 05/20] PCI/sysfs: Add static PCI resource attribute macros Krzysztof Wilczyński
` (16 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, the __resource_resize_store() allows writing to the
resourceN_resize sysfs attribute to change a BAR's size without
checking for capabilities, currently relying only on the file
access check.
Resizing a BAR modifies PCI device configuration and can disrupt
active drivers. After the upcoming conversion to static attributes,
it will also trigger resource file updates via sysfs_update_groups().
Thus, add a CAP_SYS_ADMIN check to prevent unprivileged users from
performing BAR resize operations.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index ac4e7c516e78..6b8c8e62f68a 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1619,6 +1619,9 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
int ret;
u16 cmd;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
if (kstrtoul(buf, 0, &size) < 0)
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 04/20] PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store()
2026-04-10 5:50 ` [PATCH 04/20] PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store() Krzysztof Wilczyński
@ 2026-04-10 10:18 ` Ilpo Järvinen
0 siblings, 0 replies; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 10:18 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1251 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Currently, the __resource_resize_store() allows writing to the
> resourceN_resize sysfs attribute to change a BAR's size without
> checking for capabilities, currently relying only on the file
> access check.
>
> Resizing a BAR modifies PCI device configuration and can disrupt
> active drivers. After the upcoming conversion to static attributes,
> it will also trigger resource file updates via sysfs_update_groups().
>
> Thus, add a CAP_SYS_ADMIN check to prevent unprivileged users from
> performing BAR resize operations.
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> drivers/pci/pci-sysfs.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index ac4e7c516e78..6b8c8e62f68a 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -1619,6 +1619,9 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
> int ret;
> u16 cmd;
>
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> if (kstrtoul(buf, 0, &size) < 0)
> return -EINVAL;
>
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 05/20] PCI/sysfs: Add static PCI resource attribute macros
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (3 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 04/20] PCI/sysfs: Add CAP_SYS_ADMIN check to __resource_resize_store() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
` (15 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Add three macros for declaring static binary attributes for PCI
resource files:
- pci_dev_resource_io_attr(), for I/O BAR resources (read/write)
- pci_dev_resource_uc_attr(), for memory BAR resources (mmap uncached)
- pci_dev_resource_wc_attr(), for write-combine resources (mmap WC)
Each macro only sets the callbacks its resource type needs. The I/O
macro conditionally includes mmap support via __PCI_RESOURCE_IO_MMAP_ATTRS
on architectures where arch_can_pci_mmap_io() is true at compile time
(such as PowerPC, SPARC, and Xtensa).
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 6b8c8e62f68a..d29d79be8ee5 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1220,6 +1220,47 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
return pci_resource_io(filp, kobj, attr, buf, off, count, true);
}
+/*
+ * generic_file_llseek() consults f_mapping->host to determine
+ * the file size. As iomem_inode knows nothing about the
+ * attribute, it's not going to work, so override it as well.
+ */
+#if arch_can_pci_mmap_io()
+# define __PCI_RESOURCE_IO_MMAP_ATTRS \
+ .f_mapping = iomem_get_mapping, \
+ .llseek = pci_llseek_resource, \
+ .mmap = pci_mmap_resource_uc,
+#else
+# define __PCI_RESOURCE_IO_MMAP_ATTRS
+#endif
+
+#define pci_dev_resource_io_attr(_bar) \
+static const struct bin_attribute dev_resource##_bar##_io_attr = { \
+ .attr = { .name = "resource" __stringify(_bar), .mode = 0600 }, \
+ .private = (void *)(unsigned long)(_bar), \
+ .read = pci_read_resource, \
+ .write = pci_write_resource, \
+ __PCI_RESOURCE_IO_MMAP_ATTRS \
+}
+
+#define pci_dev_resource_uc_attr(_bar) \
+static const struct bin_attribute dev_resource##_bar##_uc_attr = { \
+ .attr = { .name = "resource" __stringify(_bar), .mode = 0600 }, \
+ .private = (void *)(unsigned long)(_bar), \
+ .f_mapping = iomem_get_mapping, \
+ .llseek = pci_llseek_resource, \
+ .mmap = pci_mmap_resource_uc, \
+}
+
+#define pci_dev_resource_wc_attr(_bar) \
+static const struct bin_attribute dev_resource##_bar##_wc_attr = { \
+ .attr = { .name = "resource" __stringify(_bar) "_wc", .mode = 0600 }, \
+ .private = (void *)(unsigned long)(_bar), \
+ .f_mapping = iomem_get_mapping, \
+ .llseek = pci_llseek_resource, \
+ .mmap = pci_mmap_resource_wc, \
+}
+
/**
* pci_remove_resource_files - cleanup resource files
* @pdev: dev to cleanup
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (4 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 05/20] PCI/sysfs: Add static PCI resource attribute macros Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 10:49 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 07/20] PCI/sysfs: Convert __resource_resize_store() to use " Krzysztof Wilczyński
` (14 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, the PCI resource files (resourceN, resourceN_wc) are
dynamically created by pci_create_sysfs_dev_files(), called from
both pci_bus_add_device() and the pci_sysfs_init() late_initcall,
with only a sysfs_initialized flag for synchronisation. This has
caused "duplicate filename" warnings and boot panics when both
paths race on the same device.
This is especially likely on Devicetree-based platforms, where the
PCI host controllers are platform drivers that probe via the driver
model, which can happen during or after the late_initcall. As such,
pci_bus_add_device() and pci_sysfs_init() are more likely to overlap.
Thus, convert to static const attributes with three attribute groups
(I/O, UC, WC), each with an .is_bin_visible callback that checks
resource flags, BAR length, and non_mappable_bars. A .bin_size
callback provides pci_resource_len() to the kernfs node for correct
stat and lseek behaviour.
As part of this conversion:
- Rename pci_read_resource_io() and pci_write_resource_io() to
pci_read_resource() and pci_write_resource() since the callbacks
are no longer I/O-specific in the static attribute context.
- Remove pci_create_resource_files(), pci_remove_resource_files(),
and pci_create_attr() which are no longer needed.
- Move the __weak stubs outside the #if guard so they remain
available for callers converted in subsequent commits.
Platforms that do not define the HAVE_PCI_MMAP macro or the
ARCH_GENERIC_PCI_MMAP_RESOURCE macro, such as Alpha architecture,
continue using their platform-specific resource file creation.
For reference, the dynamic creation dates back to the pre-Git era:
https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/drivers/pci/pci-sysfs.c?id=42298be0eeb5ae98453b3374c36161b05a46c5dc
The write-combine support was added in commit 45aec1ae72fc ("x86: PAT
export resource_wc in pci sysfs").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 242 +++++++++++++++++++++-------------------
include/linux/pci.h | 2 -
2 files changed, 127 insertions(+), 117 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index d29d79be8ee5..e56fddbe7914 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1200,14 +1200,14 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
#endif
}
-static ssize_t pci_read_resource_io(struct file *filp, struct kobject *kobj,
+static ssize_t pci_read_resource(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
return pci_resource_io(filp, kobj, attr, buf, off, count, false);
}
-static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
+static ssize_t pci_write_resource(struct file *filp, struct kobject *kobj,
const struct bin_attribute *attr, char *buf,
loff_t off, size_t count)
{
@@ -1261,129 +1261,136 @@ static const struct bin_attribute dev_resource##_bar##_wc_attr = { \
.mmap = pci_mmap_resource_wc, \
}
-/**
- * pci_remove_resource_files - cleanup resource files
- * @pdev: dev to cleanup
- *
- * If we created resource files for @pdev, remove them from sysfs and
- * free their resources.
- */
-static void pci_remove_resource_files(struct pci_dev *pdev)
+static inline umode_t
+__pci_resource_attr_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar, bool write_combine,
+ unsigned long flags)
{
- int i;
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
- struct bin_attribute *res_attr;
-
- res_attr = pdev->res_attr[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
-
- res_attr = pdev->res_attr_wc[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
- }
-}
-
-static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
-{
- /* allocate attribute structure, piggyback attribute name */
- int name_len = write_combine ? 13 : 10;
- struct bin_attribute *res_attr;
- char *res_attr_name;
- int retval;
-
- res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
- if (!res_attr)
- return -ENOMEM;
-
- res_attr_name = (char *)(res_attr + 1);
-
- sysfs_bin_attr_init(res_attr);
- if (write_combine) {
- sprintf(res_attr_name, "resource%d_wc", num);
- res_attr->mmap = pci_mmap_resource_wc;
- } else {
- sprintf(res_attr_name, "resource%d", num);
- if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
- res_attr->read = pci_read_resource_io;
- res_attr->write = pci_write_resource_io;
- if (arch_can_pci_mmap_io())
- res_attr->mmap = pci_mmap_resource_uc;
- } else {
- res_attr->mmap = pci_mmap_resource_uc;
- }
- }
- if (res_attr->mmap) {
- res_attr->f_mapping = iomem_get_mapping;
- /*
- * generic_file_llseek() consults f_mapping->host to determine
- * the file size. As iomem_inode knows nothing about the
- * attribute, it's not going to work, so override it as well.
- */
- res_attr->llseek = pci_llseek_resource;
- }
- res_attr->attr.name = res_attr_name;
- res_attr->attr.mode = 0600;
- res_attr->size = pci_resource_len(pdev, num);
- res_attr->private = (void *)(unsigned long)num;
- retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
- if (retval) {
- kfree(res_attr);
- return retval;
- }
-
- if (write_combine)
- pdev->res_attr_wc[num] = res_attr;
- else
- pdev->res_attr[num] = res_attr;
-
- return 0;
-}
-
-/**
- * pci_create_resource_files - create resource files in sysfs for @dev
- * @pdev: dev in question
- *
- * Walk the resources in @pdev creating files for each resource available.
- */
-static int pci_create_resource_files(struct pci_dev *pdev)
-{
- int i;
- int retval;
-
- /* Skip devices with non-mappable BARs */
if (pdev->non_mappable_bars)
return 0;
- /* Expose the PCI resources from this device as files */
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
+ if (!pci_resource_len(pdev, bar))
+ return 0;
- /* skip empty resources */
- if (!pci_resource_len(pdev, i))
- continue;
+ if ((pci_resource_flags(pdev, bar) & flags) != flags)
+ return 0;
- retval = pci_create_attr(pdev, i, 0);
- /* for prefetchable resources, create a WC mappable file */
- if (!retval && arch_can_pci_mmap_wc() &&
- pci_resource_flags(pdev, i) & IORESOURCE_PREFETCH)
- retval = pci_create_attr(pdev, i, 1);
- if (retval) {
- pci_remove_resource_files(pdev);
- return retval;
- }
- }
- return 0;
+ if (write_combine && !arch_can_pci_mmap_wc())
+ return 0;
+
+ return a->attr.mode;
}
-#else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
-int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
-void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
+
+static umode_t pci_dev_resource_io_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
+{
+ return __pci_resource_attr_is_visible(kobj, a, n, false,
+ IORESOURCE_IO);
+}
+
+static umode_t pci_dev_resource_uc_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
+{
+ return __pci_resource_attr_is_visible(kobj, a, n, false,
+ IORESOURCE_MEM);
+}
+
+static umode_t pci_dev_resource_wc_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
+{
+ return __pci_resource_attr_is_visible(kobj, a, n, true,
+ IORESOURCE_MEM | IORESOURCE_PREFETCH);
+}
+
+static size_t pci_dev_resource_bin_size(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+
+ return pci_resource_len(pdev, n);
+}
+
+pci_dev_resource_io_attr(0);
+pci_dev_resource_io_attr(1);
+pci_dev_resource_io_attr(2);
+pci_dev_resource_io_attr(3);
+pci_dev_resource_io_attr(4);
+pci_dev_resource_io_attr(5);
+
+pci_dev_resource_uc_attr(0);
+pci_dev_resource_uc_attr(1);
+pci_dev_resource_uc_attr(2);
+pci_dev_resource_uc_attr(3);
+pci_dev_resource_uc_attr(4);
+pci_dev_resource_uc_attr(5);
+
+pci_dev_resource_wc_attr(0);
+pci_dev_resource_wc_attr(1);
+pci_dev_resource_wc_attr(2);
+pci_dev_resource_wc_attr(3);
+pci_dev_resource_wc_attr(4);
+pci_dev_resource_wc_attr(5);
+
+static const struct bin_attribute *const pci_dev_resource_io_attrs[] = {
+ &dev_resource0_io_attr,
+ &dev_resource1_io_attr,
+ &dev_resource2_io_attr,
+ &dev_resource3_io_attr,
+ &dev_resource4_io_attr,
+ &dev_resource5_io_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_dev_resource_uc_attrs[] = {
+ &dev_resource0_uc_attr,
+ &dev_resource1_uc_attr,
+ &dev_resource2_uc_attr,
+ &dev_resource3_uc_attr,
+ &dev_resource4_uc_attr,
+ &dev_resource5_uc_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_dev_resource_wc_attrs[] = {
+ &dev_resource0_wc_attr,
+ &dev_resource1_wc_attr,
+ &dev_resource2_wc_attr,
+ &dev_resource3_wc_attr,
+ &dev_resource4_wc_attr,
+ &dev_resource5_wc_attr,
+ NULL,
+};
+
+static const struct attribute_group pci_dev_resource_io_attr_group = {
+ .bin_attrs = pci_dev_resource_io_attrs,
+ .is_bin_visible = pci_dev_resource_io_is_visible,
+ .bin_size = pci_dev_resource_bin_size,
+};
+
+static const struct attribute_group pci_dev_resource_uc_attr_group = {
+ .bin_attrs = pci_dev_resource_uc_attrs,
+ .is_bin_visible = pci_dev_resource_uc_is_visible,
+ .bin_size = pci_dev_resource_bin_size,
+};
+
+static const struct attribute_group pci_dev_resource_wc_attr_group = {
+ .bin_attrs = pci_dev_resource_wc_attrs,
+ .is_bin_visible = pci_dev_resource_wc_is_visible,
+ .bin_size = pci_dev_resource_bin_size,
+};
+
#endif
+int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
+void __weak pci_remove_resource_files(struct pci_dev *dev) { }
+
/**
* pci_write_rom - used to enable access to the PCI ROM display
* @filp: sysfs file
@@ -1861,6 +1868,11 @@ static const struct attribute_group pci_dev_group = {
const struct attribute_group *pci_dev_groups[] = {
&pci_dev_group,
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+ &pci_dev_resource_io_attr_group,
+ &pci_dev_resource_uc_attr_group,
+ &pci_dev_resource_wc_attr_group,
+#endif
&pci_dev_config_attr_group,
&pci_dev_rom_attr_group,
&pci_dev_reset_attr_group,
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 1c270f1d5123..a7a104427b07 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -2501,10 +2501,8 @@ int pcibios_alloc_irq(struct pci_dev *dev);
void pcibios_free_irq(struct pci_dev *dev);
resource_size_t pcibios_default_alignment(void);
-#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
extern int pci_create_resource_files(struct pci_dev *dev);
extern void pci_remove_resource_files(struct pci_dev *dev);
-#endif
#if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
void __init pci_mmcfg_early_init(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes
2026-04-10 5:50 ` [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
@ 2026-04-10 10:49 ` Ilpo Järvinen
2026-04-10 11:13 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 10:49 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 13013 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Currently, the PCI resource files (resourceN, resourceN_wc) are
> dynamically created by pci_create_sysfs_dev_files(), called from
> both pci_bus_add_device() and the pci_sysfs_init() late_initcall,
> with only a sysfs_initialized flag for synchronisation. This has
> caused "duplicate filename" warnings and boot panics when both
> paths race on the same device.
>
> This is especially likely on Devicetree-based platforms, where the
> PCI host controllers are platform drivers that probe via the driver
> model, which can happen during or after the late_initcall. As such,
> pci_bus_add_device() and pci_sysfs_init() are more likely to overlap.
>
> Thus, convert to static const attributes with three attribute groups
> (I/O, UC, WC), each with an .is_bin_visible callback that checks
> resource flags, BAR length, and non_mappable_bars. A .bin_size
> callback provides pci_resource_len() to the kernfs node for correct
> stat and lseek behaviour.
>
> As part of this conversion:
>
> - Rename pci_read_resource_io() and pci_write_resource_io() to
> pci_read_resource() and pci_write_resource() since the callbacks
> are no longer I/O-specific in the static attribute context.
>
> - Remove pci_create_resource_files(), pci_remove_resource_files(),
> and pci_create_attr() which are no longer needed.
>
> - Move the __weak stubs outside the #if guard so they remain
> available for callers converted in subsequent commits.
>
> Platforms that do not define the HAVE_PCI_MMAP macro or the
> ARCH_GENERIC_PCI_MMAP_RESOURCE macro, such as Alpha architecture,
> continue using their platform-specific resource file creation.
>
> For reference, the dynamic creation dates back to the pre-Git era:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/drivers/pci/pci-sysfs.c?id=42298be0eeb5ae98453b3374c36161b05a46c5dc
>
> The write-combine support was added in commit 45aec1ae72fc ("x86: PAT
> export resource_wc in pci sysfs").
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> drivers/pci/pci-sysfs.c | 242 +++++++++++++++++++++-------------------
> include/linux/pci.h | 2 -
> 2 files changed, 127 insertions(+), 117 deletions(-)
>
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index d29d79be8ee5..e56fddbe7914 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -1200,14 +1200,14 @@ static ssize_t pci_resource_io(struct file *filp, struct kobject *kobj,
> #endif
> }
>
> -static ssize_t pci_read_resource_io(struct file *filp, struct kobject *kobj,
> +static ssize_t pci_read_resource(struct file *filp, struct kobject *kobj,
> const struct bin_attribute *attr, char *buf,
> loff_t off, size_t count)
> {
> return pci_resource_io(filp, kobj, attr, buf, off, count, false);
> }
>
> -static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj,
> +static ssize_t pci_write_resource(struct file *filp, struct kobject *kobj,
> const struct bin_attribute *attr, char *buf,
> loff_t off, size_t count)
> {
> @@ -1261,129 +1261,136 @@ static const struct bin_attribute dev_resource##_bar##_wc_attr = { \
> .mmap = pci_mmap_resource_wc, \
> }
>
> -/**
> - * pci_remove_resource_files - cleanup resource files
> - * @pdev: dev to cleanup
> - *
> - * If we created resource files for @pdev, remove them from sysfs and
> - * free their resources.
> - */
> -static void pci_remove_resource_files(struct pci_dev *pdev)
> +static inline umode_t
> +__pci_resource_attr_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int bar, bool write_combine,
> + unsigned long flags)
> {
> - int i;
> + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
>
> - for (i = 0; i < PCI_STD_NUM_BARS; i++) {
> - struct bin_attribute *res_attr;
> -
> - res_attr = pdev->res_attr[i];
> - if (res_attr) {
> - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
> - kfree(res_attr);
> - }
> -
> - res_attr = pdev->res_attr_wc[i];
> - if (res_attr) {
> - sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
> - kfree(res_attr);
> - }
> - }
> -}
> -
> -static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
> -{
> - /* allocate attribute structure, piggyback attribute name */
> - int name_len = write_combine ? 13 : 10;
> - struct bin_attribute *res_attr;
> - char *res_attr_name;
> - int retval;
> -
> - res_attr = kzalloc(sizeof(*res_attr) + name_len, GFP_ATOMIC);
> - if (!res_attr)
> - return -ENOMEM;
> -
> - res_attr_name = (char *)(res_attr + 1);
> -
> - sysfs_bin_attr_init(res_attr);
> - if (write_combine) {
> - sprintf(res_attr_name, "resource%d_wc", num);
> - res_attr->mmap = pci_mmap_resource_wc;
> - } else {
> - sprintf(res_attr_name, "resource%d", num);
> - if (pci_resource_flags(pdev, num) & IORESOURCE_IO) {
> - res_attr->read = pci_read_resource_io;
> - res_attr->write = pci_write_resource_io;
> - if (arch_can_pci_mmap_io())
> - res_attr->mmap = pci_mmap_resource_uc;
> - } else {
> - res_attr->mmap = pci_mmap_resource_uc;
> - }
> - }
> - if (res_attr->mmap) {
> - res_attr->f_mapping = iomem_get_mapping;
> - /*
> - * generic_file_llseek() consults f_mapping->host to determine
> - * the file size. As iomem_inode knows nothing about the
> - * attribute, it's not going to work, so override it as well.
> - */
> - res_attr->llseek = pci_llseek_resource;
> - }
> - res_attr->attr.name = res_attr_name;
> - res_attr->attr.mode = 0600;
> - res_attr->size = pci_resource_len(pdev, num);
> - res_attr->private = (void *)(unsigned long)num;
> - retval = sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
> - if (retval) {
> - kfree(res_attr);
> - return retval;
> - }
> -
> - if (write_combine)
> - pdev->res_attr_wc[num] = res_attr;
> - else
> - pdev->res_attr[num] = res_attr;
> -
> - return 0;
> -}
> -
> -/**
> - * pci_create_resource_files - create resource files in sysfs for @dev
> - * @pdev: dev in question
> - *
> - * Walk the resources in @pdev creating files for each resource available.
> - */
> -static int pci_create_resource_files(struct pci_dev *pdev)
> -{
> - int i;
> - int retval;
> -
> - /* Skip devices with non-mappable BARs */
> if (pdev->non_mappable_bars)
> return 0;
>
> - /* Expose the PCI resources from this device as files */
> - for (i = 0; i < PCI_STD_NUM_BARS; i++) {
> + if (!pci_resource_len(pdev, bar))
> + return 0;
I know it's same as in the previous code but I dislike assuming len != 0
implies resource has been assigned. While it currently holds, I'd want to
change that eventually.
The current behavior causes issue e.g. if IOV resource fails to assign, it
is reset (making its len 0 among other thing) and since IOV resource are
optional that is fine from kernel's perspective. But resetting the
resource means we also lose access to that resource because its type gets
cleared so from kernel perspective the VF BAR stops to exist. Losing it
means the user cannot solve the issue by e.g. resizing some other BAR
smaller to make space to allow the VF BARs to assign successfully.
So I think this code would actually want to check resource_assigned()
which implies also non-zero size.
AFAICT, this change looks fine (despite the diff being very messy).
> - /* skip empty resources */
> - if (!pci_resource_len(pdev, i))
> - continue;
> + if ((pci_resource_flags(pdev, bar) & flags) != flags)
> + return 0;
>
> - retval = pci_create_attr(pdev, i, 0);
> - /* for prefetchable resources, create a WC mappable file */
> - if (!retval && arch_can_pci_mmap_wc() &&
> - pci_resource_flags(pdev, i) & IORESOURCE_PREFETCH)
> - retval = pci_create_attr(pdev, i, 1);
> - if (retval) {
> - pci_remove_resource_files(pdev);
> - return retval;
> - }
> - }
> - return 0;
> + if (write_combine && !arch_can_pci_mmap_wc())
> + return 0;
> +
> + return a->attr.mode;
> }
> -#else /* !(defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)) */
> -int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
> -void __weak pci_remove_resource_files(struct pci_dev *dev) { return; }
> +
> +static umode_t pci_dev_resource_io_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> +{
> + return __pci_resource_attr_is_visible(kobj, a, n, false,
> + IORESOURCE_IO);
> +}
> +
> +static umode_t pci_dev_resource_uc_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> +{
> + return __pci_resource_attr_is_visible(kobj, a, n, false,
> + IORESOURCE_MEM);
> +}
> +
> +static umode_t pci_dev_resource_wc_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> +{
> + return __pci_resource_attr_is_visible(kobj, a, n, true,
> + IORESOURCE_MEM | IORESOURCE_PREFETCH);
> +}
> +
> +static size_t pci_dev_resource_bin_size(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> +{
> + struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
> +
> + return pci_resource_len(pdev, n);
> +}
> +
> +pci_dev_resource_io_attr(0);
> +pci_dev_resource_io_attr(1);
> +pci_dev_resource_io_attr(2);
> +pci_dev_resource_io_attr(3);
> +pci_dev_resource_io_attr(4);
> +pci_dev_resource_io_attr(5);
> +
> +pci_dev_resource_uc_attr(0);
> +pci_dev_resource_uc_attr(1);
> +pci_dev_resource_uc_attr(2);
> +pci_dev_resource_uc_attr(3);
> +pci_dev_resource_uc_attr(4);
> +pci_dev_resource_uc_attr(5);
> +
> +pci_dev_resource_wc_attr(0);
> +pci_dev_resource_wc_attr(1);
> +pci_dev_resource_wc_attr(2);
> +pci_dev_resource_wc_attr(3);
> +pci_dev_resource_wc_attr(4);
> +pci_dev_resource_wc_attr(5);
> +
> +static const struct bin_attribute *const pci_dev_resource_io_attrs[] = {
> + &dev_resource0_io_attr,
> + &dev_resource1_io_attr,
> + &dev_resource2_io_attr,
> + &dev_resource3_io_attr,
> + &dev_resource4_io_attr,
> + &dev_resource5_io_attr,
> + NULL,
> +};
> +
> +static const struct bin_attribute *const pci_dev_resource_uc_attrs[] = {
> + &dev_resource0_uc_attr,
> + &dev_resource1_uc_attr,
> + &dev_resource2_uc_attr,
> + &dev_resource3_uc_attr,
> + &dev_resource4_uc_attr,
> + &dev_resource5_uc_attr,
> + NULL,
> +};
> +
> +static const struct bin_attribute *const pci_dev_resource_wc_attrs[] = {
> + &dev_resource0_wc_attr,
> + &dev_resource1_wc_attr,
> + &dev_resource2_wc_attr,
> + &dev_resource3_wc_attr,
> + &dev_resource4_wc_attr,
> + &dev_resource5_wc_attr,
> + NULL,
> +};
> +
> +static const struct attribute_group pci_dev_resource_io_attr_group = {
> + .bin_attrs = pci_dev_resource_io_attrs,
> + .is_bin_visible = pci_dev_resource_io_is_visible,
> + .bin_size = pci_dev_resource_bin_size,
> +};
> +
> +static const struct attribute_group pci_dev_resource_uc_attr_group = {
> + .bin_attrs = pci_dev_resource_uc_attrs,
> + .is_bin_visible = pci_dev_resource_uc_is_visible,
> + .bin_size = pci_dev_resource_bin_size,
> +};
> +
> +static const struct attribute_group pci_dev_resource_wc_attr_group = {
> + .bin_attrs = pci_dev_resource_wc_attrs,
> + .is_bin_visible = pci_dev_resource_wc_is_visible,
> + .bin_size = pci_dev_resource_bin_size,
> +};
> +
> #endif
>
> +int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
> +void __weak pci_remove_resource_files(struct pci_dev *dev) { }
> +
> /**
> * pci_write_rom - used to enable access to the PCI ROM display
> * @filp: sysfs file
> @@ -1861,6 +1868,11 @@ static const struct attribute_group pci_dev_group = {
>
> const struct attribute_group *pci_dev_groups[] = {
> &pci_dev_group,
> +#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
> + &pci_dev_resource_io_attr_group,
> + &pci_dev_resource_uc_attr_group,
> + &pci_dev_resource_wc_attr_group,
> +#endif
> &pci_dev_config_attr_group,
> &pci_dev_rom_attr_group,
> &pci_dev_reset_attr_group,
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 1c270f1d5123..a7a104427b07 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -2501,10 +2501,8 @@ int pcibios_alloc_irq(struct pci_dev *dev);
> void pcibios_free_irq(struct pci_dev *dev);
> resource_size_t pcibios_default_alignment(void);
>
> -#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
> extern int pci_create_resource_files(struct pci_dev *dev);
> extern void pci_remove_resource_files(struct pci_dev *dev);
> -#endif
>
> #if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
> void __init pci_mmcfg_early_init(void);
>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes
2026-04-10 10:49 ` Ilpo Järvinen
@ 2026-04-10 11:13 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:13 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > - /* Expose the PCI resources from this device as files */
> > - for (i = 0; i < PCI_STD_NUM_BARS; i++) {
> > + if (!pci_resource_len(pdev, bar))
> > + return 0;
>
> I know it's same as in the previous code but I dislike assuming len != 0
> implies resource has been assigned. While it currently holds, I'd want to
> change that eventually.
>
> The current behavior causes issue e.g. if IOV resource fails to assign, it
> is reset (making its len 0 among other thing) and since IOV resource are
> optional that is fine from kernel's perspective. But resetting the
> resource means we also lose access to that resource because its type gets
> cleared so from kernel perspective the VF BAR stops to exist. Losing it
> means the user cannot solve the issue by e.g. resizing some other BAR
> smaller to make space to allow the VF BARs to assign successfully.
>
> So I think this code would actually want to check resource_assigned()
> which implies also non-zero size.
Makes sense.
I will update the code to use resource_assigned(). Since we are working on
this code anyway, it would be only prudent to also do the right thing.
> AFAICT, this change looks fine (despite the diff being very messy).
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 07/20] PCI/sysfs: Convert __resource_resize_store() to use static attributes
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (5 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 06/20] PCI/sysfs: Convert PCI resource files to static attributes Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 08/20] PCI/sysfs: Add stubs for pci_{create,remove}_sysfs_dev_files() Krzysztof Wilczyński
` (13 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, __resource_resize_store() calls pci_remove_resource_files()
and pci_create_resource_files() to tear down and recreate resource
files after a BAR resize.
Replace this with sysfs_update_groups(), which re-evaluates visibility
and also runs the .bin_size callback for the static resource attribute
groups after a BAR resize.
At the moment, the resize code references the static resource group
symbols, so wrap it and the resize group registration in pci_dev_groups[]
under the same "HAVE_PCI_MMAP || ARCH_GENERIC_PCI_MMAP_RESOURCE" guard.
While at it, add a warning if pci_resize_resource() fails to
expose potential failures, and rename resource_resize_is_visible()
to resource_resize_attr_is_visible() and the corresponding group
variable to align with the naming convention used by the resource
attribute groups.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e56fddbe7914..1fabd0baeb56 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1386,6 +1386,12 @@ static const struct attribute_group pci_dev_resource_wc_attr_group = {
.bin_size = pci_dev_resource_bin_size,
};
+static const struct attribute_group *pci_dev_resource_attr_groups[] = {
+ &pci_dev_resource_io_attr_group,
+ &pci_dev_resource_uc_attr_group,
+ &pci_dev_resource_wc_attr_group,
+ NULL,
+};
#endif
int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
@@ -1643,6 +1649,7 @@ static const struct attribute_group pci_dev_reset_method_attr_group = {
.is_visible = pci_dev_reset_attr_is_visible,
};
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
static ssize_t __resource_resize_show(struct device *dev, int n, char *buf)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -1692,14 +1699,15 @@ static ssize_t __resource_resize_store(struct device *dev, int n,
pci_write_config_word(pdev, PCI_COMMAND,
cmd & ~PCI_COMMAND_MEMORY);
- pci_remove_resource_files(pdev);
-
ret = pci_resize_resource(pdev, n, size, 0);
+ if (ret)
+ pci_warn(pdev, "Failed to resize BAR %d: %pe\n",
+ n, ERR_PTR(ret));
pci_assign_unassigned_bus_resources(bus);
- if (pci_create_resource_files(pdev))
- pci_warn(pdev, "Failed to recreate resource files after BAR resizing\n");
+ if (sysfs_update_groups(&pdev->dev.kobj, pci_dev_resource_attr_groups))
+ pci_warn(pdev, "Failed to update resource groups after BAR resizing\n");
pci_write_config_word(pdev, PCI_COMMAND, cmd);
pm_put:
@@ -1742,7 +1750,7 @@ static struct attribute *resource_resize_attrs[] = {
NULL,
};
-static umode_t resource_resize_is_visible(struct kobject *kobj,
+static umode_t resource_resize_attr_is_visible(struct kobject *kobj,
struct attribute *a, int n)
{
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
@@ -1750,10 +1758,11 @@ static umode_t resource_resize_is_visible(struct kobject *kobj,
return pci_rebar_get_current_size(pdev, n) < 0 ? 0 : a->mode;
}
-static const struct attribute_group pci_dev_resource_resize_group = {
+static const struct attribute_group pci_dev_resource_resize_attr_group = {
.attrs = resource_resize_attrs,
- .is_visible = resource_resize_is_visible,
+ .is_visible = resource_resize_attr_is_visible,
};
+#endif
int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
{
@@ -1872,6 +1881,7 @@ const struct attribute_group *pci_dev_groups[] = {
&pci_dev_resource_io_attr_group,
&pci_dev_resource_uc_attr_group,
&pci_dev_resource_wc_attr_group,
+ &pci_dev_resource_resize_attr_group,
#endif
&pci_dev_config_attr_group,
&pci_dev_rom_attr_group,
@@ -1884,7 +1894,6 @@ const struct attribute_group *pci_dev_groups[] = {
#ifdef CONFIG_ACPI
&pci_dev_acpi_attr_group,
#endif
- &pci_dev_resource_resize_group,
ARCH_PCI_DEV_GROUPS
NULL,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 08/20] PCI/sysfs: Add stubs for pci_{create,remove}_sysfs_dev_files()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (6 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 07/20] PCI/sysfs: Convert __resource_resize_store() to use " Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 09/20] PCI/sysfs: Limit pci_sysfs_init() late_initcall compile scope Krzysztof Wilczyński
` (12 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
On platforms with HAVE_PCI_MMAP or ARCH_GENERIC_PCI_MMAP_RESOURCE,
resource files are now handled by static attribute groups registered
via pci_dev_groups[].
Thus, the pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files()
can now be stubbed out, as the dynamic resource file creation is no
longer needed.
Also, simplify pci_sysfs_init() on these platforms to only iterate
buses for legacy attributes creation, skipping the per-device loop.
Move the __weak stubs for pci_create_resource_files() and
pci_remove_resource_files() into the #else branch since only platforms
without HAVE_PCI_MMAP (such as Alpha architecture) still need them.
Guard the res_attr[] and res_attr_wc[] fields in struct pci_dev the
same way.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 16 +++++++++++++---
include/linux/pci.h | 4 ++++
2 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 1fabd0baeb56..e200514bbaed 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1392,10 +1392,10 @@ static const struct attribute_group *pci_dev_resource_attr_groups[] = {
&pci_dev_resource_wc_attr_group,
NULL,
};
-#endif
-
+#else
int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
void __weak pci_remove_resource_files(struct pci_dev *dev) { }
+#endif
/**
* pci_write_rom - used to enable access to the PCI ROM display
@@ -1764,6 +1764,10 @@ static const struct attribute_group pci_dev_resource_resize_attr_group = {
};
#endif
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+int pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; }
+void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { }
+#else
int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
{
if (!sysfs_initialized)
@@ -1785,9 +1789,15 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
pci_remove_resource_files(pdev);
}
+#endif
static int __init pci_sysfs_init(void)
{
+#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+ struct pci_bus *pbus = NULL;
+
+ sysfs_initialized = 1;
+#else
struct pci_dev *pdev = NULL;
struct pci_bus *pbus = NULL;
int retval;
@@ -1800,7 +1810,7 @@ static int __init pci_sysfs_init(void)
return retval;
}
}
-
+#endif
while ((pbus = pci_find_next_bus(pbus)))
pci_create_legacy_files(pbus);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index a7a104427b07..2940c80fd7c5 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -507,8 +507,10 @@ struct pci_dev {
spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */
u32 saved_config_space[16]; /* Config space saved at suspend time */
struct hlist_head saved_cap_space;
+#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
+#endif
#ifdef CONFIG_HOTPLUG_PCI_PCIE
unsigned int broken_cmd_compl:1; /* No compl for some cmds */
@@ -2501,8 +2503,10 @@ int pcibios_alloc_irq(struct pci_dev *dev);
void pcibios_free_irq(struct pci_dev *dev);
resource_size_t pcibios_default_alignment(void);
+#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
extern int pci_create_resource_files(struct pci_dev *dev);
extern void pci_remove_resource_files(struct pci_dev *dev);
+#endif
#if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
void __init pci_mmcfg_early_init(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 09/20] PCI/sysfs: Limit pci_sysfs_init() late_initcall compile scope
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (7 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 08/20] PCI/sysfs: Add stubs for pci_{create,remove}_sysfs_dev_files() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource() Krzysztof Wilczyński
` (11 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, pci_sysfs_init() and sysfs_initialized compile
unconditionally, even on platforms where static attribute
groups handle all resource file creation.
Thus, place them behind a new HAVE_PCI_SYSFS_INIT macro,
especially as the late_initcall is only needed when:
- HAVE_PCI_LEGACY is set, to iterate buses and create legacy
I/O and memory files.
- Neither HAVE_PCI_MMAP nor ARCH_GENERIC_PCI_MMAP_RESOURCE is
set, to iterate devices and create resource files via the
__weak pci_create_resource_files() stub override (this is
how the Alpha architecture handles this currently).
On most systems both conditions are false and the entire
late_initcall compiles away.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index e200514bbaed..062921d5df9b 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -37,7 +37,14 @@
#define ARCH_PCI_DEV_GROUPS
#endif
+#if defined(HAVE_PCI_LEGACY) || \
+ !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
+#define HAVE_PCI_SYSFS_INIT
+#endif
+
+#ifdef HAVE_PCI_SYSFS_INIT
static int sysfs_initialized; /* = 0 */
+#endif
/* show configuration fields */
#define pci_config_attr(field, format_string) \
@@ -1791,6 +1798,7 @@ void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
}
#endif
+#ifdef HAVE_PCI_SYSFS_INIT
static int __init pci_sysfs_init(void)
{
#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
@@ -1817,6 +1825,7 @@ static int __init pci_sysfs_init(void)
return 0;
}
late_initcall(pci_sysfs_init);
+#endif
static struct attribute *pci_dev_dev_attrs[] = {
&dev_attr_boot_vga.attr,
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (8 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 09/20] PCI/sysfs: Limit pci_sysfs_init() late_initcall compile scope Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 11:04 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 11/20] alpha/PCI: Use BAR index in sysfs attr->private instead of resource pointer Krzysztof Wilczyński
` (10 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, Alpha's pci_mmap_resource() does not check
security_locked_down(LOCKDOWN_PCI_ACCESS) before allowing
userspace to mmap PCI BARs.
The generic version has had this check since commit eb627e17727e
("PCI: Lock down BAR access when the kernel is locked down") to
prevent DMA attacks when the kernel is locked down.
Add the same check to Alpha's pci_mmap_resource().
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 3048758304b5..2324720c3e83 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -11,6 +11,7 @@
*/
#include <linux/sched.h>
+#include <linux/security.h>
#include <linux/stat.h>
#include <linux/slab.h>
#include <linux/pci.h>
@@ -71,7 +72,11 @@ static int pci_mmap_resource(struct kobject *kobj,
struct resource *res = attr->private;
enum pci_mmap_state mmap_type;
struct pci_bus_region bar;
- int i;
+ int i, ret;
+
+ ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
+ if (ret)
+ return ret;
for (i = 0; i < PCI_STD_NUM_BARS; i++)
if (res == &pdev->resource[i])
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource()
2026-04-10 5:50 ` [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource() Krzysztof Wilczyński
@ 2026-04-10 11:04 ` Ilpo Järvinen
2026-04-10 11:10 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:04 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1516 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Currently, Alpha's pci_mmap_resource() does not check
> security_locked_down(LOCKDOWN_PCI_ACCESS) before allowing
> userspace to mmap PCI BARs.
>
> The generic version has had this check since commit eb627e17727e
> ("PCI: Lock down BAR access when the kernel is locked down") to
> prevent DMA attacks when the kernel is locked down.
>
> Add the same check to Alpha's pci_mmap_resource().
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Maybe add Fixes: eb627e17727e ...
> ---
> arch/alpha/kernel/pci-sysfs.c | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
> index 3048758304b5..2324720c3e83 100644
> --- a/arch/alpha/kernel/pci-sysfs.c
> +++ b/arch/alpha/kernel/pci-sysfs.c
> @@ -11,6 +11,7 @@
> */
>
> #include <linux/sched.h>
> +#include <linux/security.h>
> #include <linux/stat.h>
> #include <linux/slab.h>
> #include <linux/pci.h>
> @@ -71,7 +72,11 @@ static int pci_mmap_resource(struct kobject *kobj,
> struct resource *res = attr->private;
> enum pci_mmap_state mmap_type;
> struct pci_bus_region bar;
> - int i;
> + int i, ret;
> +
> + ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
> + if (ret)
> + return ret;
>
> for (i = 0; i < PCI_STD_NUM_BARS; i++)
> if (res == &pdev->resource[i])
>
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource()
2026-04-10 11:04 ` Ilpo Järvinen
@ 2026-04-10 11:10 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:10 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > Currently, Alpha's pci_mmap_resource() does not check
> > security_locked_down(LOCKDOWN_PCI_ACCESS) before allowing
> > userspace to mmap PCI BARs.
> >
> > The generic version has had this check since commit eb627e17727e
> > ("PCI: Lock down BAR access when the kernel is locked down") to
> > prevent DMA attacks when the kernel is locked down.
> >
> > Add the same check to Alpha's pci_mmap_resource().
> >
> > Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
>
> Maybe add Fixes: eb627e17727e ...
Good call, will do!
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 11/20] alpha/PCI: Use BAR index in sysfs attr->private instead of resource pointer
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (9 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 10/20] alpha/PCI: Add security_locked_down() check to pci_mmap_resource() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros Krzysztof Wilczyński
` (9 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, Alpha's pci_create_one_attr() stores a resource pointer in
attr->private, and pci_mmap_resource() loops through all BARs to find
the matching index.
Thus, store the BAR index directly in attr->private and retrieve the
resource via pci_resource_n(). This eliminates the loop and aligns
with the convention used by the generic PCI sysfs code.
While at it, add parentheses around the bitwise flag test in
pci_mmap_resource() to make the precedence explicit, and to
match the preferred style.
The PCI core change was first added in the commit dca40b186b75 ("PCI:
Use BAR index in sysfs attr->private instead of resource pointer").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 2324720c3e83..c84867ce31f5 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -69,25 +69,20 @@ static int pci_mmap_resource(struct kobject *kobj,
struct vm_area_struct *vma, int sparse)
{
struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
- struct resource *res = attr->private;
+ int barno = (unsigned long)attr->private;
+ struct resource *res = pci_resource_n(pdev, barno);
enum pci_mmap_state mmap_type;
struct pci_bus_region bar;
- int i, ret;
+ int ret;
ret = security_locked_down(LOCKDOWN_PCI_ACCESS);
if (ret)
return ret;
- for (i = 0; i < PCI_STD_NUM_BARS; i++)
- if (res == &pdev->resource[i])
- break;
- if (i >= PCI_STD_NUM_BARS)
- return -ENODEV;
-
- if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start))
+ if ((res->flags & IORESOURCE_MEM) && iomem_is_exclusive(res->start))
return -EINVAL;
- if (!__pci_mmap_fits(pdev, i, vma, sparse))
+ if (!__pci_mmap_fits(pdev, barno, vma, sparse))
return -EINVAL;
pcibios_resource_to_bus(pdev->bus, &bar, res);
@@ -170,7 +165,7 @@ static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
res_attr->attr.name = name;
res_attr->attr.mode = S_IRUSR | S_IWUSR;
res_attr->size = sparse ? size << 5 : size;
- res_attr->private = &pdev->resource[num];
+ res_attr->private = (void *)(unsigned long)num;
return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (10 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 11/20] alpha/PCI: Use BAR index in sysfs attr->private instead of resource pointer Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 11:11 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits() Krzysztof Wilczyński
` (8 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Replace direct pdev->resource[] accesses with pci_resource_n(),
and pdev->resource[].flags accesses with pci_resource_flags().
No functional changes intended.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index c84867ce31f5..7aac5e76dcd6 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -141,7 +141,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
long dense_offset;
unsigned long sparse_size;
- pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]);
+ pcibios_resource_to_bus(pdev->bus, &bar, pci_resource_n(pdev, num));
/* All core logic chips have 4G sparse address space, except
CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
@@ -181,7 +181,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num)
suffix = ""; /* Assume bwx machine, normal resourceN files. */
nlen1 = 10;
- if (pdev->resource[num].flags & IORESOURCE_MEM) {
+ if (pci_resource_flags(pdev, num) & IORESOURCE_MEM) {
sparse_base = hose->sparse_mem_base;
dense_base = hose->dense_mem_base;
if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros
2026-04-10 5:50 ` [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros Krzysztof Wilczyński
@ 2026-04-10 11:11 ` Ilpo Järvinen
2026-04-10 11:27 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:11 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1555 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Replace direct pdev->resource[] accesses with pci_resource_n(),
> and pdev->resource[].flags accesses with pci_resource_flags().
>
> No functional changes intended.
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> arch/alpha/kernel/pci-sysfs.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
> index c84867ce31f5..7aac5e76dcd6 100644
> --- a/arch/alpha/kernel/pci-sysfs.c
> +++ b/arch/alpha/kernel/pci-sysfs.c
> @@ -141,7 +141,7 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
> long dense_offset;
> unsigned long sparse_size;
>
> - pcibios_resource_to_bus(pdev->bus, &bar, &pdev->resource[num]);
> + pcibios_resource_to_bus(pdev->bus, &bar, pci_resource_n(pdev, num));
>
> /* All core logic chips have 4G sparse address space, except
> CIA which has 16G (see xxx_SPARSE_MEM and xxx_DENSE_MEM
> @@ -181,7 +181,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num)
> suffix = ""; /* Assume bwx machine, normal resourceN files. */
> nlen1 = 10;
>
> - if (pdev->resource[num].flags & IORESOURCE_MEM) {
> + if (pci_resource_flags(pdev, num) & IORESOURCE_MEM) {
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
I started wonder though if we'd want to add pci_resource_is_mem/io()
shortcuts for these, as it's largely what
git grep pci_resource_flags
results contain.
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros
2026-04-10 11:11 ` Ilpo Järvinen
@ 2026-04-10 11:27 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:27 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > - if (pdev->resource[num].flags & IORESOURCE_MEM) {
> > + if (pci_resource_flags(pdev, num) & IORESOURCE_MEM) {
>
> Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
>
> I started wonder though if we'd want to add pci_resource_is_mem/io()
> shortcuts for these, as it's largely what
>
> git grep pci_resource_flags
>
> results contain.
I see what you mean... We can introduce such helpers here, and be the first
users within the PCI tree, that is, before someone will do a tree-wide or some
more granular update eventually.
Should I do it? Thoughts?
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (11 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 12/20] alpha/PCI: Use PCI resource accessor macros Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 11:14 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros Krzysztof Wilczyński
` (7 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, __pci_mmap_fits() computes the BAR size using
pci_resource_len() - 1, which wraps to a large value when the
BAR length is zero, causing the bounds check to incorrectly
succeed.
Thus, add an early return for empty resources.
Also, remove the WARN() that fires when userspace attempts to
mmap beyond the BAR bounds. The check still returns 0 to reject
the mapping, but the warning is excessive for normal operation.
A similar warning was removed from the PCI core in the commit
3b519e4ea618 ("PCI: fix size checks for mmap() on /proc/bus/pci files").
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 7aac5e76dcd6..867199b988de 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -37,20 +37,18 @@ static int hose_mmap_page_range(struct pci_controller *hose,
static int __pci_mmap_fits(struct pci_dev *pdev, int num,
struct vm_area_struct *vma, int sparse)
{
+ resource_size_t len = pci_resource_len(pdev, num);
unsigned long nr, start, size;
int shift = sparse ? 5 : 0;
+ if (!len)
+ return 0;
+
nr = vma_pages(vma);
start = vma->vm_pgoff;
- size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
+ size = ((len - 1) >> (PAGE_SHIFT - shift)) + 1;
- if (start < size && size - start >= nr)
- return 1;
- WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d "
- "(size 0x%08lx)\n",
- current->comm, sparse ? " sparse" : "", start, start + nr,
- pci_name(pdev), num, size);
- return 0;
+ return start < size && size - start >= nr;
}
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits()
2026-04-10 5:50 ` [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits() Krzysztof Wilczyński
@ 2026-04-10 11:14 ` Ilpo Järvinen
2026-04-10 11:21 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:14 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2055 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Currently, __pci_mmap_fits() computes the BAR size using
> pci_resource_len() - 1, which wraps to a large value when the
> BAR length is zero, causing the bounds check to incorrectly
> succeed.
>
> Thus, add an early return for empty resources.
>
> Also, remove the WARN() that fires when userspace attempts to
> mmap beyond the BAR bounds. The check still returns 0 to reject
> the mapping, but the warning is excessive for normal operation.
>
> A similar warning was removed from the PCI core in the commit
> 3b519e4ea618 ("PCI: fix size checks for mmap() on /proc/bus/pci files").
This looks like entirely separate two changes to me which just happen
within the same context.
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> arch/alpha/kernel/pci-sysfs.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
> index 7aac5e76dcd6..867199b988de 100644
> --- a/arch/alpha/kernel/pci-sysfs.c
> +++ b/arch/alpha/kernel/pci-sysfs.c
> @@ -37,20 +37,18 @@ static int hose_mmap_page_range(struct pci_controller *hose,
> static int __pci_mmap_fits(struct pci_dev *pdev, int num,
> struct vm_area_struct *vma, int sparse)
> {
> + resource_size_t len = pci_resource_len(pdev, num);
> unsigned long nr, start, size;
> int shift = sparse ? 5 : 0;
>
> + if (!len)
> + return 0;
> +
> nr = vma_pages(vma);
> start = vma->vm_pgoff;
> - size = ((pci_resource_len(pdev, num) - 1) >> (PAGE_SHIFT - shift)) + 1;
> + size = ((len - 1) >> (PAGE_SHIFT - shift)) + 1;
>
> - if (start < size && size - start >= nr)
> - return 1;
> - WARN(1, "process \"%s\" tried to map%s 0x%08lx-0x%08lx on %s BAR %d "
> - "(size 0x%08lx)\n",
> - current->comm, sparse ? " sparse" : "", start, start + nr,
> - pci_name(pdev), num, size);
> - return 0;
> + return start < size && size - start >= nr;
> }
>
> /**
>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits()
2026-04-10 11:14 ` Ilpo Järvinen
@ 2026-04-10 11:21 ` Krzysztof Wilczyński
2026-04-10 11:32 ` Ilpo Järvinen
0 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:21 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > Currently, __pci_mmap_fits() computes the BAR size using
> > pci_resource_len() - 1, which wraps to a large value when the
> > BAR length is zero, causing the bounds check to incorrectly
> > succeed.
> >
> > Thus, add an early return for empty resources.
> >
> > Also, remove the WARN() that fires when userspace attempts to
> > mmap beyond the BAR bounds. The check still returns 0 to reject
> > the mapping, but the warning is excessive for normal operation.
> >
> > A similar warning was removed from the PCI core in the commit
> > 3b519e4ea618 ("PCI: fix size checks for mmap() on /proc/bus/pci files").
>
> This looks like entirely separate two changes to me which just happen
> within the same context.
True. I could split this into two separate patches. However, the early
return is so trivial, that I decided to keep it here, in lieu of that the
linked patch did, too.
Thoughts?
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits()
2026-04-10 11:21 ` Krzysztof Wilczyński
@ 2026-04-10 11:32 ` Ilpo Järvinen
2026-04-10 11:55 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:32 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 1660 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Hello,
>
> > > Currently, __pci_mmap_fits() computes the BAR size using
> > > pci_resource_len() - 1, which wraps to a large value when the
> > > BAR length is zero, causing the bounds check to incorrectly
> > > succeed.
> > >
> > > Thus, add an early return for empty resources.
> > >
> > > Also, remove the WARN() that fires when userspace attempts to
> > > mmap beyond the BAR bounds. The check still returns 0 to reject
> > > the mapping, but the warning is excessive for normal operation.
> > >
> > > A similar warning was removed from the PCI core in the commit
> > > 3b519e4ea618 ("PCI: fix size checks for mmap() on /proc/bus/pci files").
> >
> > This looks like entirely separate two changes to me which just happen
> > within the same context.
>
> True. I could split this into two separate patches. However, the early
> return is so trivial, that I decided to keep it here, in lieu of that the
> linked patch did, too.
>
> Thoughts?
It's not just adding the early return that would go to the first patch but
you also need to rearrange the len for that. Effectively, the change is
split in half, each becoming cleaner and more focused (both diff and the
changelog text).
As is I'm left on the borderline, while I can see it's "correct" after
splitting those changes inside my head, I also know it could have been
done better. I'd easily given rev-by for both if they'd have been done
individually, saved the time writing these emails about it, and
effectively "forgotten" the patches (including upcoming versions of the
series).
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits()
2026-04-10 11:32 ` Ilpo Järvinen
@ 2026-04-10 11:55 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:55 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > > This looks like entirely separate two changes to me which just happen
> > > within the same context.
> >
> > True. I could split this into two separate patches. However, the early
> > return is so trivial, that I decided to keep it here, in lieu of that the
> > linked patch did, too.
> >
> > Thoughts?
>
> It's not just adding the early return that would go to the first patch but
> you also need to rearrange the len for that. Effectively, the change is
> split in half, each becoming cleaner and more focused (both diff and the
> changelog text).
>
> As is I'm left on the borderline, while I can see it's "correct" after
> splitting those changes inside my head, I also know it could have been
> done better. I'd easily given rev-by for both if they'd have been done
> individually, saved the time writing these emails about it, and
> effectively "forgotten" the patches (including upcoming versions of the
> series).
A simple "yes, please split" would suffice. :) For future reference.
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (12 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 13/20] alpha/PCI: Clean up __pci_mmap_fits() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 11:19 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 15/20] alpha/PCI: Convert resource files to static attributes Krzysztof Wilczyński
` (6 subsequent siblings)
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Add macros for declaring static binary attributes for Alpha's PCI
resource files:
- pci_dev_resource_attr(), for dense/BWX systems (mmap dense)
- pci_dev_resource_sparse_attr(), for sparse systems (mmap sparse)
- pci_dev_resource_dense_attr(), for dense companion files (mmap dense)
Each macro creates a const bin_attribute with the BAR index stored in
the .private property and the appropriate .mmap callback.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 867199b988de..0e016b597b06 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -104,6 +104,26 @@ static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj,
return pci_mmap_resource(kobj, attr, vma, 0);
}
+#define __pci_dev_resource_attr(_bar, _name, _suffix, _mmap) \
+static const struct bin_attribute \
+pci_dev_resource##_bar##_suffix##_attr = { \
+ .attr = { .name = __stringify(_name), .mode = 0600 }, \
+ .private = (void *)(unsigned long)(_bar), \
+ .mmap = (_mmap), \
+}
+
+#define pci_dev_resource_attr(_bar) \
+ __pci_dev_resource_attr(_bar, resource##_bar,, \
+ pci_mmap_resource_dense)
+
+#define pci_dev_resource_sparse_attr(_bar) \
+ __pci_dev_resource_attr(_bar, resource##_bar##_sparse, _sparse, \
+ pci_mmap_resource_sparse)
+
+#define pci_dev_resource_dense_attr(_bar) \
+ __pci_dev_resource_attr(_bar, resource##_bar##_dense, _dense, \
+ pci_mmap_resource_dense)
+
/**
* pci_remove_resource_files - cleanup resource files
* @pdev: pci_dev to cleanup
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros
2026-04-10 5:50 ` [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros Krzysztof Wilczyński
@ 2026-04-10 11:19 ` Ilpo Järvinen
2026-04-10 11:48 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:19 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 2058 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Add macros for declaring static binary attributes for Alpha's PCI
> resource files:
>
> - pci_dev_resource_attr(), for dense/BWX systems (mmap dense)
> - pci_dev_resource_sparse_attr(), for sparse systems (mmap sparse)
> - pci_dev_resource_dense_attr(), for dense companion files (mmap dense)
>
> Each macro creates a const bin_attribute with the BAR index stored in
> the .private property and the appropriate .mmap callback.
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> arch/alpha/kernel/pci-sysfs.c | 20 ++++++++++++++++++++
> 1 file changed, 20 insertions(+)
>
> diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
> index 867199b988de..0e016b597b06 100644
> --- a/arch/alpha/kernel/pci-sysfs.c
> +++ b/arch/alpha/kernel/pci-sysfs.c
> @@ -104,6 +104,26 @@ static int pci_mmap_resource_dense(struct file *filp, struct kobject *kobj,
> return pci_mmap_resource(kobj, attr, vma, 0);
> }
>
> +#define __pci_dev_resource_attr(_bar, _name, _suffix, _mmap) \
> +static const struct bin_attribute \
> +pci_dev_resource##_bar##_suffix##_attr = { \
> + .attr = { .name = __stringify(_name), .mode = 0600 }, \
> + .private = (void *)(unsigned long)(_bar), \
> + .mmap = (_mmap), \
> +}
> +
> +#define pci_dev_resource_attr(_bar) \
> + __pci_dev_resource_attr(_bar, resource##_bar,, \
> + pci_mmap_resource_dense)
> +
> +#define pci_dev_resource_sparse_attr(_bar) \
> + __pci_dev_resource_attr(_bar, resource##_bar##_sparse, _sparse, \
> + pci_mmap_resource_sparse)
> +
> +#define pci_dev_resource_dense_attr(_bar) \
> + __pci_dev_resource_attr(_bar, resource##_bar##_dense, _dense, \
> + pci_mmap_resource_dense)
> +
> /**
> * pci_remove_resource_files - cleanup resource files
> * @pdev: pci_dev to cleanup
>
Wouldn't this belong together with the next patch, or is there some good
reason why you added them separately?
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros
2026-04-10 11:19 ` Ilpo Järvinen
@ 2026-04-10 11:48 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 11:48 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > +#define __pci_dev_resource_attr(_bar, _name, _suffix, _mmap) \
> > +static const struct bin_attribute \
> > +pci_dev_resource##_bar##_suffix##_attr = { \
> > + .attr = { .name = __stringify(_name), .mode = 0600 }, \
> > + .private = (void *)(unsigned long)(_bar), \
> > + .mmap = (_mmap), \
> > +}
> > +
> > +#define pci_dev_resource_attr(_bar) \
> > + __pci_dev_resource_attr(_bar, resource##_bar,, \
> > + pci_mmap_resource_dense)
> > +
> > +#define pci_dev_resource_sparse_attr(_bar) \
> > + __pci_dev_resource_attr(_bar, resource##_bar##_sparse, _sparse, \
> > + pci_mmap_resource_sparse)
> > +
> > +#define pci_dev_resource_dense_attr(_bar) \
> > + __pci_dev_resource_attr(_bar, resource##_bar##_dense, _dense, \
> > + pci_mmap_resource_dense)
> > +
> > /**
> > * pci_remove_resource_files - cleanup resource files
> > * @pdev: pci_dev to cleanup
> >
>
> Wouldn't this belong together with the next patch, or is there some good
> reason why you added them separately?
No specific reason other than to make it easier to review. The pattern
here is: macros first and then users later (when converting things over).
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 15/20] alpha/PCI: Convert resource files to static attributes
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (13 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 14/20] alpha/PCI: Add static PCI resource attribute macros Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 16/20] PCI/sysfs: Remove pci_{create,remove}_sysfs_dev_files() Krzysztof Wilczyński
` (5 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, Alpha's PCI resource files (resourceN, resourceN_sparse,
resourceN_dense) are dynamically created by pci_create_resource_files(),
which overrides the generic __weak implementation. The current code
allocates bin_attributes at runtime and manages them via the res_attr[]
and res_attr_wc[] fields in struct pci_dev.
Thus, convert to static const attributes with three attribute groups
(plain, sparse, dense), each with an .is_bin_visible callback that
checks BAR length, has_sparse(), and sparse_mem_mmap_fits(). A .bin_size
callback provides the resource size to the kernfs node, with the sparse
variant shifting by 5 bits for byte-level addressing.
Register the groups via ARCH_PCI_DEV_GROUPS so the driver model handles
creation and removal automatically.
Finally, remove pci_create_resource_files(), pci_remove_resource_files(),
pci_create_attr(), and pci_create_one_attr() which are no longer needed.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/include/asm/pci.h | 9 ++
arch/alpha/kernel/pci-sysfs.c | 292 +++++++++++++++++++---------------
2 files changed, 173 insertions(+), 128 deletions(-)
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index 6c04fcbdc8ed..ef19295f2e33 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -88,4 +88,13 @@ extern void pci_adjust_legacy_attr(struct pci_bus *bus,
enum pci_mmap_state mmap_type);
#define HAVE_PCI_LEGACY 1
+extern const struct attribute_group pci_dev_resource_attr_group;
+extern const struct attribute_group pci_dev_resource_sparse_attr_group;
+extern const struct attribute_group pci_dev_resource_dense_attr_group;
+
+#define ARCH_PCI_DEV_GROUPS \
+ &pci_dev_resource_attr_group, \
+ &pci_dev_resource_sparse_attr_group, \
+ &pci_dev_resource_dense_attr_group,
+
#endif /* __ALPHA_PCI_H */
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 0e016b597b06..27adfe6dbd5e 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -12,8 +12,6 @@
#include <linux/sched.h>
#include <linux/security.h>
-#include <linux/stat.h>
-#include <linux/slab.h>
#include <linux/pci.h>
static int hose_mmap_page_range(struct pci_controller *hose,
@@ -124,34 +122,6 @@ pci_dev_resource##_bar##_suffix##_attr = { \
__pci_dev_resource_attr(_bar, resource##_bar##_dense, _dense, \
pci_mmap_resource_dense)
-/**
- * pci_remove_resource_files - cleanup resource files
- * @pdev: pci_dev to cleanup
- *
- * If we created resource files for @dev, remove them from sysfs and
- * free their resources.
- */
-void pci_remove_resource_files(struct pci_dev *pdev)
-{
- int i;
-
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
- struct bin_attribute *res_attr;
-
- res_attr = pdev->res_attr[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
-
- res_attr = pdev->res_attr_wc[i];
- if (res_attr) {
- sysfs_remove_bin_file(&pdev->dev.kobj, res_attr);
- kfree(res_attr);
- }
- }
-}
-
static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
{
struct pci_bus_region bar;
@@ -171,104 +141,6 @@ static int sparse_mem_mmap_fits(struct pci_dev *pdev, int num)
return bar.end < sparse_size;
}
-static int pci_create_one_attr(struct pci_dev *pdev, int num, char *name,
- char *suffix, struct bin_attribute *res_attr,
- unsigned long sparse)
-{
- size_t size = pci_resource_len(pdev, num);
-
- sprintf(name, "resource%d%s", num, suffix);
- res_attr->mmap = sparse ? pci_mmap_resource_sparse :
- pci_mmap_resource_dense;
- res_attr->attr.name = name;
- res_attr->attr.mode = S_IRUSR | S_IWUSR;
- res_attr->size = sparse ? size << 5 : size;
- res_attr->private = (void *)(unsigned long)num;
- return sysfs_create_bin_file(&pdev->dev.kobj, res_attr);
-}
-
-static int pci_create_attr(struct pci_dev *pdev, int num)
-{
- /* allocate attribute structure, piggyback attribute name */
- int retval, nlen1, nlen2 = 0, res_count = 1;
- unsigned long sparse_base, dense_base;
- struct bin_attribute *attr;
- struct pci_controller *hose = pdev->sysdata;
- char *suffix, *attr_name;
-
- suffix = ""; /* Assume bwx machine, normal resourceN files. */
- nlen1 = 10;
-
- if (pci_resource_flags(pdev, num) & IORESOURCE_MEM) {
- sparse_base = hose->sparse_mem_base;
- dense_base = hose->dense_mem_base;
- if (sparse_base && !sparse_mem_mmap_fits(pdev, num)) {
- sparse_base = 0;
- suffix = "_dense";
- nlen1 = 16; /* resourceN_dense */
- }
- } else {
- sparse_base = hose->sparse_io_base;
- dense_base = hose->dense_io_base;
- }
-
- if (sparse_base) {
- suffix = "_sparse";
- nlen1 = 17;
- if (dense_base) {
- nlen2 = 16; /* resourceN_dense */
- res_count = 2;
- }
- }
-
- attr = kzalloc(sizeof(*attr) * res_count + nlen1 + nlen2, GFP_ATOMIC);
- if (!attr)
- return -ENOMEM;
-
- /* Create bwx, sparse or single dense file */
- attr_name = (char *)(attr + res_count);
- pdev->res_attr[num] = attr;
- retval = pci_create_one_attr(pdev, num, attr_name, suffix, attr,
- sparse_base);
- if (retval || res_count == 1)
- return retval;
-
- /* Create dense file */
- attr_name += nlen1;
- attr++;
- pdev->res_attr_wc[num] = attr;
- return pci_create_one_attr(pdev, num, attr_name, "_dense", attr, 0);
-}
-
-/**
- * pci_create_resource_files - create resource files in sysfs for @pdev
- * @pdev: pci_dev in question
- *
- * Walk the resources in @dev creating files for each resource available.
- *
- * Return: %0 on success, or negative error code
- */
-int pci_create_resource_files(struct pci_dev *pdev)
-{
- int i;
- int retval;
-
- /* Expose the PCI resources from this device as files */
- for (i = 0; i < PCI_STD_NUM_BARS; i++) {
-
- /* skip empty resources */
- if (!pci_resource_len(pdev, i))
- continue;
-
- retval = pci_create_attr(pdev, i);
- if (retval) {
- pci_remove_resource_files(pdev);
- return retval;
- }
- }
- return 0;
-}
-
/* Legacy I/O bus mapping stuff. */
static int __legacy_mmap_fits(struct pci_controller *hose,
@@ -388,3 +260,167 @@ int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val, size_t size)
}
return -EINVAL;
}
+
+pci_dev_resource_attr(0);
+pci_dev_resource_attr(1);
+pci_dev_resource_attr(2);
+pci_dev_resource_attr(3);
+pci_dev_resource_attr(4);
+pci_dev_resource_attr(5);
+
+pci_dev_resource_sparse_attr(0);
+pci_dev_resource_sparse_attr(1);
+pci_dev_resource_sparse_attr(2);
+pci_dev_resource_sparse_attr(3);
+pci_dev_resource_sparse_attr(4);
+pci_dev_resource_sparse_attr(5);
+
+pci_dev_resource_dense_attr(0);
+pci_dev_resource_dense_attr(1);
+pci_dev_resource_dense_attr(2);
+pci_dev_resource_dense_attr(3);
+pci_dev_resource_dense_attr(4);
+pci_dev_resource_dense_attr(5);
+
+static inline enum pci_mmap_state pci_bar_mmap_type(struct pci_dev *pdev,
+ int bar)
+{
+ return (pci_resource_flags(pdev, bar) & IORESOURCE_MEM) ?
+ pci_mmap_mem : pci_mmap_io;
+}
+
+static inline umode_t __pci_dev_resource_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+
+ if (!pci_resource_len(pdev, bar))
+ return 0;
+
+ return a->attr.mode;
+}
+
+static umode_t pci_dev_resource_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ struct pci_controller *hose = pdev->sysdata;
+
+ if (has_sparse(hose, pci_bar_mmap_type(pdev, bar)))
+ return 0;
+
+ return __pci_dev_resource_is_visible(kobj, a, bar);
+}
+
+static umode_t pci_dev_resource_sparse_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ struct pci_controller *hose = pdev->sysdata;
+ enum pci_mmap_state type = pci_bar_mmap_type(pdev, bar);
+
+ if (!has_sparse(hose, type))
+ return 0;
+
+ if (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar))
+ return 0;
+
+ return __pci_dev_resource_is_visible(kobj, a, bar);
+}
+
+static umode_t pci_dev_resource_dense_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ struct pci_controller *hose = pdev->sysdata;
+ enum pci_mmap_state type = pci_bar_mmap_type(pdev, bar);
+ unsigned long dense_base;
+
+ if (!has_sparse(hose, type))
+ return 0;
+
+ if (type == pci_mmap_mem && !sparse_mem_mmap_fits(pdev, bar))
+ return __pci_dev_resource_is_visible(kobj, a, bar);
+
+ dense_base = (type == pci_mmap_mem) ? hose->dense_mem_base :
+ hose->dense_io_base;
+ if (!dense_base)
+ return 0;
+
+ return __pci_dev_resource_is_visible(kobj, a, bar);
+}
+
+static inline size_t __pci_dev_resource_bin_size(struct kobject *kobj,
+ int bar, bool sparse)
+{
+ struct pci_dev *pdev = to_pci_dev(kobj_to_dev(kobj));
+ size_t size = pci_resource_len(pdev, bar);
+
+ return sparse ? size << 5 : size;
+}
+
+static size_t pci_dev_resource_bin_size(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ return __pci_dev_resource_bin_size(kobj, bar, false);
+}
+
+static size_t pci_dev_resource_sparse_bin_size(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int bar)
+{
+ return __pci_dev_resource_bin_size(kobj, bar, true);
+}
+
+static const struct bin_attribute *const pci_dev_resource_attrs[] = {
+ &pci_dev_resource0_attr,
+ &pci_dev_resource1_attr,
+ &pci_dev_resource2_attr,
+ &pci_dev_resource3_attr,
+ &pci_dev_resource4_attr,
+ &pci_dev_resource5_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_dev_resource_sparse_attrs[] = {
+ &pci_dev_resource0_sparse_attr,
+ &pci_dev_resource1_sparse_attr,
+ &pci_dev_resource2_sparse_attr,
+ &pci_dev_resource3_sparse_attr,
+ &pci_dev_resource4_sparse_attr,
+ &pci_dev_resource5_sparse_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_dev_resource_dense_attrs[] = {
+ &pci_dev_resource0_dense_attr,
+ &pci_dev_resource1_dense_attr,
+ &pci_dev_resource2_dense_attr,
+ &pci_dev_resource3_dense_attr,
+ &pci_dev_resource4_dense_attr,
+ &pci_dev_resource5_dense_attr,
+ NULL,
+};
+
+const struct attribute_group pci_dev_resource_attr_group = {
+ .bin_attrs = pci_dev_resource_attrs,
+ .is_bin_visible = pci_dev_resource_is_visible,
+ .bin_size = pci_dev_resource_bin_size,
+};
+
+const struct attribute_group pci_dev_resource_sparse_attr_group = {
+ .bin_attrs = pci_dev_resource_sparse_attrs,
+ .is_bin_visible = pci_dev_resource_sparse_is_visible,
+ .bin_size = pci_dev_resource_sparse_bin_size,
+};
+
+const struct attribute_group pci_dev_resource_dense_attr_group = {
+ .bin_attrs = pci_dev_resource_dense_attrs,
+ .is_bin_visible = pci_dev_resource_dense_is_visible,
+ .bin_size = pci_dev_resource_bin_size,
+};
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 16/20] PCI/sysfs: Remove pci_{create,remove}_sysfs_dev_files()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (14 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 15/20] alpha/PCI: Convert resource files to static attributes Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 17/20] alpha/PCI: Compute legacy size in pci_mmap_legacy_page_range() Krzysztof Wilczyński
` (4 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, pci_create_sysfs_dev_files() and pci_remove_sysfs_dev_files()
are no-op stubs. With both the generic and Alpha resource files now
handled by static attribute groups, no platform needs dynamic per-device
sysfs file creation.
Thus, remove both functions, their declarations, and the call sites in
pci_bus_add_device() and pci_stop_bus_device().
Remove __weak pci_create_resource_files() and pci_remove_resource_files()
stubs and their declarations in pci.h, as no architecture overrides them
anymore.
Remove the res_attr[] and res_attr_wc[] fields from struct pci_dev
which were used to track dynamically allocated resource attributes.
Finally, simplify pci_sysfs_init() to only handle legacy file creation
under HAVE_PCI_LEGACY, removing the per-device loop and the
HAVE_PCI_SYSFS_INIT helper added earlier.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/bus.c | 1 -
drivers/pci/pci-sysfs.c | 53 ++---------------------------------------
drivers/pci/pci.h | 4 ----
drivers/pci/remove.c | 1 -
include/linux/pci.h | 9 -------
5 files changed, 2 insertions(+), 66 deletions(-)
diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c
index 6c1ad1f542d9..655ed53436d3 100644
--- a/drivers/pci/bus.c
+++ b/drivers/pci/bus.c
@@ -354,7 +354,6 @@ void pci_bus_add_device(struct pci_dev *dev)
pci_fixup_device(pci_fixup_final, dev);
if (pci_is_bridge(dev))
of_pci_make_dev_node(dev);
- pci_create_sysfs_dev_files(dev);
pci_proc_attach_device(dev);
pci_bridge_d3_update(dev);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 062921d5df9b..40b5e21d77f3 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -37,12 +37,7 @@
#define ARCH_PCI_DEV_GROUPS
#endif
-#if defined(HAVE_PCI_LEGACY) || \
- !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
-#define HAVE_PCI_SYSFS_INIT
-#endif
-
-#ifdef HAVE_PCI_SYSFS_INIT
+#ifdef HAVE_PCI_LEGACY
static int sysfs_initialized; /* = 0 */
#endif
@@ -1399,9 +1394,6 @@ static const struct attribute_group *pci_dev_resource_attr_groups[] = {
&pci_dev_resource_wc_attr_group,
NULL,
};
-#else
-int __weak pci_create_resource_files(struct pci_dev *dev) { return 0; }
-void __weak pci_remove_resource_files(struct pci_dev *dev) { }
#endif
/**
@@ -1771,54 +1763,13 @@ static const struct attribute_group pci_dev_resource_resize_attr_group = {
};
#endif
-#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
-int pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; }
-void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { }
-#else
-int __must_check pci_create_sysfs_dev_files(struct pci_dev *pdev)
-{
- if (!sysfs_initialized)
- return -EACCES;
-
- return pci_create_resource_files(pdev);
-}
-
-/**
- * pci_remove_sysfs_dev_files - cleanup PCI specific sysfs files
- * @pdev: device whose entries we should free
- *
- * Cleanup when @pdev is removed from sysfs.
- */
-void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
-{
- if (!sysfs_initialized)
- return;
-
- pci_remove_resource_files(pdev);
-}
-#endif
-
-#ifdef HAVE_PCI_SYSFS_INIT
+#ifdef HAVE_PCI_LEGACY
static int __init pci_sysfs_init(void)
{
-#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
struct pci_bus *pbus = NULL;
sysfs_initialized = 1;
-#else
- struct pci_dev *pdev = NULL;
- struct pci_bus *pbus = NULL;
- int retval;
- sysfs_initialized = 1;
- for_each_pci_dev(pdev) {
- retval = pci_create_sysfs_dev_files(pdev);
- if (retval) {
- pci_dev_put(pdev);
- return retval;
- }
- }
-#endif
while ((pbus = pci_find_next_bus(pbus)))
pci_create_legacy_files(pbus);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 13d998fbacce..1bf165595583 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -391,16 +391,12 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
}
#ifdef CONFIG_SYSFS
-int pci_create_sysfs_dev_files(struct pci_dev *pdev);
-void pci_remove_sysfs_dev_files(struct pci_dev *pdev);
extern const struct attribute_group *pci_dev_groups[];
extern const struct attribute_group *pci_dev_attr_groups[];
extern const struct attribute_group *pcibus_groups[];
extern const struct attribute_group *pci_bus_groups[];
extern const struct attribute_group pci_doe_sysfs_group;
#else
-static inline int pci_create_sysfs_dev_files(struct pci_dev *pdev) { return 0; }
-static inline void pci_remove_sysfs_dev_files(struct pci_dev *pdev) { }
#define pci_dev_groups NULL
#define pci_dev_attr_groups NULL
#define pcibus_groups NULL
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index e9d519993853..6e796dbc5b29 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -26,7 +26,6 @@ static void pci_stop_dev(struct pci_dev *dev)
device_release_driver(&dev->dev);
pci_proc_detach_device(dev);
- pci_remove_sysfs_dev_files(dev);
of_pci_remove_node(dev);
}
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 2940c80fd7c5..5a418fbe5a5f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -507,10 +507,6 @@ struct pci_dev {
spinlock_t pcie_cap_lock; /* Protects RMW ops in capability accessors */
u32 saved_config_space[16]; /* Config space saved at suspend time */
struct hlist_head saved_cap_space;
-#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
- struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
- struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
-#endif
#ifdef CONFIG_HOTPLUG_PCI_PCIE
unsigned int broken_cmd_compl:1; /* No compl for some cmds */
@@ -2503,11 +2499,6 @@ int pcibios_alloc_irq(struct pci_dev *dev);
void pcibios_free_irq(struct pci_dev *dev);
resource_size_t pcibios_default_alignment(void);
-#if !defined(HAVE_PCI_MMAP) && !defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
-extern int pci_create_resource_files(struct pci_dev *dev);
-extern void pci_remove_resource_files(struct pci_dev *dev);
-#endif
-
#if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG)
void __init pci_mmcfg_early_init(void);
void __init pci_mmcfg_late_init(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 17/20] alpha/PCI: Compute legacy size in pci_mmap_legacy_page_range()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (15 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 16/20] PCI/sysfs: Remove pci_{create,remove}_sysfs_dev_files() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 18/20] PCI/sysfs: Add __weak pci_legacy_has_sparse() helper Krzysztof Wilczyński
` (3 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, pci_mmap_legacy_page_range() reads the legacy resource
size from bus->legacy_mem->size or bus->legacy_io->size. This
couples the mmap bounds check to the struct pci_bus fields that
will be removed when legacy attributes are converted to static
definitions.
Compute the size directly from the known constants (0x100000 for
memory, 0xffff for I/O) and shift by 5 bits for sparse systems.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 27adfe6dbd5e..2da95d965e9c 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -180,8 +180,10 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
int sparse = has_sparse(hose, mmap_type);
unsigned long res_size;
- res_size = (mmap_type == pci_mmap_mem) ? bus->legacy_mem->size :
- bus->legacy_io->size;
+ res_size = (mmap_type == pci_mmap_mem) ? 0x100000 : 0xffff;
+ if (sparse)
+ res_size <<= 5;
+
if (!__legacy_mmap_fits(hose, vma, res_size, sparse))
return -EINVAL;
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 18/20] PCI/sysfs: Add __weak pci_legacy_has_sparse() helper
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (16 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 17/20] alpha/PCI: Compute legacy size in pci_mmap_legacy_page_range() Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 5:50 ` [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions Krzysztof Wilczyński
` (2 subsequent siblings)
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, Alpha's sparse/dense legacy attribute handling is done via
pci_adjust_legacy_attr(), which updates dynamically allocated attributes
at runtime. The upcoming conversion to static attributes needs a way
to determine sparse support at visibility check time.
Add a __weak pci_legacy_has_sparse() that returns false by default.
Alpha overrides it to check has_sparse() on the bus host controller.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/kernel/pci-sysfs.c | 7 +++++++
drivers/pci/pci-sysfs.c | 6 ++++++
drivers/pci/pci.h | 4 ++++
3 files changed, 17 insertions(+)
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 2da95d965e9c..2031a3b6972c 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -190,6 +190,13 @@ int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma,
return hose_mmap_page_range(hose, vma, mmap_type, sparse);
}
+bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ return has_sparse(hose, type);
+}
+
/**
* pci_adjust_legacy_attr - adjustment of legacy file attributes
* @bus: bus to create files under
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 40b5e21d77f3..fe079fb31dce 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -1019,6 +1019,12 @@ static int pci_mmap_legacy_io(struct file *filp, struct kobject *kobj,
return pci_mmap_legacy_page_range(bus, vma, pci_mmap_io);
}
+bool __weak pci_legacy_has_sparse(struct pci_bus *bus,
+ enum pci_mmap_state type)
+{
+ return false;
+}
+
/**
* pci_adjust_legacy_attr - adjustment of legacy file attributes
* @b: bus to create files under
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 1bf165595583..f52caf7e4d13 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -390,6 +390,10 @@ static inline int pci_no_d1d2(struct pci_dev *dev)
}
+#ifdef HAVE_PCI_LEGACY
+bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type);
+#endif
+
#ifdef CONFIG_SYSFS
extern const struct attribute_group *pci_dev_groups[];
extern const struct attribute_group *pci_dev_attr_groups[];
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (17 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 18/20] PCI/sysfs: Add __weak pci_legacy_has_sparse() helper Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 11:47 ` Ilpo Järvinen
2026-04-10 5:50 ` [PATCH 20/20] PCI/sysfs: Remove pci_create_legacy_files() and pci_sysfs_init() Krzysztof Wilczyński
2026-04-10 18:18 ` [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
20 siblings, 1 reply; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, legacy_io and legacy_mem are dynamically allocated and
created by pci_create_legacy_files(), with pci_adjust_legacy_attr()
updating the attributes at runtime on Alpha to rename them and shift
the size for sparse addressing.
Convert to four static const attributes (legacy_io, legacy_io_sparse,
legacy_mem, legacy_mem_sparse) with is_bin_visible() callbacks that
use pci_legacy_has_sparse() to select the appropriate variant per bus.
The sizes are compile-time constants and .size is set directly on
each attribute.
Register the groups in pcibus_groups[] under a HAVE_PCI_LEGACY guard
so the driver model handles creation and removal automatically.
Stub out pci_create_legacy_files() and pci_remove_legacy_files() as
the dynamic creation is no longer needed. Remove the __weak
pci_adjust_legacy_attr(), Alpha's override, and its declaration from
both Alpha and PowerPC asm/pci.h headers.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
arch/alpha/include/asm/pci.h | 4 +-
arch/alpha/kernel/pci-sysfs.c | 24 ----
arch/powerpc/include/asm/pci.h | 2 -
drivers/pci/pci-sysfs.c | 200 ++++++++++++++++++++-------------
4 files changed, 122 insertions(+), 108 deletions(-)
diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
index ef19295f2e33..ad5d1391e1fa 100644
--- a/arch/alpha/include/asm/pci.h
+++ b/arch/alpha/include/asm/pci.h
@@ -84,8 +84,8 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state);
-extern void pci_adjust_legacy_attr(struct pci_bus *bus,
- enum pci_mmap_state mmap_type);
+extern bool pci_legacy_has_sparse(struct pci_bus *bus,
+ enum pci_mmap_state type);
#define HAVE_PCI_LEGACY 1
extern const struct attribute_group pci_dev_resource_attr_group;
diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
index 2031a3b6972c..2db91169bf5a 100644
--- a/arch/alpha/kernel/pci-sysfs.c
+++ b/arch/alpha/kernel/pci-sysfs.c
@@ -197,30 +197,6 @@ bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type)
return has_sparse(hose, type);
}
-/**
- * pci_adjust_legacy_attr - adjustment of legacy file attributes
- * @bus: bus to create files under
- * @mmap_type: I/O port or memory
- *
- * Adjust file name and size for sparse mappings.
- */
-void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)
-{
- struct pci_controller *hose = bus->sysdata;
-
- if (!has_sparse(hose, mmap_type))
- return;
-
- if (mmap_type == pci_mmap_mem) {
- bus->legacy_mem->attr.name = "legacy_mem_sparse";
- bus->legacy_mem->size <<= 5;
- } else {
- bus->legacy_io->attr.name = "legacy_io_sparse";
- bus->legacy_io->size <<= 5;
- }
- return;
-}
-
/* Legacy I/O bus read/write functions */
int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
{
diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
index 46a9c4491ed0..72f286e74786 100644
--- a/arch/powerpc/include/asm/pci.h
+++ b/arch/powerpc/include/asm/pci.h
@@ -82,8 +82,6 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
struct vm_area_struct *vma,
enum pci_mmap_state mmap_state);
-extern void pci_adjust_legacy_attr(struct pci_bus *bus,
- enum pci_mmap_state mmap_type);
#define HAVE_PCI_LEGACY 1
extern void pcibios_claim_one_bus(struct pci_bus *b);
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index fe079fb31dce..dc0bb0488317 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -702,11 +702,6 @@ static const struct attribute_group pcibus_group = {
.attrs = pcibus_attrs,
};
-const struct attribute_group *pcibus_groups[] = {
- &pcibus_group,
- NULL,
-};
-
static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -1025,91 +1020,136 @@ bool __weak pci_legacy_has_sparse(struct pci_bus *bus,
return false;
}
-/**
- * pci_adjust_legacy_attr - adjustment of legacy file attributes
- * @b: bus to create files under
- * @mmap_type: I/O port or memory
- *
- * Stub implementation. Can be overridden by arch if necessary.
- */
-void __weak pci_adjust_legacy_attr(struct pci_bus *b,
- enum pci_mmap_state mmap_type)
+static inline umode_t __pci_legacy_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ enum pci_mmap_state type,
+ bool sparse)
{
+ struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
+
+ if (pci_legacy_has_sparse(bus, type) != sparse)
+ return 0;
+
+ return a->attr.mode;
}
-/**
- * pci_create_legacy_files - create legacy I/O port and memory files
- * @b: bus to create files under
- *
- * Some platforms allow access to legacy I/O port and ISA memory space on
- * a per-bus basis. This routine creates the files and ties them into
- * their associated read, write and mmap files from pci-sysfs.c
- *
- * On error unwind, but don't propagate the error to the caller
- * as it is ok to set up the PCI bus without these files.
- */
-void pci_create_legacy_files(struct pci_bus *b)
+static umode_t pci_legacy_io_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a, int n)
{
- int error;
-
- if (!sysfs_initialized)
- return;
-
- b->legacy_io = kzalloc_objs(struct bin_attribute, 2, GFP_ATOMIC);
- if (!b->legacy_io)
- goto kzalloc_err;
-
- sysfs_bin_attr_init(b->legacy_io);
- b->legacy_io->attr.name = "legacy_io";
- b->legacy_io->size = 0xffff;
- b->legacy_io->attr.mode = 0600;
- b->legacy_io->read = pci_read_legacy_io;
- b->legacy_io->write = pci_write_legacy_io;
- /* See pci_create_attr() for motivation */
- b->legacy_io->llseek = pci_llseek_resource;
- b->legacy_io->mmap = pci_mmap_legacy_io;
- b->legacy_io->f_mapping = iomem_get_mapping;
- pci_adjust_legacy_attr(b, pci_mmap_io);
- error = device_create_bin_file(&b->dev, b->legacy_io);
- if (error)
- goto legacy_io_err;
-
- /* Allocated above after the legacy_io struct */
- b->legacy_mem = b->legacy_io + 1;
- sysfs_bin_attr_init(b->legacy_mem);
- b->legacy_mem->attr.name = "legacy_mem";
- b->legacy_mem->size = 1024*1024;
- b->legacy_mem->attr.mode = 0600;
- b->legacy_mem->mmap = pci_mmap_legacy_mem;
- /* See pci_create_attr() for motivation */
- b->legacy_mem->llseek = pci_llseek_resource;
- b->legacy_mem->f_mapping = iomem_get_mapping;
- pci_adjust_legacy_attr(b, pci_mmap_mem);
- error = device_create_bin_file(&b->dev, b->legacy_mem);
- if (error)
- goto legacy_mem_err;
-
- return;
-
-legacy_mem_err:
- device_remove_bin_file(&b->dev, b->legacy_io);
-legacy_io_err:
- kfree(b->legacy_io);
- b->legacy_io = NULL;
-kzalloc_err:
- dev_warn(&b->dev, "could not create legacy I/O port and ISA memory resources in sysfs\n");
+ return __pci_legacy_is_visible(kobj, a, pci_mmap_io, false);
}
-void pci_remove_legacy_files(struct pci_bus *b)
+static umode_t pci_legacy_io_sparse_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
{
- if (b->legacy_io) {
- device_remove_bin_file(&b->dev, b->legacy_io);
- device_remove_bin_file(&b->dev, b->legacy_mem);
- kfree(b->legacy_io); /* both are allocated here */
- }
+ return __pci_legacy_is_visible(kobj, a, pci_mmap_io, true);
}
+
+static umode_t pci_legacy_mem_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a, int n)
+{
+ return __pci_legacy_is_visible(kobj, a, pci_mmap_mem, false);
+}
+
+static umode_t pci_legacy_mem_sparse_is_visible(struct kobject *kobj,
+ const struct bin_attribute *a,
+ int n)
+{
+ return __pci_legacy_is_visible(kobj, a, pci_mmap_mem, true);
+}
+
+static const struct bin_attribute pci_legacy_io_attr = {
+ .attr = { .name = "legacy_io", .mode = 0600 },
+ .size = 0xffff,
+ .read = pci_read_legacy_io,
+ .write = pci_write_legacy_io,
+ .mmap = pci_mmap_legacy_io,
+ .llseek = pci_llseek_resource,
+ .f_mapping = iomem_get_mapping,
+};
+
+static const struct bin_attribute pci_legacy_io_sparse_attr = {
+ .attr = { .name = "legacy_io_sparse", .mode = 0600 },
+ .size = 0xffff << 5,
+ .read = pci_read_legacy_io,
+ .write = pci_write_legacy_io,
+ .mmap = pci_mmap_legacy_io,
+ .llseek = pci_llseek_resource,
+ .f_mapping = iomem_get_mapping,
+};
+
+static const struct bin_attribute pci_legacy_mem_attr = {
+ .attr = { .name = "legacy_mem", .mode = 0600 },
+ .size = 0x100000,
+ .mmap = pci_mmap_legacy_mem,
+ .llseek = pci_llseek_resource,
+ .f_mapping = iomem_get_mapping,
+};
+
+static const struct bin_attribute pci_legacy_mem_sparse_attr = {
+ .attr = { .name = "legacy_mem_sparse", .mode = 0600 },
+ .size = 0x100000 << 5,
+ .mmap = pci_mmap_legacy_mem,
+ .llseek = pci_llseek_resource,
+ .f_mapping = iomem_get_mapping,
+};
+
+static const struct bin_attribute *const pci_legacy_io_attrs[] = {
+ &pci_legacy_io_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_legacy_io_sparse_attrs[] = {
+ &pci_legacy_io_sparse_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_legacy_mem_attrs[] = {
+ &pci_legacy_mem_attr,
+ NULL,
+};
+
+static const struct bin_attribute *const pci_legacy_mem_sparse_attrs[] = {
+ &pci_legacy_mem_sparse_attr,
+ NULL,
+};
+
+static const struct attribute_group pci_legacy_io_group = {
+ .bin_attrs = pci_legacy_io_attrs,
+ .is_bin_visible = pci_legacy_io_is_visible,
+};
+
+static const struct attribute_group pci_legacy_io_sparse_group = {
+ .bin_attrs = pci_legacy_io_sparse_attrs,
+ .is_bin_visible = pci_legacy_io_sparse_is_visible,
+};
+
+static const struct attribute_group pci_legacy_mem_group = {
+ .bin_attrs = pci_legacy_mem_attrs,
+ .is_bin_visible = pci_legacy_mem_is_visible,
+};
+
+static const struct attribute_group pci_legacy_mem_sparse_group = {
+ .bin_attrs = pci_legacy_mem_sparse_attrs,
+ .is_bin_visible = pci_legacy_mem_sparse_is_visible,
+};
+
+void pci_create_legacy_files(struct pci_bus *b) { }
+void pci_remove_legacy_files(struct pci_bus *b) { }
#endif /* HAVE_PCI_LEGACY */
+const struct attribute_group *pcibus_groups[] = {
+ &pcibus_group,
+#ifdef HAVE_PCI_LEGACY
+ &pci_legacy_io_group,
+ &pci_legacy_io_sparse_group,
+ &pci_legacy_mem_group,
+ &pci_legacy_mem_sparse_group,
+#endif
+ NULL,
+};
+
#if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
/**
* pci_mmap_resource - map a PCI resource into user memory space
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions
2026-04-10 5:50 ` [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions Krzysztof Wilczyński
@ 2026-04-10 11:47 ` Ilpo Järvinen
2026-04-10 12:04 ` Krzysztof Wilczyński
0 siblings, 1 reply; 38+ messages in thread
From: Ilpo Järvinen @ 2026-04-10 11:47 UTC (permalink / raw)
To: Krzysztof Wilczyński
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 11639 bytes --]
On Fri, 10 Apr 2026, Krzysztof Wilczyński wrote:
> Currently, legacy_io and legacy_mem are dynamically allocated and
> created by pci_create_legacy_files(), with pci_adjust_legacy_attr()
> updating the attributes at runtime on Alpha to rename them and shift
> the size for sparse addressing.
>
> Convert to four static const attributes (legacy_io, legacy_io_sparse,
> legacy_mem, legacy_mem_sparse) with is_bin_visible() callbacks that
> use pci_legacy_has_sparse() to select the appropriate variant per bus.
> The sizes are compile-time constants and .size is set directly on
> each attribute.
>
> Register the groups in pcibus_groups[] under a HAVE_PCI_LEGACY guard
> so the driver model handles creation and removal automatically.
>
> Stub out pci_create_legacy_files() and pci_remove_legacy_files() as
> the dynamic creation is no longer needed. Remove the __weak
> pci_adjust_legacy_attr(), Alpha's override, and its declaration from
> both Alpha and PowerPC asm/pci.h headers.
>
> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
> ---
> arch/alpha/include/asm/pci.h | 4 +-
> arch/alpha/kernel/pci-sysfs.c | 24 ----
> arch/powerpc/include/asm/pci.h | 2 -
> drivers/pci/pci-sysfs.c | 200 ++++++++++++++++++++-------------
> 4 files changed, 122 insertions(+), 108 deletions(-)
>
> diff --git a/arch/alpha/include/asm/pci.h b/arch/alpha/include/asm/pci.h
> index ef19295f2e33..ad5d1391e1fa 100644
> --- a/arch/alpha/include/asm/pci.h
> +++ b/arch/alpha/include/asm/pci.h
> @@ -84,8 +84,8 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
> extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
> struct vm_area_struct *vma,
> enum pci_mmap_state mmap_state);
> -extern void pci_adjust_legacy_attr(struct pci_bus *bus,
> - enum pci_mmap_state mmap_type);
> +extern bool pci_legacy_has_sparse(struct pci_bus *bus,
> + enum pci_mmap_state type);
> #define HAVE_PCI_LEGACY 1
>
> extern const struct attribute_group pci_dev_resource_attr_group;
> diff --git a/arch/alpha/kernel/pci-sysfs.c b/arch/alpha/kernel/pci-sysfs.c
> index 2031a3b6972c..2db91169bf5a 100644
> --- a/arch/alpha/kernel/pci-sysfs.c
> +++ b/arch/alpha/kernel/pci-sysfs.c
> @@ -197,30 +197,6 @@ bool pci_legacy_has_sparse(struct pci_bus *bus, enum pci_mmap_state type)
> return has_sparse(hose, type);
> }
>
> -/**
> - * pci_adjust_legacy_attr - adjustment of legacy file attributes
> - * @bus: bus to create files under
> - * @mmap_type: I/O port or memory
> - *
> - * Adjust file name and size for sparse mappings.
> - */
> -void pci_adjust_legacy_attr(struct pci_bus *bus, enum pci_mmap_state mmap_type)
> -{
> - struct pci_controller *hose = bus->sysdata;
> -
> - if (!has_sparse(hose, mmap_type))
> - return;
> -
> - if (mmap_type == pci_mmap_mem) {
> - bus->legacy_mem->attr.name = "legacy_mem_sparse";
> - bus->legacy_mem->size <<= 5;
> - } else {
> - bus->legacy_io->attr.name = "legacy_io_sparse";
> - bus->legacy_io->size <<= 5;
> - }
> - return;
> -}
> -
> /* Legacy I/O bus read/write functions */
> int pci_legacy_read(struct pci_bus *bus, loff_t port, u32 *val, size_t size)
> {
> diff --git a/arch/powerpc/include/asm/pci.h b/arch/powerpc/include/asm/pci.h
> index 46a9c4491ed0..72f286e74786 100644
> --- a/arch/powerpc/include/asm/pci.h
> +++ b/arch/powerpc/include/asm/pci.h
> @@ -82,8 +82,6 @@ extern int pci_legacy_write(struct pci_bus *bus, loff_t port, u32 val,
> extern int pci_mmap_legacy_page_range(struct pci_bus *bus,
> struct vm_area_struct *vma,
> enum pci_mmap_state mmap_state);
> -extern void pci_adjust_legacy_attr(struct pci_bus *bus,
> - enum pci_mmap_state mmap_type);
> #define HAVE_PCI_LEGACY 1
>
> extern void pcibios_claim_one_bus(struct pci_bus *b);
> diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
> index fe079fb31dce..dc0bb0488317 100644
> --- a/drivers/pci/pci-sysfs.c
> +++ b/drivers/pci/pci-sysfs.c
> @@ -702,11 +702,6 @@ static const struct attribute_group pcibus_group = {
> .attrs = pcibus_attrs,
> };
>
> -const struct attribute_group *pcibus_groups[] = {
> - &pcibus_group,
> - NULL,
> -};
> -
> static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
> char *buf)
> {
> @@ -1025,91 +1020,136 @@ bool __weak pci_legacy_has_sparse(struct pci_bus *bus,
> return false;
> }
>
> -/**
> - * pci_adjust_legacy_attr - adjustment of legacy file attributes
> - * @b: bus to create files under
> - * @mmap_type: I/O port or memory
> - *
> - * Stub implementation. Can be overridden by arch if necessary.
> - */
> -void __weak pci_adjust_legacy_attr(struct pci_bus *b,
> - enum pci_mmap_state mmap_type)
> +static inline umode_t __pci_legacy_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + enum pci_mmap_state type,
> + bool sparse)
> {
> + struct pci_bus *bus = to_pci_bus(kobj_to_dev(kobj));
> +
> + if (pci_legacy_has_sparse(bus, type) != sparse)
> + return 0;
> +
> + return a->attr.mode;
> }
>
> -/**
> - * pci_create_legacy_files - create legacy I/O port and memory files
> - * @b: bus to create files under
> - *
> - * Some platforms allow access to legacy I/O port and ISA memory space on
> - * a per-bus basis. This routine creates the files and ties them into
> - * their associated read, write and mmap files from pci-sysfs.c
> - *
> - * On error unwind, but don't propagate the error to the caller
> - * as it is ok to set up the PCI bus without these files.
> - */
> -void pci_create_legacy_files(struct pci_bus *b)
> +static umode_t pci_legacy_io_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a, int n)
> {
> - int error;
> -
> - if (!sysfs_initialized)
> - return;
> -
> - b->legacy_io = kzalloc_objs(struct bin_attribute, 2, GFP_ATOMIC);
> - if (!b->legacy_io)
> - goto kzalloc_err;
> -
> - sysfs_bin_attr_init(b->legacy_io);
> - b->legacy_io->attr.name = "legacy_io";
> - b->legacy_io->size = 0xffff;
> - b->legacy_io->attr.mode = 0600;
> - b->legacy_io->read = pci_read_legacy_io;
> - b->legacy_io->write = pci_write_legacy_io;
> - /* See pci_create_attr() for motivation */
> - b->legacy_io->llseek = pci_llseek_resource;
> - b->legacy_io->mmap = pci_mmap_legacy_io;
> - b->legacy_io->f_mapping = iomem_get_mapping;
> - pci_adjust_legacy_attr(b, pci_mmap_io);
> - error = device_create_bin_file(&b->dev, b->legacy_io);
> - if (error)
> - goto legacy_io_err;
> -
> - /* Allocated above after the legacy_io struct */
> - b->legacy_mem = b->legacy_io + 1;
> - sysfs_bin_attr_init(b->legacy_mem);
> - b->legacy_mem->attr.name = "legacy_mem";
> - b->legacy_mem->size = 1024*1024;
> - b->legacy_mem->attr.mode = 0600;
> - b->legacy_mem->mmap = pci_mmap_legacy_mem;
> - /* See pci_create_attr() for motivation */
> - b->legacy_mem->llseek = pci_llseek_resource;
> - b->legacy_mem->f_mapping = iomem_get_mapping;
> - pci_adjust_legacy_attr(b, pci_mmap_mem);
> - error = device_create_bin_file(&b->dev, b->legacy_mem);
> - if (error)
> - goto legacy_mem_err;
> -
> - return;
> -
> -legacy_mem_err:
> - device_remove_bin_file(&b->dev, b->legacy_io);
> -legacy_io_err:
> - kfree(b->legacy_io);
> - b->legacy_io = NULL;
> -kzalloc_err:
> - dev_warn(&b->dev, "could not create legacy I/O port and ISA memory resources in sysfs\n");
> + return __pci_legacy_is_visible(kobj, a, pci_mmap_io, false);
> }
>
> -void pci_remove_legacy_files(struct pci_bus *b)
> +static umode_t pci_legacy_io_sparse_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> {
> - if (b->legacy_io) {
> - device_remove_bin_file(&b->dev, b->legacy_io);
> - device_remove_bin_file(&b->dev, b->legacy_mem);
> - kfree(b->legacy_io); /* both are allocated here */
> - }
> + return __pci_legacy_is_visible(kobj, a, pci_mmap_io, true);
> }
> +
> +static umode_t pci_legacy_mem_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a, int n)
> +{
> + return __pci_legacy_is_visible(kobj, a, pci_mmap_mem, false);
> +}
> +
> +static umode_t pci_legacy_mem_sparse_is_visible(struct kobject *kobj,
> + const struct bin_attribute *a,
> + int n)
> +{
> + return __pci_legacy_is_visible(kobj, a, pci_mmap_mem, true);
> +}
> +
> +static const struct bin_attribute pci_legacy_io_attr = {
> + .attr = { .name = "legacy_io", .mode = 0600 },
> + .size = 0xffff,
> + .read = pci_read_legacy_io,
> + .write = pci_write_legacy_io,
> + .mmap = pci_mmap_legacy_io,
> + .llseek = pci_llseek_resource,
> + .f_mapping = iomem_get_mapping,
> +};
> +
> +static const struct bin_attribute pci_legacy_io_sparse_attr = {
> + .attr = { .name = "legacy_io_sparse", .mode = 0600 },
> + .size = 0xffff << 5,
> + .read = pci_read_legacy_io,
> + .write = pci_write_legacy_io,
> + .mmap = pci_mmap_legacy_io,
> + .llseek = pci_llseek_resource,
> + .f_mapping = iomem_get_mapping,
> +};
> +
> +static const struct bin_attribute pci_legacy_mem_attr = {
> + .attr = { .name = "legacy_mem", .mode = 0600 },
> + .size = 0x100000,
> + .mmap = pci_mmap_legacy_mem,
> + .llseek = pci_llseek_resource,
> + .f_mapping = iomem_get_mapping,
> +};
> +
> +static const struct bin_attribute pci_legacy_mem_sparse_attr = {
> + .attr = { .name = "legacy_mem_sparse", .mode = 0600 },
> + .size = 0x100000 << 5,
I suggest naming these legacy literals with defines. At least the mem one
could also use SZ_1M:
#define PCI_LEGACY_MEM_SIZE SZ_1M
> + .mmap = pci_mmap_legacy_mem,
> + .llseek = pci_llseek_resource,
> + .f_mapping = iomem_get_mapping,
> +};
> +
> +static const struct bin_attribute *const pci_legacy_io_attrs[] = {
> + &pci_legacy_io_attr,
> + NULL,
> +};
> +
> +static const struct bin_attribute *const pci_legacy_io_sparse_attrs[] = {
> + &pci_legacy_io_sparse_attr,
> + NULL,
> +};
> +
> +static const struct bin_attribute *const pci_legacy_mem_attrs[] = {
> + &pci_legacy_mem_attr,
> + NULL,
> +};
> +
> +static const struct bin_attribute *const pci_legacy_mem_sparse_attrs[] = {
> + &pci_legacy_mem_sparse_attr,
> + NULL,
> +};
> +
> +static const struct attribute_group pci_legacy_io_group = {
> + .bin_attrs = pci_legacy_io_attrs,
> + .is_bin_visible = pci_legacy_io_is_visible,
> +};
> +
> +static const struct attribute_group pci_legacy_io_sparse_group = {
> + .bin_attrs = pci_legacy_io_sparse_attrs,
> + .is_bin_visible = pci_legacy_io_sparse_is_visible,
> +};
> +
> +static const struct attribute_group pci_legacy_mem_group = {
> + .bin_attrs = pci_legacy_mem_attrs,
> + .is_bin_visible = pci_legacy_mem_is_visible,
> +};
> +
> +static const struct attribute_group pci_legacy_mem_sparse_group = {
> + .bin_attrs = pci_legacy_mem_sparse_attrs,
> + .is_bin_visible = pci_legacy_mem_sparse_is_visible,
> +};
> +
> +void pci_create_legacy_files(struct pci_bus *b) { }
> +void pci_remove_legacy_files(struct pci_bus *b) { }
> #endif /* HAVE_PCI_LEGACY */
>
> +const struct attribute_group *pcibus_groups[] = {
> + &pcibus_group,
> +#ifdef HAVE_PCI_LEGACY
> + &pci_legacy_io_group,
> + &pci_legacy_io_sparse_group,
> + &pci_legacy_mem_group,
> + &pci_legacy_mem_sparse_group,
> +#endif
> + NULL,
> +};
> +
> #if defined(HAVE_PCI_MMAP) || defined(ARCH_GENERIC_PCI_MMAP_RESOURCE)
> /**
> * pci_mmap_resource - map a PCI resource into user memory space
>
--
i.
^ permalink raw reply [flat|nested] 38+ messages in thread* Re: [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions
2026-04-10 11:47 ` Ilpo Järvinen
@ 2026-04-10 12:04 ` Krzysztof Wilczyński
0 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 12:04 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Bjorn Helgaas, Bjorn Helgaas, Manivannan Sadhasivam,
Lorenzo Pieralisi, Magnus Lindholm, Matt Turner,
Richard Henderson, Christophe Leroy, Madhavan Srinivasan,
Michael Ellerman, Nicholas Piggin, Dexuan Cui,
Krzysztof Hałasa, Lukas Wunner, Oliver O'Halloran,
Saurabh Singh Sengar, Shuan He, Srivatsa Bhat, linux-pci,
linux-alpha, linuxppc-dev
Hello,
> > +static const struct bin_attribute pci_legacy_mem_sparse_attr = {
> > + .attr = { .name = "legacy_mem_sparse", .mode = 0600 },
> > + .size = 0x100000 << 5,
>
> I suggest naming these legacy literals with defines. At least the mem one
> could also use SZ_1M:
>
> #define PCI_LEGACY_MEM_SIZE SZ_1M
Sounds good. Will do.
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread
* [PATCH 20/20] PCI/sysfs: Remove pci_create_legacy_files() and pci_sysfs_init()
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (18 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 19/20] PCI/sysfs: Convert legacy I/O and memory attributes to static definitions Krzysztof Wilczyński
@ 2026-04-10 5:50 ` Krzysztof Wilczyński
2026-04-10 18:18 ` [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 5:50 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Currently, pci_create_legacy_files() and pci_remove_legacy_files() are
no-op stubs. With legacy attributes now handled by static groups
registered via pcibus_groups[], no call site needs them.
Remove both functions, their declarations, and the call sites in
pci_register_host_bridge(), pci_alloc_child_bus(), and pci_remove_bus().
Remove the pci_sysfs_init() late_initcall and sysfs_initialized. The
late_initcall originally existed to create all the dynamic PCI sysfs
files, but with both resource and legacy attributes now handled by
static groups, it is no longer needed.
Remove the legacy_io and legacy_mem fields from struct pci_bus which
were used to track the dynamically allocated legacy attributes.
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
---
drivers/pci/pci-sysfs.c | 21 ---------------------
drivers/pci/pci.h | 8 --------
drivers/pci/probe.c | 6 ------
drivers/pci/remove.c | 2 --
include/linux/pci.h | 2 --
5 files changed, 39 deletions(-)
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index dc0bb0488317..3275698a5d5d 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -37,10 +37,6 @@
#define ARCH_PCI_DEV_GROUPS
#endif
-#ifdef HAVE_PCI_LEGACY
-static int sysfs_initialized; /* = 0 */
-#endif
-
/* show configuration fields */
#define pci_config_attr(field, format_string) \
static ssize_t \
@@ -1135,8 +1131,6 @@ static const struct attribute_group pci_legacy_mem_sparse_group = {
.is_bin_visible = pci_legacy_mem_sparse_is_visible,
};
-void pci_create_legacy_files(struct pci_bus *b) { }
-void pci_remove_legacy_files(struct pci_bus *b) { }
#endif /* HAVE_PCI_LEGACY */
const struct attribute_group *pcibus_groups[] = {
@@ -1809,21 +1803,6 @@ static const struct attribute_group pci_dev_resource_resize_attr_group = {
};
#endif
-#ifdef HAVE_PCI_LEGACY
-static int __init pci_sysfs_init(void)
-{
- struct pci_bus *pbus = NULL;
-
- sysfs_initialized = 1;
-
- while ((pbus = pci_find_next_bus(pbus)))
- pci_create_legacy_files(pbus);
-
- return 0;
-}
-late_initcall(pci_sysfs_init);
-#endif
-
static struct attribute *pci_dev_dev_attrs[] = {
&dev_attr_boot_vga.attr,
&dev_attr_serial_number.attr,
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index f52caf7e4d13..63f249d4833a 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -356,14 +356,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; }
int pci_hp_add_bridge(struct pci_dev *dev);
bool pci_hp_spurious_link_change(struct pci_dev *pdev);
-#if defined(CONFIG_SYSFS) && defined(HAVE_PCI_LEGACY)
-void pci_create_legacy_files(struct pci_bus *bus);
-void pci_remove_legacy_files(struct pci_bus *bus);
-#else
-static inline void pci_create_legacy_files(struct pci_bus *bus) { }
-static inline void pci_remove_legacy_files(struct pci_bus *bus) { }
-#endif
-
/* Lock for read/write access to pci device and bus lists */
extern struct rw_semaphore pci_bus_sem;
extern struct mutex pci_slot_mutex;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index bccc7a4bdd79..94c52bf3a65c 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1068,9 +1068,6 @@ static int pci_register_host_bridge(struct pci_host_bridge *bridge)
dev_err(&bus->dev, "failed to add bus: %d\n", err);
}
- /* Create legacy_io and legacy_mem files for this bus */
- pci_create_legacy_files(bus);
-
if (parent)
dev_info(parent, "PCI host bridge to bus %s\n", name);
else
@@ -1276,9 +1273,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
dev_err(&child->dev, "failed to add bus: %d\n", ret);
}
- /* Create legacy_io and legacy_mem files for this bus */
- pci_create_legacy_files(child);
-
return child;
}
diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c
index 6e796dbc5b29..d8bffa21498a 100644
--- a/drivers/pci/remove.c
+++ b/drivers/pci/remove.c
@@ -65,8 +65,6 @@ void pci_remove_bus(struct pci_bus *bus)
list_del(&bus->node);
pci_bus_release_busn_res(bus);
up_write(&pci_bus_sem);
- pci_remove_legacy_files(bus);
-
if (bus->ops->remove_bus)
bus->ops->remove_bus(bus);
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 5a418fbe5a5f..c0828b96eb66 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -723,8 +723,6 @@ struct pci_bus {
pci_bus_flags_t bus_flags; /* Inherited by child buses */
struct device *bridge;
struct device dev;
- struct bin_attribute *legacy_io; /* Legacy I/O for this bus */
- struct bin_attribute *legacy_mem; /* Legacy mem */
unsigned int is_added:1;
unsigned int unsafe_warn:1; /* warned about RW1C config write */
unsigned int flit_mode:1; /* Link in Flit mode */
--
2.53.0
^ permalink raw reply related [flat|nested] 38+ messages in thread* Re: [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static
2026-04-10 5:50 [PATCH 00/20] PCI: Convert all dynamic sysfs attributes to static Krzysztof Wilczyński
` (19 preceding siblings ...)
2026-04-10 5:50 ` [PATCH 20/20] PCI/sysfs: Remove pci_create_legacy_files() and pci_sysfs_init() Krzysztof Wilczyński
@ 2026-04-10 18:18 ` Krzysztof Wilczyński
20 siblings, 0 replies; 38+ messages in thread
From: Krzysztof Wilczyński @ 2026-04-10 18:18 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: Bjorn Helgaas, Manivannan Sadhasivam, Lorenzo Pieralisi,
Magnus Lindholm, Matt Turner, Richard Henderson, Christophe Leroy,
Madhavan Srinivasan, Michael Ellerman, Nicholas Piggin,
Dexuan Cui, Krzysztof Hałasa, Lukas Wunner,
Oliver O'Halloran, Saurabh Singh Sengar, Shuan He,
Srivatsa Bhat, Ilpo Järvinen, linux-pci, linux-alpha,
linuxppc-dev
Hello,
> This series converts every dynamically allocated PCI sysfs attribute to
> a static const definition. After the full series, pci_sysfs_init() and
> sysfs_initialized are gone, and every sysfs file is created by the
> driver model at device_add() time.
A note on testing:
0-day bot (recent test runs; newer builds will arrive later):
- https://lore.kernel.org/linux-pci/202603170336.zSLrDvlj-lkp@intel.com/
- https://lore.kernel.org/linux-pci/202603122052.tMV5rzNq-lkp@intel.com/
- https://lore.kernel.org/linux-pci/202603081334.b91RGVS6-lkp@intel.com/
- https://lore.kernel.org/linux-pci/202603060207.pnGfKgGa-lkp@intel.com/
KernelCI (for the "for-kernelci" branch):
- https://dashboard.kernelci.org/tree/linux-pci/for-kernelci/
Sashiko's feedback:
- https://sashiko.dev/#/patchset/20260410055040.39233-1-kwilczynski%40kernel.org/
I sadly do not own any Alpha or PowerPC hardware, so when I was testing
these architectures while working on the series, it would be only under
QEMU.
Thank you!
Krzysztof
^ permalink raw reply [flat|nested] 38+ messages in thread