Takashi Iwai a2d742
From e4d8716c3dcec47f1557024add24e1f3c09eb24b Mon Sep 17 00:00:00 2001
Takashi Iwai a2d742
From: Jean Delvare <jdelvare@suse.de>
Takashi Iwai a2d742
Date: Tue, 25 May 2021 17:03:36 +0200
Takashi Iwai a2d742
Subject: [PATCH] i2c: i801: Don't generate an interrupt on bus reset
Takashi Iwai a2d742
Git-commit: e4d8716c3dcec47f1557024add24e1f3c09eb24b
Takashi Iwai a2d742
Patch-mainline: v5.13-rc4
Takashi Iwai a2d742
References: git-fixes
Takashi Iwai a2d742
Takashi Iwai a2d742
Now that the i2c-i801 driver supports interrupts, setting the KILL bit
Takashi Iwai a2d742
in a attempt to recover from a timed out transaction triggers an
Takashi Iwai a2d742
interrupt. Unfortunately, the interrupt handler (i801_isr) is not
Takashi Iwai a2d742
prepared for this situation and will try to process the interrupt as
Takashi Iwai a2d742
if it was signaling the end of a successful transaction. In the case
Takashi Iwai a2d742
of a block transaction, this can result in an out-of-range memory
Takashi Iwai a2d742
access.
Takashi Iwai a2d742
Takashi Iwai a2d742
This condition was reproduced several times by syzbot:
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=ed71512d469895b5b34e
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=8c8dedc0ba9e03f6c79e
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=c8ff0b6d6c73d81b610e
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=33f6c360821c399d69eb
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=be15dc0b1933f04b043a
Takashi Iwai a2d742
https://syzkaller.appspot.com/bug?extid=b4d3fd1dfd53e90afd79
Takashi Iwai a2d742
Takashi Iwai a2d742
So disable interrupts while trying to reset the bus. Interrupts will
Takashi Iwai a2d742
be enabled again for the following transaction.
Takashi Iwai a2d742
Takashi Iwai a2d742
Fixes: 636752bcb517 ("i2c-i801: Enable IRQ for SMBus transactions")
Takashi Iwai a2d742
Reported-by: syzbot+b4d3fd1dfd53e90afd79@syzkaller.appspotmail.com
Takashi Iwai a2d742
Signed-off-by: Jean Delvare <jdelvare@suse.de>
Takashi Iwai a2d742
Acked-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Takashi Iwai a2d742
Cc: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Takashi Iwai a2d742
Tested-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Takashi Iwai a2d742
Signed-off-by: Wolfram Sang <wsa@kernel.org>
Takashi Iwai a2d742
Acked-by: Takashi Iwai <tiwai@suse.de>
Takashi Iwai a2d742
Takashi Iwai a2d742
---
Takashi Iwai a2d742
 drivers/i2c/busses/i2c-i801.c | 6 ++----
Takashi Iwai a2d742
 1 file changed, 2 insertions(+), 4 deletions(-)
Takashi Iwai a2d742
Takashi Iwai a2d742
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
Takashi Iwai a2d742
index 99d446763530..f9e1c2ceaac0 100644
Takashi Iwai a2d742
--- a/drivers/i2c/busses/i2c-i801.c
Takashi Iwai a2d742
+++ b/drivers/i2c/busses/i2c-i801.c
Takashi Iwai a2d742
@@ -395,11 +395,9 @@ static int i801_check_post(struct i801_priv *priv, int status)
Takashi Iwai a2d742
 		dev_err(&priv->pci_dev->dev, "Transaction timeout\n");
Takashi Iwai a2d742
 		/* try to stop the current command */
Takashi Iwai a2d742
 		dev_dbg(&priv->pci_dev->dev, "Terminating the current operation\n");
Takashi Iwai a2d742
-		outb_p(inb_p(SMBHSTCNT(priv)) | SMBHSTCNT_KILL,
Takashi Iwai a2d742
-		       SMBHSTCNT(priv));
Takashi Iwai a2d742
+		outb_p(SMBHSTCNT_KILL, SMBHSTCNT(priv));
Takashi Iwai a2d742
 		usleep_range(1000, 2000);
Takashi Iwai a2d742
-		outb_p(inb_p(SMBHSTCNT(priv)) & (~SMBHSTCNT_KILL),
Takashi Iwai a2d742
-		       SMBHSTCNT(priv));
Takashi Iwai a2d742
+		outb_p(0, SMBHSTCNT(priv));
Takashi Iwai a2d742
 
Takashi Iwai a2d742
 		/* Check if it worked */
Takashi Iwai a2d742
 		status = inb_p(SMBHSTSTS(priv));
Takashi Iwai a2d742
-- 
Takashi Iwai a2d742
2.26.2
Takashi Iwai a2d742