mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
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 commit2fc59fe2ec("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:
parent
337bdf8531
commit
1832dc1579
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user