Commit f5067e67 authored by Jean Delvare's avatar Jean Delvare Committed by openeuler-sync-bot
Browse files

i2c: i801: Fix block process call transactions

stable inclusion
from stable-v5.10.210
commit 7a14b8a477b88607d157c24aeb23e7389ec3319f
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I93ELY
CVE: CVE-2024-26593

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=d074d5ff5ae77b18300e5079c6bda6342a4d44b7



--------------------------------

[ Upstream commit c1c9d0f6f7f1dbf29db996bd8e166242843a5f21 ]

According to the Intel datasheets, software must reset the block
buffer index twice for block process call transactions: once before
writing the outgoing data to the buffer, and once again before
reading the incoming data from the buffer.

The driver is currently missing the second reset, causing the wrong
portion of the block buffer to be read.

Signed-off-by: default avatarJean Delvare <jdelvare@suse.de>
Reported-by: default avatarPiotr Zakowski <piotr.zakowski@intel.com>
Closes: https://lore.kernel.org/linux-i2c/20240213120553.7b0ab120@endymion.delvare/


Fixes: 315cd67c ("i2c: i801: Add Block Write-Block Read Process Call support")
Reviewed-by: default avatarAlexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: default avatarAndi Shyti <andi.shyti@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
Signed-off-by: default avatarLiao Chen <liaochen4@huawei.com>
(cherry picked from commit e3d57867)
parent 8d06bcc8
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -540,12 +540,11 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
		return -EOPNOTSUPP;
	}

	inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */

	/* Use 32-byte buffer to process this transaction */
	if (read_write == I2C_SMBUS_WRITE) {
		len = data->block[0];
		outb_p(len, SMBHSTDAT0(priv));
		inb_p(SMBHSTCNT(priv)); /* reset the data buffer index */
		for (i = 0; i < len; i++)
			outb_p(data->block[i+1], SMBBLKDAT(priv));
	}
@@ -561,6 +560,7 @@ static int i801_block_transaction_by_block(struct i801_priv *priv,
			return -EPROTO;

		data->block[0] = len;
		inb_p(SMBHSTCNT(priv));	/* reset the data buffer index */
		for (i = 0; i < len; i++)
			data->block[i + 1] = inb_p(SMBBLKDAT(priv));
	}