[PATCH 1/7] s390/pci: fix double-free in zpci MSI cleanup

From: Tobias Schumacher

Date: Wed Aug 19 2026 - 04:51:22 EST


zpci_remove_parent_msi_domain() can be called multiple times on the
same zbus, causing a double-free. This occurs when pci_create_root_bus()
fails after successful MSI domain creation in zpci_bus_create_pci_bus():
the error path calls zpci_remove_parent_msi_domain() to clean up, but
doesn't NULL the pointer. Later, when zpci_bus_release() is called via
kref_put(), it calls zpci_remove_parent_msi_domain() again, attempting
to free the already-freed domain and fwnode.

Add NULL check at function entry and NULL the pointer after cleanup to
make the function idempotent and safe for multiple calls.

Fixes: f770950a4709 ("s390/pci: Migrate s390 IRQ logic to IRQ domain API")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tobias Schumacher <ts@xxxxxxxxxxxxx>
---
arch/s390/pci/pci_irq.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/arch/s390/pci/pci_irq.c b/arch/s390/pci/pci_irq.c
index 9c9ed3d8d959..c9520a16ca75 100644
--- a/arch/s390/pci/pci_irq.c
+++ b/arch/s390/pci/pci_irq.c
@@ -533,9 +533,13 @@ void zpci_remove_parent_msi_domain(struct zpci_bus *zbus)
{
struct fwnode_handle *fn;

+ if (!zbus->msi_parent_domain)
+ return;
+
fn = zbus->msi_parent_domain->fwnode;
irq_domain_remove(zbus->msi_parent_domain);
irq_domain_free_fwnode(fn);
+ zbus->msi_parent_domain = NULL;
}

static void __init cpu_enable_directed_irq(void *unused)

--
2.53.0