]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
PCI/sysfs: Expose PCI device serial number
authorMatthew Wood <thepacketgeek@gmail.com>
Wed, 17 Sep 2025 12:58:14 +0000 (05:58 -0700)
committerBjorn Helgaas <bhelgaas@google.com>
Wed, 17 Sep 2025 15:53:36 +0000 (10:53 -0500)
Add a single sysfs read-only interface for reading PCI device serial
numbers from userspace in a programmatic way. This device attribute uses
the same hexadecimal 1-byte dashed formatting as lspci serial number
capability output. If a device doesn't support the serial number
capability, the serial_number sysfs attribute will not be visible.

Signed-off-by: Matthew Wood <thepacketgeek@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Reviewed-by: Mario Limonciello <superm1@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Reviewed-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Reviewed-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Link: https://patch.msgid.link/20250917125815.722952-2-thepacketgeek@gmail.com
Documentation/ABI/testing/sysfs-bus-pci
drivers/pci/pci-sysfs.c

index 69f952fffec72f1515d144e0cd33cb43267ead49..92debe879ffbf54b68c73db6c4a852851dfab92f 100644 (file)
@@ -612,3 +612,12 @@ Description:
 
                  # ls doe_features
                  0001:01        0001:02        doe_discovery
+
+What:          /sys/bus/pci/devices/.../serial_number
+Date:          December 2025
+Contact:       Matthew Wood <thepacketgeek@gmail.com>
+Description:
+               This is visible only for PCI devices that support the serial
+               number extended capability. The file is read only and due to
+               the possible sensitivity of accessible serial numbers, admin
+               only.
index 5eea14c1f7f5f704d43eed7e3a6d6136a4920679..95d9c01453596ea18114fafc9febf1e8bfd91edb 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/aperture.h>
+#include <linux/unaligned.h>
 #include "pci.h"
 
 #ifndef ARCH_PCI_DEV_GROUPS
@@ -694,6 +695,22 @@ static ssize_t boot_vga_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR_RO(boot_vga);
 
+static ssize_t serial_number_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct pci_dev *pci_dev = to_pci_dev(dev);
+       u64 dsn;
+       u8 bytes[8];
+
+       dsn = pci_get_dsn(pci_dev);
+       if (!dsn)
+               return -EIO;
+
+       put_unaligned_be64(dsn, bytes);
+       return sysfs_emit(buf, "%8phD\n", bytes);
+}
+static DEVICE_ATTR_ADMIN_RO(serial_number);
+
 static ssize_t pci_read_config(struct file *filp, struct kobject *kobj,
                               const struct bin_attribute *bin_attr, char *buf,
                               loff_t off, size_t count)
@@ -1698,6 +1715,7 @@ late_initcall(pci_sysfs_init);
 
 static struct attribute *pci_dev_dev_attrs[] = {
        &dev_attr_boot_vga.attr,
+       &dev_attr_serial_number.attr,
        NULL,
 };
 
@@ -1710,6 +1728,9 @@ static umode_t pci_dev_attrs_are_visible(struct kobject *kobj,
        if (a == &dev_attr_boot_vga.attr && pci_is_vga(pdev))
                return a->mode;
 
+       if (a == &dev_attr_serial_number.attr && pci_get_dsn(pdev))
+               return a->mode;
+
        return 0;
 }