PCI/sysfs: Handle a malformed _DSM result in acpi_attr_is_visible()

Currently, the "label" and "acpi_index" attributes are created whenever the
_DSM function 0 bitmap advertises the Device Name function, without
evaluating that function.  The documented ABI states that each attribute is
created only if the firmware has given a name or an instance number to the
PCI device.

The bitmap says nothing about the object the function returns.  Firmware
that advertises the function but returns an object that cannot be parsed
therefore produces attributes that exist and fail every read, as in the
report below.

Evaluate the Device Name _DSM when deciding attribute visibility and create
each attribute only when the element it exports has a type the read path
accepts, mirroring the checks performed at read time.  The SMBIOS attribute
group already follows this pattern by performing the DMI lookup in its
is_visible() callback.  The read side checks remain in place since the two
evaluations happen at different times.

This restores the behaviour from before commit 2fc59fe2ec ("PCI /
pci-label: treat PCI label with index 0 as valid label"), which switched
visibility from evaluating the function to checking only the function 0
bitmap.  The check is now made for each attribute, not once for both.

Fixes: 2fc59fe2ec ("PCI / pci-label: treat PCI label with index 0 as valid label")
Closes: https://github.com/pciutils/pciutils/issues/175
Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Link: https://patch.msgid.link/20260814070522.2327975-4-kwilczynski@kernel.org
This commit is contained in:
Krzysztof Wilczyński 2026-08-14 07:05:21 +00:00 committed by Bjorn Helgaas
parent 337bdf8531
commit 1832dc1579
2 changed files with 42 additions and 5 deletions

View File

@ -244,10 +244,16 @@ Contact: Narendra K <narendra_k@dell.com>, linux-bugs@dell.com
Description:
Reading this attribute will provide the firmware
given name (SMBIOS type 41 string or ACPI _DSM string) of
the PCI device. The attribute will be created only
if the firmware has given a name to the PCI device.
ACPI _DSM string name will be given priority if the
system firmware provides SMBIOS type 41 string also.
the PCI device. The attribute will be created only if the
firmware naming mechanism is implemented for the device:
a SMBIOS type 41 record with a non-empty reference
designation, or a Device Name _DSM that returns the name
as a string or a buffer. The value read is empty when the
firmware implements the _DSM but gives the device no name,
which per PCI Firmware r3.3, sec 4.6.7 the firmware reports
as a NULL string. ACPI _DSM string name will be given
priority if the system firmware provides SMBIOS type 41
string also.
Users:
Userspace applications interested in knowing the
firmware assigned name of the PCI device.

View File

@ -230,11 +230,42 @@ static umode_t acpi_attr_is_visible(struct kobject *kobj, struct attribute *a,
int n)
{
struct device *dev = kobj_to_dev(kobj);
union acpi_object *obj, *tmp;
umode_t mode = 0;
if (!device_has_acpi_name(dev))
return 0;
return a->mode;
/*
* The bitmap from _DSM function 0 only advertises function 7,
* and whether the returned object can be parsed is a separate
* question. Evaluate it and expose each attribute only if the
* element it exports has one of the types the read path
* accepts, mirroring the checks in dsm_get_label().
*/
obj = acpi_evaluate_dsm(ACPI_HANDLE(dev), &pci_acpi_dsm_guid, 0x2,
DSM_PCI_DEVICE_NAME, NULL);
if (!obj)
return 0;
if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != 2)
goto out;
tmp = obj->package.elements;
if (tmp[0].type != ACPI_TYPE_INTEGER)
goto out;
if (a == &dev_attr_acpi_index.attr)
mode = a->mode;
else if (a == &dev_attr_label.attr &&
(tmp[1].type == ACPI_TYPE_STRING ||
tmp[1].type == ACPI_TYPE_BUFFER))
mode = a->mode;
out:
ACPI_FREE(obj);
return mode;
}
const struct attribute_group pci_dev_acpi_attr_group = {