* [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 [not found] <20260630164807.643-1-alifm@linux.ibm.com> @ 2026-06-30 16:48 ` Farhan Ali 2026-07-15 23:34 ` Bjorn Helgaas 2026-06-30 16:48 ` [PATCH v21 4/4] PCI/MSI: Enable memory decoding before restoring MSI-X messages Farhan Ali 1 sibling, 1 reply; 7+ messages in thread From: Farhan Ali @ 2026-06-30 16:48 UTC (permalink / raw) To: linux-s390, linux-kernel, linux-pci Cc: helgaas, alex, alifm, schnelle, mjrosato, stable On s390 systems, which use a machine level hypervisor, PCI devices are always accessed through a form of PCI pass-through which fundamentally operates on a per PCI function granularity. This is also reflected in the s390 PCI hotplug driver which creates hotplug slots for individual PCI functions. Its reset_slot() function, which is a wrapper for zpci_hot_reset_device(), thus also resets individual functions. Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object to multifunction devices. This approach worked fine on s390 systems that only exposed virtual functions as individual PCI domains to the operating system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions") s390 supports exposing the topology of multifunction PCI devices by grouping them in a shared PCI domain. This creates a problem when resetting a function through the hotplug driver's slot_reset() interface. When attempting to reset a function through the hotplug driver, the shared slot assignment causes the wrong function to be reset instead of the intended one. It also leaks memory as we do create a pci_slot object for the function, but don't correctly free it in pci_slot_release(). Add a flag for struct pci_slot to allow per function PCI slots for functions managed through a hypervisor, which exposes individual PCI functions while retaining the topology. Since we can use all 8 bits for slot 'number' (for ARI devices), change slot 'number' u16 to account for special values -1 and PCI_SLOT_ALL_DEVICES. Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions") Cc: stable@vger.kernel.org Suggested-by: Niklas Schnelle <schnelle@linux.ibm.com> Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Farhan Ali <alifm@linux.ibm.com> --- drivers/pci/hotplug/rpaphp_slot.c | 2 +- drivers/pci/pci.c | 5 +++-- drivers/pci/slot.c | 33 +++++++++++++++++++++++-------- include/linux/pci.h | 8 ++++++-- 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 67362e5b9971..92eabf5f61b9 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -84,7 +84,7 @@ int rpaphp_register_slot(struct slot *slot) struct hotplug_slot *php_slot = &slot->hotplug_slot; u32 my_index; int retval; - int slotno = -1; + int slotno = PCI_SLOT_PLACEHOLDER; dbg("%s registering slot:path[%pOF] index[%x], name[%s] pdomain[%x] type[%d]\n", __func__, slot->dn, slot->index, slot->name, diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 77b17b13ee61..350bae907ebf 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)) return -ENOTTY; return pci_reset_hotplug_slot(dev->slot->hotplug, probe); diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c index 6d5cd37bfb1e..894d6213ed30 100644 --- a/drivers/pci/slot.c +++ b/drivers/pci/slot.c @@ -37,7 +37,7 @@ static const struct sysfs_ops pci_slot_sysfs_ops = { static ssize_t address_read_file(struct pci_slot *slot, char *buf) { - if (slot->number == 0xff) + if (slot->number == (u16)PCI_SLOT_PLACEHOLDER) return sysfs_emit(buf, "%04x:%02x\n", pci_domain_nr(slot->bus), slot->bus->number); @@ -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; +} + static void pci_slot_release(struct kobject *kobj) { struct pci_dev *dev; @@ -82,8 +99,7 @@ static void pci_slot_release(struct kobject *kobj) down_read(&pci_bus_sem); list_for_each_entry(dev, &slot->bus->devices, bus_list) - if (slot->number == PCI_SLOT_ALL_DEVICES || - PCI_SLOT(dev->devfn) == slot->number) + if (pci_dev_matches_slot(dev, slot)) dev->slot = NULL; up_read(&pci_bus_sem); @@ -187,8 +203,7 @@ void pci_dev_assign_slot(struct pci_dev *dev) mutex_lock(&pci_slot_mutex); list_for_each_entry(slot, &dev->bus->slots, list) - if (slot->number == PCI_SLOT_ALL_DEVICES || - PCI_SLOT(dev->devfn) == slot->number) + if (pci_dev_matches_slot(dev, slot)) dev->slot = slot; mutex_unlock(&pci_slot_mutex); } @@ -267,7 +282,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, mutex_lock(&pci_slot_mutex); - if (slot_nr == -1) + if (slot_nr == PCI_SLOT_PLACEHOLDER) goto placeholder; /* @@ -298,6 +313,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; + slot->kobj.kset = pci_slots_kset; slot_name = make_slot_name(name); @@ -318,8 +336,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, down_read(&pci_bus_sem); list_for_each_entry(dev, &parent->devices, bus_list) - if (slot_nr == PCI_SLOT_ALL_DEVICES || - PCI_SLOT(dev->devfn) == slot_nr) + if (pci_dev_matches_slot(dev, slot)) dev->slot = slot; up_read(&pci_bus_sem); diff --git a/include/linux/pci.h b/include/linux/pci.h index ebb5b9d76360..b6e20616e17f 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -79,14 +79,18 @@ * and, if ARI Forwarding is enabled, functions may appear to be on multiple * devices. */ -#define PCI_SLOT_ALL_DEVICES 0xfe +#define PCI_SLOT_ALL_DEVICES 0xfeff + +/* Used to identify a slot as a placeholder */ +#define PCI_SLOT_PLACEHOLDER -1 /* pci_slot represents a physical slot */ struct pci_slot { struct pci_bus *bus; /* Bus this slot is on */ struct list_head list; /* Node in list of slots */ struct hotplug_slot *hotplug; /* Hotplug info (move here) */ - unsigned char number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ + u16 number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ + unsigned int per_func_slot:1; /* Allow per function slot */ struct kobject kobj; }; -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 2026-06-30 16:48 ` [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 Farhan Ali @ 2026-07-15 23:34 ` Bjorn Helgaas 2026-07-16 18:15 ` Farhan Ali 2026-07-16 18:19 ` Farhan Ali 0 siblings, 2 replies; 7+ messages in thread From: Bjorn Helgaas @ 2026-07-15 23:34 UTC (permalink / raw) To: Farhan Ali Cc: linux-s390, linux-kernel, linux-pci, alex, schnelle, mjrosato, stable On Tue, Jun 30, 2026 at 09:48:04AM -0700, Farhan Ali wrote: > On s390 systems, which use a machine level hypervisor, PCI devices are > always accessed through a form of PCI pass-through which fundamentally > operates on a per PCI function granularity. This is also reflected in the > s390 PCI hotplug driver which creates hotplug slots for individual PCI > functions. Its reset_slot() function, which is a wrapper for > zpci_hot_reset_device(), thus also resets individual functions. > > Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object > to multifunction devices. PCI_SLOT() doesn't assign pci_slot objects; I guess they're assigned by some code that *uses* PCI_SLOT(). Since this says "currently," I assume you're changing that code, so we should mention where it is to help readers out. I see some Sashiko comments; those also need to be addressed or explained away. > This approach worked fine on s390 systems that > only exposed virtual functions as individual PCI domains to the operating > system. Since commit 44510d6fa0c0 ("s390/pci: Handling multifunctions") > s390 supports exposing the topology of multifunction PCI devices by > grouping them in a shared PCI domain. This creates a problem when resetting > a function through the hotplug driver's slot_reset() interface. > > When attempting to reset a function through the hotplug driver, the shared > slot assignment causes the wrong function to be reset instead of the > intended one. It also leaks memory as we do create a pci_slot object for > the function, but don't correctly free it in pci_slot_release(). > > Add a flag for struct pci_slot to allow per function PCI slots for > functions managed through a hypervisor, which exposes individual PCI > functions while retaining the topology. Since we can use all 8 bits > for slot 'number' (for ARI devices), change slot 'number' u16 to > account for special values -1 and PCI_SLOT_ALL_DEVICES. > > Fixes: 44510d6fa0c0 ("s390/pci: Handling multifunctions") > Cc: stable@vger.kernel.org > Suggested-by: Niklas Schnelle <schnelle@linux.ibm.com> > Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com> > Signed-off-by: Farhan Ali <alifm@linux.ibm.com> > --- > drivers/pci/hotplug/rpaphp_slot.c | 2 +- > drivers/pci/pci.c | 5 +++-- > drivers/pci/slot.c | 33 +++++++++++++++++++++++-------- > include/linux/pci.h | 8 ++++++-- > 4 files changed, 35 insertions(+), 13 deletions(-) > > diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c > index 67362e5b9971..92eabf5f61b9 100644 > --- a/drivers/pci/hotplug/rpaphp_slot.c > +++ b/drivers/pci/hotplug/rpaphp_slot.c > @@ -84,7 +84,7 @@ int rpaphp_register_slot(struct slot *slot) > struct hotplug_slot *php_slot = &slot->hotplug_slot; > u32 my_index; > int retval; > - int slotno = -1; > + int slotno = PCI_SLOT_PLACEHOLDER; > > dbg("%s registering slot:path[%pOF] index[%x], name[%s] pdomain[%x] type[%d]\n", > __func__, slot->dn, slot->index, slot->name, > diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c > index 77b17b13ee61..350bae907ebf 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)) > return -ENOTTY; > > return pci_reset_hotplug_slot(dev->slot->hotplug, probe); > diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c > index 6d5cd37bfb1e..894d6213ed30 100644 > --- a/drivers/pci/slot.c > +++ b/drivers/pci/slot.c > @@ -37,7 +37,7 @@ static const struct sysfs_ops pci_slot_sysfs_ops = { > > static ssize_t address_read_file(struct pci_slot *slot, char *buf) > { > - if (slot->number == 0xff) > + if (slot->number == (u16)PCI_SLOT_PLACEHOLDER) > return sysfs_emit(buf, "%04x:%02x\n", > pci_domain_nr(slot->bus), > slot->bus->number); > @@ -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; > +} > + > static void pci_slot_release(struct kobject *kobj) > { > struct pci_dev *dev; > @@ -82,8 +99,7 @@ static void pci_slot_release(struct kobject *kobj) > > down_read(&pci_bus_sem); > list_for_each_entry(dev, &slot->bus->devices, bus_list) > - if (slot->number == PCI_SLOT_ALL_DEVICES || > - PCI_SLOT(dev->devfn) == slot->number) > + if (pci_dev_matches_slot(dev, slot)) > dev->slot = NULL; > up_read(&pci_bus_sem); > > @@ -187,8 +203,7 @@ void pci_dev_assign_slot(struct pci_dev *dev) > > mutex_lock(&pci_slot_mutex); > list_for_each_entry(slot, &dev->bus->slots, list) > - if (slot->number == PCI_SLOT_ALL_DEVICES || > - PCI_SLOT(dev->devfn) == slot->number) > + if (pci_dev_matches_slot(dev, slot)) > dev->slot = slot; > mutex_unlock(&pci_slot_mutex); > } > @@ -267,7 +282,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, > > mutex_lock(&pci_slot_mutex); > > - if (slot_nr == -1) > + if (slot_nr == PCI_SLOT_PLACEHOLDER) > goto placeholder; > > /* > @@ -298,6 +313,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; > + > slot->kobj.kset = pci_slots_kset; > > slot_name = make_slot_name(name); > @@ -318,8 +336,7 @@ struct pci_slot *pci_create_slot(struct pci_bus *parent, int slot_nr, > > down_read(&pci_bus_sem); > list_for_each_entry(dev, &parent->devices, bus_list) > - if (slot_nr == PCI_SLOT_ALL_DEVICES || > - PCI_SLOT(dev->devfn) == slot_nr) > + if (pci_dev_matches_slot(dev, slot)) > dev->slot = slot; > up_read(&pci_bus_sem); > > diff --git a/include/linux/pci.h b/include/linux/pci.h > index ebb5b9d76360..b6e20616e17f 100644 > --- a/include/linux/pci.h > +++ b/include/linux/pci.h > @@ -79,14 +79,18 @@ > * and, if ARI Forwarding is enabled, functions may appear to be on multiple > * devices. > */ > -#define PCI_SLOT_ALL_DEVICES 0xfe > +#define PCI_SLOT_ALL_DEVICES 0xfeff > + > +/* Used to identify a slot as a placeholder */ > +#define PCI_SLOT_PLACEHOLDER -1 > > /* pci_slot represents a physical slot */ > struct pci_slot { > struct pci_bus *bus; /* Bus this slot is on */ > struct list_head list; /* Node in list of slots */ > struct hotplug_slot *hotplug; /* Hotplug info (move here) */ > - unsigned char number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ > + u16 number; /* Device nr, or PCI_SLOT_ALL_DEVICES */ > + unsigned int per_func_slot:1; /* Allow per function slot */ > struct kobject kobj; > }; > > -- > 2.43.0 > ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 2026-07-15 23:34 ` Bjorn Helgaas @ 2026-07-16 18:15 ` Farhan Ali 2026-07-22 22:32 ` Bjorn Helgaas 2026-07-16 18:19 ` Farhan Ali 1 sibling, 1 reply; 7+ messages in thread From: Farhan Ali @ 2026-07-16 18:15 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-s390, linux-kernel, linux-pci, alex, schnelle, mjrosato, stable On 7/15/2026 4:34 PM, Bjorn Helgaas wrote: >> On s390 systems, which use a machine level hypervisor, PCI devices are >> always accessed through a form of PCI pass-through which fundamentally >> operates on a per PCI function granularity. This is also reflected in the >> s390 PCI hotplug driver which creates hotplug slots for individual PCI >> functions. Its reset_slot() function, which is a wrapper for >> zpci_hot_reset_device(), thus also resets individual functions. >> >> Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object >> to multifunction devices. > PCI_SLOT() doesn't assign pci_slot objects; I guess they're assigned > by some code that*uses* PCI_SLOT(). Since this says "currently," I > assume you're changing that code, so we should mention where it is to > help readers out. Thanks for your response! I can re-word the commit message, how about something like this: Currently, the pci_create_slot() assigns the same pci_slot object to multifunction devices. > > I see some Sashiko comments; those also need to be addressed or > explained away. Regarding Sashiko's comments for this patch, it mentions 2 issues: New issues: - [High] Unconditional enablement of `per_func_slot` on S390 breaks standard PCI hotplug (e.g., pciehp, shpchp) slot matching and resets. I believe this is not applicable as on s390 we don't support any other PCI hotplug drivers given the unique nature of zPCI architecture. Pre-existing issues: - [High] Lockless access to `dev->slot` in `pci_dev_reset_slot_function` can lead to Use-After-Free if a hotplug driver is concurrently unbound. Sashiko identified this as a pre-existing issue, so I don't think should be addressed with this patch. Thanks Farhan ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 2026-07-16 18:15 ` Farhan Ali @ 2026-07-22 22:32 ` Bjorn Helgaas 2026-07-23 1:21 ` Farhan Ali 0 siblings, 1 reply; 7+ messages in thread From: Bjorn Helgaas @ 2026-07-22 22:32 UTC (permalink / raw) To: Farhan Ali Cc: linux-s390, linux-kernel, linux-pci, alex, schnelle, mjrosato, stable On Thu, Jul 16, 2026 at 11:15:33AM -0700, Farhan Ali wrote: > > On 7/15/2026 4:34 PM, Bjorn Helgaas wrote: > > > On s390 systems, which use a machine level hypervisor, PCI devices are > > > always accessed through a form of PCI pass-through which fundamentally > > > operates on a per PCI function granularity. This is also reflected in the > > > s390 PCI hotplug driver which creates hotplug slots for individual PCI > > > functions. Its reset_slot() function, which is a wrapper for > > > zpci_hot_reset_device(), thus also resets individual functions. > > > > > > Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object > > > to multifunction devices. > > PCI_SLOT() doesn't assign pci_slot objects; I guess they're assigned > > by some code that*uses* PCI_SLOT(). Since this says "currently," I > > assume you're changing that code, so we should mention where it is to > > help readers out. > > Thanks for your response! I can re-word the commit message, how about > something like this: > > Currently, the pci_create_slot() assigns the same pci_slot object to > multifunction devices. > > > I see some Sashiko comments; those also need to be addressed or > > explained away. > > Regarding Sashiko's comments for this patch, it mentions 2 issues: > > New issues: - [High] Unconditional enablement of `per_func_slot` on S390 > breaks standard PCI hotplug (e.g., pciehp, shpchp) slot matching and resets. > > I believe this is not applicable as on s390 we don't support any other PCI > hotplug drivers given the unique nature of zPCI architecture. Makes sense. > Pre-existing issues: > - [High] Lockless access to `dev->slot` in `pci_dev_reset_slot_function` can > lead to Use-After-Free if a hotplug driver is concurrently unbound. > > Sashiko identified this as a pre-existing issue, so I don't think should be > addressed with this patch. Right, we don't need to fix pre-existing issues in this series, but I meant there were Sashiko comments on other patches in this series that look like they *should* be addressed, e.g., [PATCH v21 2/4] PCI: Avoid saving config space state if inaccessible - [High] pci_dev_save_and_disable() skips disabling the device if config space is momentarily inaccessible, potentially leaving DMA and interrupts enabled. - [Low] String literal passed to a non-const `char *` pointer in `pci_dev_config_accessible()`. https://lore.kernel.org/all/20260630170754.093021F00A3A@smtp.kernel.org [PATCH v21 3/4] PCI: Fail FLR when config space is inaccessible - [High] Un-ratelimited pci_warn() in pci_dev_config_accessible() allows an attacker to flood the host kernel log. - [High] Early bailout in pcie_flr() when config space is inaccessible skips the Function Level Reset and the subsequent wait, allowing device assignment to continue without reset, leaking state. https://lore.kernel.org/all/20260630171310.F25D41F000E9@smtp.kernel.org [PATCH v21 4/4] PCI/MSI: Enable memory decoding before restoring MSI-X messages - [Medium] Blindly restoring a stale PCI_COMMAND value introduces a TOCTOU race window that can erase concurrent modifications to the register. https://lore.kernel.org/all/20260630171255.20BD91F000E9@smtp.kernel.org Annoyingly, on v22, Sashiko complained about *different* things and didn't complain about some of these even though the v22 patches are identical to v21. Sigh. ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 2026-07-22 22:32 ` Bjorn Helgaas @ 2026-07-23 1:21 ` Farhan Ali 0 siblings, 0 replies; 7+ messages in thread From: Farhan Ali @ 2026-07-23 1:21 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-s390, linux-kernel, linux-pci, alex, schnelle, mjrosato, stable On 7/22/2026 3:32 PM, Bjorn Helgaas wrote: > On Thu, Jul 16, 2026 at 11:15:33AM -0700, Farhan Ali wrote: >> On 7/15/2026 4:34 PM, Bjorn Helgaas wrote: >>>> On s390 systems, which use a machine level hypervisor, PCI devices are >>>> always accessed through a form of PCI pass-through which fundamentally >>>> operates on a per PCI function granularity. This is also reflected in the >>>> s390 PCI hotplug driver which creates hotplug slots for individual PCI >>>> functions. Its reset_slot() function, which is a wrapper for >>>> zpci_hot_reset_device(), thus also resets individual functions. >>>> >>>> Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object >>>> to multifunction devices. >>> PCI_SLOT() doesn't assign pci_slot objects; I guess they're assigned >>> by some code that*uses* PCI_SLOT(). Since this says "currently," I >>> assume you're changing that code, so we should mention where it is to >>> help readers out. >> Thanks for your response! I can re-word the commit message, how about >> something like this: >> >> Currently, the pci_create_slot() assigns the same pci_slot object to >> multifunction devices. >> >>> I see some Sashiko comments; those also need to be addressed or >>> explained away. >> Regarding Sashiko's comments for this patch, it mentions 2 issues: >> >> New issues: - [High] Unconditional enablement of `per_func_slot` on S390 >> breaks standard PCI hotplug (e.g., pciehp, shpchp) slot matching and resets. >> >> I believe this is not applicable as on s390 we don't support any other PCI >> hotplug drivers given the unique nature of zPCI architecture. > Makes sense. > >> Pre-existing issues: >> - [High] Lockless access to `dev->slot` in `pci_dev_reset_slot_function` can >> lead to Use-After-Free if a hotplug driver is concurrently unbound. >> >> Sashiko identified this as a pre-existing issue, so I don't think should be >> addressed with this patch. > Right, we don't need to fix pre-existing issues in this series, but I > meant there were Sashiko comments on other patches in this series that > look like they *should* be addressed, e.g., > > [PATCH v21 2/4] PCI: Avoid saving config space state if inaccessible > > - [High] pci_dev_save_and_disable() skips disabling the device if > config space is momentarily inaccessible, potentially leaving > DMA and interrupts enabled. I am not sure if this is an issue? If we want to check if the device is momentarily inaccessible, then we would need to poll and do something similar to pci_dev_wait(). Please correct me if I am wrong. FWIW this doesn't even show up as an error anymore in v22 even though its the same code. https://lore.kernel.org/all/20260720194254.E6B811F000E9@smtp.kernel.org/ > - [Low] String literal passed to a non-const `char *` pointer in > `pci_dev_config_accessible()`. I wasn't sure if this is something that is strictly enforced. But I can fix this if we want to enforce it. > https://lore.kernel.org/all/20260630170754.093021F00A3A@smtp.kernel.org > > [PATCH v21 3/4] PCI: Fail FLR when config space is inaccessible > > - [High] Un-ratelimited pci_warn() in pci_dev_config_accessible() > allows an attacker to flood the host kernel log. Since we bailout early with -ENOTTY, we should at least try the other reset methods such as bus reset. So AFAIU we shouldn't be spamming the logs. > - [High] Early bailout in pcie_flr() when config space is > inaccessible skips the Function Level Reset and the subsequent > wait, allowing device assignment to continue without reset, > leaking state. > > https://lore.kernel.org/all/20260630171310.F25D41F000E9@smtp.kernel.org The idea with early bailout was to make sure we can try the other reset methods as currently if FLR is inaccessible/fails we don't try any other reset methods. So we should be trying the other reset methods and it shouldn't leak state. I think we probably are leaking the state today, as we don't try any other reset methods to reset the device. > > [PATCH v21 4/4] PCI/MSI: Enable memory decoding before restoring MSI-X messages > > - [Medium] Blindly restoring a stale PCI_COMMAND value introduces > a TOCTOU race window that can erase concurrent modifications to > the register. > > https://lore.kernel.org/all/20260630171255.20BD91F000E9@smtp.kernel.org I am not sure if this something we should fix? > > Annoyingly, on v22, Sashiko complained about *different* things and > didn't complain about some of these even though the v22 patches are > identical to v21. Sigh. Yeah, for this series Sashiko has been a little inconsistent in the issues it identifies :) Thanks Farhan ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 2026-07-15 23:34 ` Bjorn Helgaas 2026-07-16 18:15 ` Farhan Ali @ 2026-07-16 18:19 ` Farhan Ali 1 sibling, 0 replies; 7+ messages in thread From: Farhan Ali @ 2026-07-16 18:19 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-s390, linux-kernel, linux-pci, alex, schnelle, mjrosato, stable On 7/15/2026 4:34 PM, Bjorn Helgaas wrote: >> On s390 systems, which use a machine level hypervisor, PCI devices are >> always accessed through a form of PCI pass-through which fundamentally >> operates on a per PCI function granularity. This is also reflected in the >> s390 PCI hotplug driver which creates hotplug slots for individual PCI >> functions. Its reset_slot() function, which is a wrapper for >> zpci_hot_reset_device(), thus also resets individual functions. >> >> Currently, the kernel's PCI_SLOT() macro assigns the same pci_slot object >> to multifunction devices. > PCI_SLOT() doesn't assign pci_slot objects; I guess they're assigned > by some code that*uses* PCI_SLOT(). Since this says "currently," I > assume you're changing that code, so we should mention where it is to > help readers out. Thanks for your response! I can re-word the commit message, how about something like this: Currently, the pci_create_slot() assigns the same pci_slot object to multifunction devices. > > I see some Sashiko comments; those also need to be addressed or > explained away. Regarding Sashiko's comments for this patch, it mentions 2 issues: New issues: - [High] Unconditional enablement of `per_func_slot` on S390 breaks standard PCI hotplug (e.g., pciehp, shpchp) slot matching and resets. I believe this is not applicable as on s390 we don't support any other PCI hotplug drivers given the unique nature of zPCI architecture. Pre-existing issues: - [High] Lockless access to `dev->slot` in `pci_dev_reset_slot_function` can lead to Use-After-Free if a hotplug driver is concurrently unbound. Sashiko identified this as a pre-existing issue, so I don't think should be addressed with this patch. Thanks Farhan ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v21 4/4] PCI/MSI: Enable memory decoding before restoring MSI-X messages [not found] <20260630164807.643-1-alifm@linux.ibm.com> 2026-06-30 16:48 ` [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 Farhan Ali @ 2026-06-30 16:48 ` Farhan Ali 1 sibling, 0 replies; 7+ messages in thread From: Farhan Ali @ 2026-06-30 16:48 UTC (permalink / raw) To: linux-s390, linux-kernel, linux-pci Cc: helgaas, alex, alifm, schnelle, mjrosato, stable, Thomas Gleixner The current MSI-X restoration path assumes the Command register Memory bit is enabled when writing MSI-X messages. But it's possible the last saved and restored state of a device may not have the Memory bit enabled, even if a device driver later enables Memory bit and MSI-X. Attempting to access Memory space without Memory bit enabled can lead to Unsupported Request (UR) from the device. Fix this by enabling Memory bit and restore it afterwards. Fixes: 41017f0cac92 ("[PATCH] PCI: MSI(X) save/restore for suspend/resume") Cc: stable@vger.kernel.org Reviewed-by: Thomas Gleixner <tglx@kernel.org> Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com> Signed-off-by: Farhan Ali <alifm@linux.ibm.com> --- drivers/pci/msi/msi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c index 209373c92e9e..79c7e84d314b 100644 --- a/drivers/pci/msi/msi.c +++ b/drivers/pci/msi/msi.c @@ -870,6 +870,7 @@ void __pci_restore_msix_state(struct pci_dev *dev) { struct msi_desc *entry; bool write_msg; + u16 cmd; if (!dev->msix_enabled) return; @@ -879,6 +880,14 @@ void __pci_restore_msix_state(struct pci_dev *dev) pci_msix_clear_and_set_ctrl(dev, 0, PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL); + /* + * The restored device state may not have Memory decoding enabled + * in the Command register. Since the MSI-X was enabled for the + * device, enable Memory decoding before restoring MSI-X. + */ + pci_read_config_word(dev, PCI_COMMAND, &cmd); + pci_write_config_word(dev, PCI_COMMAND, cmd | PCI_COMMAND_MEMORY); + write_msg = arch_restore_msi_irqs(dev); scoped_guard (msi_descs_lock, &dev->dev) { @@ -889,6 +898,7 @@ void __pci_restore_msix_state(struct pci_dev *dev) } } + pci_write_config_word(dev, PCI_COMMAND, cmd); pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0); } -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-23 1:21 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20260630164807.643-1-alifm@linux.ibm.com>
2026-06-30 16:48 ` [PATCH v21 1/4] PCI: Allow per function PCI slots to fix slot reset on s390 Farhan Ali
2026-07-15 23:34 ` Bjorn Helgaas
2026-07-16 18:15 ` Farhan Ali
2026-07-22 22:32 ` Bjorn Helgaas
2026-07-23 1:21 ` Farhan Ali
2026-07-16 18:19 ` Farhan Ali
2026-06-30 16:48 ` [PATCH v21 4/4] PCI/MSI: Enable memory decoding before restoring MSI-X messages Farhan Ali
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox