Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
New issues:
- [High] Unconditionally enabling per_func_slot on S390 breaks standard PCIe hotplug (e.g., pciehp), PCI_SLOT_ALL_DEVICES assignment, and physical slot matching.
Pre-existing issues:
- [High] Lockless access to `dev->slot` allows a Use-After-Free if a hotplug slot is concurrently destroyed.
--
--- Patch [2]: [PATCH v23 2/5] PCI: Allow per function PCI slots to fix slot reset on s390 ---
commit 5800507f8f4f03803f3a4540f211363e22c66b48
Author: Farhan Ali <[email protected]>
PCI: Allow per function PCI slots to fix slot reset on s390
This patch introduces a per_func_slot flag for struct pci_slot to allow
per-function PCI slots on s390. It modifies slot matching logic and changes
the slot number field to a u16 to accommodate special values.
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 77b17b13ee615..350bae907ebf8 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -4897,8 +4897,9 @@ static int pci_reset_hotplug_slot(struct hotplug_slot *hotplug, bool probe)
>
> static int pci_dev_reset_slot_function(struct pci_dev *dev, bool probe)
> {
> - if (dev->multifunction || dev->subordinate || !dev->slot ||
> - dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET)
> + if (dev->subordinate || !dev->slot ||
> + dev->dev_flags & PCI_DEV_FLAGS_NO_BUS_RESET ||
> + (dev->multifunction && !dev->slot->per_func_slot))
[Severity: High]
This is a pre-existing issue, but does reading dev->slot here and accessing
dev->slot->per_func_slot allow a use-after-free?
__pci_reset_function_locked() acquires device_lock(&dev->dev) but calls
pci_dev_reset_slot_function(), which reads dev->slot locklessly.
Concurrently, if a hotplug driver is removed, pci_destroy_slot() drops
the kobject refcount and triggers pci_slot_release().
pci_slot_release() frees the slot and sets dev->slot = NULL:
pci_slot_release() {
...
list_for_each_entry(dev, &slot->bus->devices, bus_list)
if (pci_dev_matches_slot(dev, slot))
dev->slot = NULL;
...
kfree(slot);
}
If the reset thread is preempted after checking dev->slot but before
dereferencing dev->slot->per_func_slot, could it dereference the freed
pointer?
> return -ENOTTY;
>
> return pci_reset_hotplug_slot(dev->slot->hotplug, probe);
> diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
> index 42ff66461f74a..897223f01f6ac 100644
> --- a/drivers/pci/slot.c
> +++ b/drivers/pci/slot.c
> @@ -72,6 +72,23 @@ static ssize_t cur_speed_read_file(struct pci_slot *slot, char *buf)
> return bus_speed_read(slot->bus->cur_bus_speed, buf);
> }
>
> +static bool pci_dev_matches_slot(struct pci_dev *dev, struct pci_slot *slot)
> +{
> + if (slot->per_func_slot)
> + return dev->devfn == slot->number;
> +
> + return slot->number == PCI_SLOT_ALL_DEVICES ||
> + PCI_SLOT(dev->devfn) == slot->number;
> +}
> +
> +static bool pci_slot_enabled_per_func(void)
> +{
> + if (IS_ENABLED(CONFIG_S390))
> + return true;
> +
> + return false;
> +}
> +
[ ... ]
> @@ -299,6 +314,9 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr,
> slot->bus = pci_bus_get(parent);
> slot->number = slot_nr;
>
> + if (pci_slot_enabled_per_func())
> + slot->per_func_slot = 1;
> +
[Severity: High]
Does unconditionally setting per_func_slot for all slots on S390 break
standard PCIe hotplug topologies?
When generic PCIe hotplug drivers like pciehp create a bus-wide slot, they
pass PCI_SLOT_ALL_DEVICES (now 0xfeff). Because pci_slot_enabled_per_func()
globally forces per_func_slot = 1 on S390, pci_dev_matches_slot() will
evaluate:
dev->devfn == 0xfeff
Since devfn is an 8-bit value (0-255), this will never match, leaving
dev->slot unassigned for all devices on those buses.
Similarly, if a generic driver specifies a physical slot number (like 2),
it will evaluate dev->devfn == 2, which incorrectly matches Function 2 of
Device 0 rather than matching all functions of Device 2.
Will this cause generic hotplug slots to fail matching on S390, breaking
sysfs linkages and PCI resets?
> slot->kobj.kset = pci_slots_kset;
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/[email protected]?part=2
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.