]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ACPI: IPMI: Fix inverted interface check in ipmi_bmc_gone()
authorXu Rao <raoxu@uniontech.com>
Tue, 16 Jun 2026 09:36:21 +0000 (17:36 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 19 Jun 2026 18:56:20 +0000 (20:56 +0200)
Before commit a1a69b297e47 ("ACPI / IPMI: Fix race caused by the
unprotected ACPI IPMI user"), ipmi_bmc_gone() skipped entries whose
interface number did not match the SMI being removed, then killed the
matching entry:

if (ipmi_device->ipmi_ifnum != iface)
continue;

__ipmi_dev_kill(ipmi_device);

That commit folded the removal block into the existing non-match test
while converting the object lifetime handling, but left the comparison
unchanged. The old != meant "continue past this entry"; after the
refactor it meant "kill this entry".

As a result, a single ACPI IPMI interface is never removed when its SMI
disappears. If multiple interfaces are tracked, the first interface
whose number differs from iface is removed instead, while the interface
that actually disappeared remains on driver_data.ipmi_devices. The
stale entry is not marked dead and can continue to be selected for ACPI
IPMI transactions. It can also prevent the same ACPI handle from being
registered again.

Change the comparison to == so ipmi_bmc_gone() removes exactly the
interface reported as gone by the SMI watcher. This restores the
pre-a1a69b297e47 behavior and is the correct interface matching logic.

Fixes: a1a69b297e47 ("ACPI / IPMI: Fix race caused by the unprotected ACPI IPMI user")
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/B486593E06E6F6E0+20260616093621.1039943-1-raoxu@uniontech.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/acpi_ipmi.c

index 79ce6e72bf295a87c2a805fcdc3a931a651f65a0..2dbed92d54b30d551051f0156386d715192341cd 100644 (file)
@@ -490,7 +490,7 @@ static void ipmi_bmc_gone(int iface)
        mutex_lock(&driver_data.ipmi_lock);
        list_for_each_entry_safe(iter, temp,
                                 &driver_data.ipmi_devices, head) {
-               if (iter->ipmi_ifnum != iface) {
+               if (iter->ipmi_ifnum == iface) {
                        ipmi_device = iter;
                        __ipmi_dev_kill(iter);
                        break;