* Re: [PATCH] i2c: i801: fix hardware state machine corruption in error path
2026-05-07 11:43 [PATCH] i2c: i801: fix hardware state machine corruption in error path w15303746062
@ 2026-05-12 8:38 ` Jean Delvare
2026-05-14 16:39 ` kernel test robot
2026-05-15 1:08 ` kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: Jean Delvare @ 2026-05-12 8:38 UTC (permalink / raw)
To: w15303746062; +Cc: andi.shyti, linux-i2c, linux-kernel, Mingyu Wang
Hi Wang,
On Thu, 7 May 2026 19:43:56 +0800, w15303746062@163.com wrote:
> From: Mingyu Wang <25181214217@stu.xidian.edu.cn>
>
> 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 or another thread), the kernel
This can't be "another thread", as calls to i801_access() are
serialized.
> 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.
Analysis looks good. We indeed should not write to a register if we do
not own the device.
> Fix this by introducing an 'out_err' label. If i801_check_pre() fails,
> we safely bypass the hardware register cleanup and only release the
> software locks (pm_runtime and mutex), strictly adhering to the rule of
> not releasing resources that were never acquired.
This fix introduces a build-time warning:
drivers/i2c/busses/i2c-i801.c: In function ‘i801_access’:
drivers/i2c/busses/i2c-i801.c:930:1: warning: label ‘out’ defined but not used [-Wunused-label]
930 | out:
| ^~~
drivers/i2c/busses/i2c-i801.c:930:1: warning: unused label 'out'
Am I missing another driver change? Or did you not test-build your
patch?
There's only one goto in i801_access(), so you don't need 2 labels.
Instead of introducing a new label you should move the existing one.
> Signed-off-by: Mingyu Wang <25181214217@stu.xidian.edu.cn>
I looked into the driver history to try and figure out when the bug was
introduced.
The label you are moving was re-introduced when the call to
i801_check_pre() was moved to i801_access() in v6.3 by:
commit 1f760b87e54cf56a25ab68f8dc625e339f6e46d5
Author: Heiner Kallweit
Date: Thu Feb 16 17:14:51 2023 +0100
i2c: i801: Call i801_check_pre() from i801_access()
However it existed already in earlier driver versions, until
a3989dc0b059 ("i2c: i801: Centralize configuring block commands in
i801_block_transaction") also in v6.3. As i801_check_pre() was called
later back then, we already wrote to device registers many times before
the check, so fixing this bug in older versions of the driver would be
much harder.
So I think your fix should be backported to stable branches v6.3+, and
if anyone wants the fix in an older kernel, they will have to backport
1f760b87e54c ("i2c: i801: Call i801_check_pre() from i801_access()")
first.
The first relevant commit in the driver history seems to be:
ommit 065b6211a87746e196b56759a70c7851418dd741
Author: Heiner Kallweit
Date: Sun Jun 6 15:55:55 2021 +0200
i2c: i801: Ensure that SMBHSTSTS_INUSE_STS is cleared when leaving i801_access
Before that, we did not touch SMBHSTSTS at the end of i801_access(), so
the fix does not apply (although the bug was present in another form, as
we were writing to device registers before the busy check back then).
The status flag clearing was added by:
commit 4f7275fc7e570dfc46f733ff8ae131cb128a4758
Author: Heiner Kallweit
Date: Sat Dec 4 21:04:40 2021 +0100
i2c: i801: Don't clear status flags twice in interrupt mode
but then again it's only moving the execution around, not introducing
the bug.
Anyway, this was for information only, I do not think the issue is
worth fixing in older kernels where the driver code is very different.
Concurrent access to the SMBus controller by the native Linux driver
and the firmware was best effort originally and we are well aware that
it was not 100% reliable back then. Anyone who cares about this
scenario would have to use a newer version of the i2c-i801 driver.
> ---
> drivers/i2c/busses/i2c-i801.c | 3 ++-
> 1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
> index 32a3cef02c7b..068b9ffb234f 100644
> --- a/drivers/i2c/busses/i2c-i801.c
> +++ b/drivers/i2c/busses/i2c-i801.c
> @@ -905,7 +905,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
>
> ret = i801_check_pre(priv);
> if (ret)
> - goto out;
> + goto out_err;
>
> hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
> && size != I2C_SMBUS_QUICK
> @@ -938,6 +938,7 @@ static s32 i801_access(struct i2c_adapter *adap, u16 addr,
> */
> iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
>
> +out_err:
> pm_runtime_put_autosuspend(&priv->pci_dev->dev);
> mutex_unlock(&priv->acpi_lock);
> return ret;
--
Jean Delvare
SUSE L3 Support
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] i2c: i801: fix hardware state machine corruption in error path
2026-05-07 11:43 [PATCH] i2c: i801: fix hardware state machine corruption in error path w15303746062
2026-05-12 8:38 ` Jean Delvare
@ 2026-05-14 16:39 ` kernel test robot
2026-05-15 1:08 ` kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-05-14 16:39 UTC (permalink / raw)
To: w15303746062, jdelvare, andi.shyti
Cc: oe-kbuild-all, linux-i2c, linux-kernel, Mingyu Wang
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on andi-shyti/i2c/i2c-host]
[also build test WARNING on linus/master v7.1-rc3 next-20260508]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/w15303746062-163-com/i2c-i801-fix-hardware-state-machine-corruption-in-error-path/20260514-165009
base: https://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c/i2c-host
patch link: https://lore.kernel.org/r/20260507114356.247525-1-w15303746062%40163.com
patch subject: [PATCH] i2c: i801: fix hardware state machine corruption in error path
config: powerpc-randconfig-001-20260514 (https://download.01.org/0day-ci/archive/20260515/202605150012.iDZZ7jFf-lkp@intel.com/config)
compiler: powerpc-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260515/202605150012.iDZZ7jFf-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605150012.iDZZ7jFf-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/i2c/busses/i2c-i801.c: In function 'i801_access':
>> drivers/i2c/busses/i2c-i801.c:934:1: warning: label 'out' defined but not used [-Wunused-label]
out:
^~~
vim +/out +934 drivers/i2c/busses/i2c-i801.c
^1da177e4c3f415 Linus Torvalds 2005-04-16 889
97140342e69d479 David Brownell 2008-07-14 890 /* Return negative errno on error. */
^1da177e4c3f415 Linus Torvalds 2005-04-16 891 static s32 i801_access(struct i2c_adapter *adap, u16 addr,
^1da177e4c3f415 Linus Torvalds 2005-04-16 892 unsigned short flags, char read_write, u8 command,
^1da177e4c3f415 Linus Torvalds 2005-04-16 893 int size, union i2c_smbus_data *data)
^1da177e4c3f415 Linus Torvalds 2005-04-16 894 {
a3989dc0b059a51 Heiner Kallweit 2023-02-16 895 int hwpec, ret;
0cd96eb0a74791c David Woodhouse 2010-10-31 896 struct i801_priv *priv = i2c_get_adapdata(adap);
^1da177e4c3f415 Linus Torvalds 2005-04-16 897
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 898 mutex_lock(&priv->acpi_lock);
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 899 if (priv->acpi_reserved) {
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 900 mutex_unlock(&priv->acpi_lock);
a7ae81952cdab56 Mika Westerberg 2016-06-09 901 return -EBUSY;
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 902 }
a7ae81952cdab56 Mika Westerberg 2016-06-09 903
a7401ca5596e246 Jarkko Nikula 2016-03-10 904 pm_runtime_get_sync(&priv->pci_dev->dev);
a7401ca5596e246 Jarkko Nikula 2016-03-10 905
1f760b87e54cf56 Heiner Kallweit 2023-02-16 906 ret = i801_check_pre(priv);
1f760b87e54cf56 Heiner Kallweit 2023-02-16 907 if (ret)
e67d702846114f6 Mingyu Wang 2026-05-07 908 goto out_err;
1f760b87e54cf56 Heiner Kallweit 2023-02-16 909
0cd96eb0a74791c David Woodhouse 2010-10-31 910 hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
e8aac4a9b417643 Jean Delvare 2005-10-26 911 && size != I2C_SMBUS_QUICK
e8aac4a9b417643 Jean Delvare 2005-10-26 912 && size != I2C_SMBUS_I2C_BLOCK_DATA;
^1da177e4c3f415 Linus Torvalds 2005-04-16 913
ca8b9e32a11a7cb Oleg Ryjkov 2007-07-12 914 if (hwpec) /* enable/disable hardware PEC */
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 915 iowrite8(ioread8(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
ca8b9e32a11a7cb Oleg Ryjkov 2007-07-12 916 else
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 917 iowrite8(ioread8(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
0cd96eb0a74791c David Woodhouse 2010-10-31 918 SMBAUXCTL(priv));
e8aac4a9b417643 Jean Delvare 2005-10-26 919
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 920 if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_BLOCK_PROC_CALL)
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 921 ret = i801_smbus_block_transaction(priv, data, addr, command, read_write, size);
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 922 else if (size == I2C_SMBUS_I2C_BLOCK_DATA)
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 923 ret = i801_i2c_block_transaction(priv, data, addr, command, read_write, size);
7edcb9abb594a8f Oleg Ryjkov 2007-07-12 924 else
24592482d235107 Heiner Kallweit 2023-02-16 925 ret = i801_simple_transaction(priv, data, addr, command, read_write, size);
^1da177e4c3f415 Linus Torvalds 2005-04-16 926
de461a2607c69c4 Heiner Kallweit 2023-02-16 927 ret = i801_check_post(priv, ret);
de461a2607c69c4 Heiner Kallweit 2023-02-16 928
c79cfbaccac0ef8 Jean Delvare 2006-04-20 929 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
63fd342fd121c3e Heiner Kallweit 2023-02-16 930 * time, so we forcibly disable it after every transaction.
63fd342fd121c3e Heiner Kallweit 2023-02-16 931 */
63fd342fd121c3e Heiner Kallweit 2023-02-16 932 if (hwpec)
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 933 iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
1f760b87e54cf56 Heiner Kallweit 2023-02-16 @934 out:
4f7275fc7e570df Heiner Kallweit 2021-12-04 935 /*
4f7275fc7e570df Heiner Kallweit 2021-12-04 936 * Unlock the SMBus device for use by BIOS/ACPI,
4f7275fc7e570df Heiner Kallweit 2021-12-04 937 * and clear status flags if not done already.
4f7275fc7e570df Heiner Kallweit 2021-12-04 938 */
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 939 iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
065b6211a87746e Heiner Kallweit 2021-06-06 940
e67d702846114f6 Mingyu Wang 2026-05-07 941 out_err:
a7401ca5596e246 Jarkko Nikula 2016-03-10 942 pm_runtime_put_autosuspend(&priv->pci_dev->dev);
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 943 mutex_unlock(&priv->acpi_lock);
a7401ca5596e246 Jarkko Nikula 2016-03-10 944 return ret;
^1da177e4c3f415 Linus Torvalds 2005-04-16 945 }
^1da177e4c3f415 Linus Torvalds 2005-04-16 946
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [PATCH] i2c: i801: fix hardware state machine corruption in error path
2026-05-07 11:43 [PATCH] i2c: i801: fix hardware state machine corruption in error path w15303746062
2026-05-12 8:38 ` Jean Delvare
2026-05-14 16:39 ` kernel test robot
@ 2026-05-15 1:08 ` kernel test robot
2 siblings, 0 replies; 4+ messages in thread
From: kernel test robot @ 2026-05-15 1:08 UTC (permalink / raw)
To: w15303746062, jdelvare, andi.shyti
Cc: llvm, oe-kbuild-all, linux-i2c, linux-kernel, Mingyu Wang
Hi,
kernel test robot noticed the following build warnings:
[auto build test WARNING on andi-shyti/i2c/i2c-host]
[also build test WARNING on linus/master v7.1-rc3 next-20260508]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/w15303746062-163-com/i2c-i801-fix-hardware-state-machine-corruption-in-error-path/20260514-165009
base: https://git.kernel.org/pub/scm/linux/kernel/git/andi.shyti/linux.git i2c/i2c-host
patch link: https://lore.kernel.org/r/20260507114356.247525-1-w15303746062%40163.com
patch subject: [PATCH] i2c: i801: fix hardware state machine corruption in error path
config: loongarch-randconfig-002-20260514 (https://download.01.org/0day-ci/archive/20260515/202605150921.HPErQGU3-lkp@intel.com/config)
compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 5bac06718f502014fade905512f1d26d578a18f3)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260515/202605150921.HPErQGU3-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202605150921.HPErQGU3-lkp@intel.com/
All warnings (new ones prefixed by >>):
>> drivers/i2c/busses/i2c-i801.c:934:1: warning: unused label 'out' [-Wunused-label]
934 | out:
| ^~~~
1 warning generated.
vim +/out +934 drivers/i2c/busses/i2c-i801.c
^1da177e4c3f415 Linus Torvalds 2005-04-16 889
97140342e69d479 David Brownell 2008-07-14 890 /* Return negative errno on error. */
^1da177e4c3f415 Linus Torvalds 2005-04-16 891 static s32 i801_access(struct i2c_adapter *adap, u16 addr,
^1da177e4c3f415 Linus Torvalds 2005-04-16 892 unsigned short flags, char read_write, u8 command,
^1da177e4c3f415 Linus Torvalds 2005-04-16 893 int size, union i2c_smbus_data *data)
^1da177e4c3f415 Linus Torvalds 2005-04-16 894 {
a3989dc0b059a51 Heiner Kallweit 2023-02-16 895 int hwpec, ret;
0cd96eb0a74791c David Woodhouse 2010-10-31 896 struct i801_priv *priv = i2c_get_adapdata(adap);
^1da177e4c3f415 Linus Torvalds 2005-04-16 897
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 898 mutex_lock(&priv->acpi_lock);
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 899 if (priv->acpi_reserved) {
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 900 mutex_unlock(&priv->acpi_lock);
a7ae81952cdab56 Mika Westerberg 2016-06-09 901 return -EBUSY;
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 902 }
a7ae81952cdab56 Mika Westerberg 2016-06-09 903
a7401ca5596e246 Jarkko Nikula 2016-03-10 904 pm_runtime_get_sync(&priv->pci_dev->dev);
a7401ca5596e246 Jarkko Nikula 2016-03-10 905
1f760b87e54cf56 Heiner Kallweit 2023-02-16 906 ret = i801_check_pre(priv);
1f760b87e54cf56 Heiner Kallweit 2023-02-16 907 if (ret)
e67d702846114f6 Mingyu Wang 2026-05-07 908 goto out_err;
1f760b87e54cf56 Heiner Kallweit 2023-02-16 909
0cd96eb0a74791c David Woodhouse 2010-10-31 910 hwpec = (priv->features & FEATURE_SMBUS_PEC) && (flags & I2C_CLIENT_PEC)
e8aac4a9b417643 Jean Delvare 2005-10-26 911 && size != I2C_SMBUS_QUICK
e8aac4a9b417643 Jean Delvare 2005-10-26 912 && size != I2C_SMBUS_I2C_BLOCK_DATA;
^1da177e4c3f415 Linus Torvalds 2005-04-16 913
ca8b9e32a11a7cb Oleg Ryjkov 2007-07-12 914 if (hwpec) /* enable/disable hardware PEC */
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 915 iowrite8(ioread8(SMBAUXCTL(priv)) | SMBAUXCTL_CRC, SMBAUXCTL(priv));
ca8b9e32a11a7cb Oleg Ryjkov 2007-07-12 916 else
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 917 iowrite8(ioread8(SMBAUXCTL(priv)) & (~SMBAUXCTL_CRC),
0cd96eb0a74791c David Woodhouse 2010-10-31 918 SMBAUXCTL(priv));
e8aac4a9b417643 Jean Delvare 2005-10-26 919
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 920 if (size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_BLOCK_PROC_CALL)
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 921 ret = i801_smbus_block_transaction(priv, data, addr, command, read_write, size);
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 922 else if (size == I2C_SMBUS_I2C_BLOCK_DATA)
6ff9d46cd36fbd0 Heiner Kallweit 2024-02-02 923 ret = i801_i2c_block_transaction(priv, data, addr, command, read_write, size);
7edcb9abb594a8f Oleg Ryjkov 2007-07-12 924 else
24592482d235107 Heiner Kallweit 2023-02-16 925 ret = i801_simple_transaction(priv, data, addr, command, read_write, size);
^1da177e4c3f415 Linus Torvalds 2005-04-16 926
de461a2607c69c4 Heiner Kallweit 2023-02-16 927 ret = i801_check_post(priv, ret);
de461a2607c69c4 Heiner Kallweit 2023-02-16 928
c79cfbaccac0ef8 Jean Delvare 2006-04-20 929 /* Some BIOSes don't like it when PEC is enabled at reboot or resume
63fd342fd121c3e Heiner Kallweit 2023-02-16 930 * time, so we forcibly disable it after every transaction.
63fd342fd121c3e Heiner Kallweit 2023-02-16 931 */
63fd342fd121c3e Heiner Kallweit 2023-02-16 932 if (hwpec)
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 933 iowrite8(ioread8(SMBAUXCTL(priv)) & ~SMBAUXCTL_CRC, SMBAUXCTL(priv));
1f760b87e54cf56 Heiner Kallweit 2023-02-16 @934 out:
4f7275fc7e570df Heiner Kallweit 2021-12-04 935 /*
4f7275fc7e570df Heiner Kallweit 2021-12-04 936 * Unlock the SMBus device for use by BIOS/ACPI,
4f7275fc7e570df Heiner Kallweit 2021-12-04 937 * and clear status flags if not done already.
4f7275fc7e570df Heiner Kallweit 2021-12-04 938 */
4a3f77ea77013d8 Heiner Kallweit 2025-03-12 939 iowrite8(SMBHSTSTS_INUSE_STS | STATUS_FLAGS, SMBHSTSTS(priv));
065b6211a87746e Heiner Kallweit 2021-06-06 940
e67d702846114f6 Mingyu Wang 2026-05-07 941 out_err:
a7401ca5596e246 Jarkko Nikula 2016-03-10 942 pm_runtime_put_autosuspend(&priv->pci_dev->dev);
cfc69c2e6c699c9 Charles Haithcock 2026-02-27 943 mutex_unlock(&priv->acpi_lock);
a7401ca5596e246 Jarkko Nikula 2016-03-10 944 return ret;
^1da177e4c3f415 Linus Torvalds 2005-04-16 945 }
^1da177e4c3f415 Linus Torvalds 2005-04-16 946
--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
^ permalink raw reply [flat|nested] 4+ messages in thread