[PATCH 02/28] mfd: ls2kbmc: Unregister GPIO GSI via devm_add_action_or_reset()

From: Lee Jones

Date: Wed Oct 21 2026 - 08:27:19 EST


ls2k_bmc_init() unconditionally calls acpi_unregister_gsi() immediately
after requesting the GPIO interrupt via devm_request_irq(). This
prematurely disposes of the active IRQ mapping while the interrupt
handler remains registered, breaking the GPIO watchdog interrupt and
causing a use-after-free when devres later frees the disposed IRQ
descriptor on probe failure or device unbind.

Register a devm_add_action_or_reset() callback before devm_request_irq()
so that acpi_unregister_gsi() is invoked only after devres has freed the
interrupt.

Fixes: d952bba3fbb5 ("mfd: ls2kbmc: Add Loongson-2K BMC reset function support")
Closes: https://sashiko.dev/#/bug/linux-cab8bfb6-4077-46f3-a173-ac2e2042cf66
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Lee Jones <lee@xxxxxxxxxx>
---
drivers/mfd/ls2k-bmc-core.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/drivers/mfd/ls2k-bmc-core.c b/drivers/mfd/ls2k-bmc-core.c
index 408056bfb2fe..23c774a09842 100644
--- a/drivers/mfd/ls2k-bmc-core.c
+++ b/drivers/mfd/ls2k-bmc-core.c
@@ -363,6 +363,11 @@ static void ls2k_bmc_save_pci_data(struct pci_dev *pdev, struct ls2k_bmc_ddata *
pci_read_config_dword(pdev, PCI_INTERRUPT_LINE, &ddata->bmc_pci_data.interrupt_line);
}

+static void ls2k_bmc_unregister_gsi(void *data)
+{
+ acpi_unregister_gsi(LS2K_BMC_RESET_GPIO_GSI);
+}
+
static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
{
struct pci_dev *pdev = to_pci_dev(ddata->dev);
@@ -412,12 +417,15 @@ static int ls2k_bmc_init(struct ls2k_bmc_ddata *ddata)
if (gpio_irq < 0)
return gpio_irq;

+ ret = devm_add_action_or_reset(ddata->dev, ls2k_bmc_unregister_gsi, NULL);
+ if (ret)
+ return ret;
+
ret = devm_request_irq(ddata->dev, gpio_irq, ls2k_bmc_interrupt,
IRQF_SHARED | IRQF_TRIGGER_FALLING, "ls2kbmc gpio", ddata);
if (ret)
dev_err(ddata->dev, "Failed to request LS2KBMC GPIO IRQ %d.\n", gpio_irq);

- acpi_unregister_gsi(LS2K_BMC_RESET_GPIO_GSI);
return ret;
}

--
2.56.0.218.g1ec904b173-goog