Re:[PATCH v2] i2c: i801: fix hardware state machine corruption in error path

From: w15303746062

Date: Thu Jun 04 2026 - 08:22:34 EST




Hi Jean, Andi,

Just a gentle ping on this v2 patch. It reuses the existing 'out' label to fix
the unused label warning and updates the commit message exactly as Jean suggested.

Please let me know if there is anything else needed from my side, or if
it is good to be queued up.

Thanks,
Mingyu

At 2026-05-12 17:35:34, w15303746062@xxxxxxx wrote:
>From: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
>
>A severe livelock and subsequent Hung Task panic were observed in the
>i2c-i801 driver during concurrent Fuzzing. The crash is caused by an
>unconditional hardware register cleanup in the error handling path of
>i801_access().
>
>When i801_check_pre() fails (e.g., returning -EBUSY because the SMBus
>controller is actively used by BIOS/ACPI), the kernel does not actually
>acquire the hardware ownership. However, the code jumps to the 'out'
>label and executes:
>
> iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
>
>This forcefully clears the INUSE_STS lock and resets the hardware status
>flags without owning the controller. Doing so interrupts ongoing BIOS/ACPI
>transactions and totally corrupts the SMBus hardware state machine.
>
>Consequently, all subsequent i801_access() calls fail at the pre-check
>stage, triggering an endless stream of "SMBus is busy, can't use it!"
>error logs. Over a slow serial console, this printk flood monopolizes
>the CPU (Console Livelock), starving other processes trying to acquire
>the mmap_lock down_read semaphore, ultimately triggering the hung task
>watchdog.
>
>Fix this by moving the 'out' label below the hardware register cleanup.
>If i801_check_pre() fails, we safely bypass the iowrite8() and only
>release the software locks (pm_runtime and mutex), strictly adhering to
>the rule of not releasing resources that were never acquired.
>
>Fixes: 1f760b87e54c ("i2c: i801: Call i801_check_pre() from i801_access()")
>Cc: stable@xxxxxxxxxxxxxxx # v6.3+
>
>Signed-off-by: Mingyu Wang <25181214217@xxxxxxxxxxxxxxxxx>
>---
>Changes in v2:
> - Reused and moved the existing 'out' label instead of adding a new one,
> fixing a build warning regarding an unused label.
> - Dropped the inaccurate mention of "another thread" in the commit message,
> as i801_access() is serialized by a mutex.
> - Added Fixes and Cc stable tags as suggested.
>
> drivers/i2c/busses/i2c-i801.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
>index 32a3cef02c7b..b29c99ed3883 100644
>--- a/drivers/i2c/busses/i2c-i801.c
>+++ b/drivers/i2c/busses/i2c-i801.c
>@@ -931,13 +931,13 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
> */
> if (hwpec)
> iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
>-out:
> /*
> * Unlock the SMBus device for use by BIOS/ACPI,
> * and clear status flags if not done already.
> */
> iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
>
>+out:
> pm_runtime_put_autosuspend(&priv->pci_dev->dev);
> mutex_unlock(&priv->acpi_lock);
> return ret;
>--
>2.34.1