[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20250616-aspeed-lpc-snoop-fixes-v2-2-3cdd59c934d3@codeconstruct.com.au>
Date: Mon, 16 Jun 2025 22:43:39 +0930
From: Andrew Jeffery <andrew@...econstruct.com.au>
To: linux-aspeed@...ts.ozlabs.org
Cc: Joel Stanley <joel@....id.au>, Henry Martin <bsdhenrymartin@...il.com>,
Jean Delvare <jdelvare@...e.de>,
Patrick Rudolph <patrick.rudolph@...ements.com>,
Andrew Geissler <geissonator@...oo.com>,
Ninad Palsule <ninad@...ux.ibm.com>, Patrick Venture <venture@...gle.com>,
Robert Lippert <roblip@...il.com>, linux-arm-kernel@...ts.infradead.org,
linux-kernel@...r.kernel.org, Andrew Jeffery <andrew@...econstruct.com.au>,
stable@...r.kernel.org
Subject: [PATCH v2 02/10] soc: aspeed: lpc-snoop: Don't disable channels
that aren't enabled
Mitigate e.g. the following:
# echo 1e789080.lpc-snoop > /sys/bus/platform/drivers/aspeed-lpc-snoop/unbind
...
[ 120.363594] Unable to handle kernel NULL pointer dereference at virtual address 00000004 when write
[ 120.373866] [00000004] *pgd=00000000
[ 120.377910] Internal error: Oops: 805 [#1] SMP ARM
[ 120.383306] CPU: 1 UID: 0 PID: 315 Comm: sh Not tainted 6.15.0-rc1-00009-g926217bc7d7d-dirty #20 NONE
...
[ 120.679543] Call trace:
[ 120.679559] misc_deregister from aspeed_lpc_snoop_remove+0x84/0xac
[ 120.692462] aspeed_lpc_snoop_remove from platform_remove+0x28/0x38
[ 120.700996] platform_remove from device_release_driver_internal+0x188/0x200
...
Fixes: 9f4f9ae81d0a ("drivers/misc: add Aspeed LPC snoop driver")
Cc: stable@...r.kernel.org
Cc: Jean Delvare <jdelvare@...e.de>
Acked-by: Jean Delvare <jdelvare@...e.de>
Signed-off-by: Andrew Jeffery <andrew@...econstruct.com.au>
---
drivers/soc/aspeed/aspeed-lpc-snoop.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/drivers/soc/aspeed/aspeed-lpc-snoop.c b/drivers/soc/aspeed/aspeed-lpc-snoop.c
index 59c18afa649cd672f54f947066f468f2a78c0d5d..fc3a2c41cc10739f5f70ded7ac02baab6468d652 100644
--- a/drivers/soc/aspeed/aspeed-lpc-snoop.c
+++ b/drivers/soc/aspeed/aspeed-lpc-snoop.c
@@ -58,6 +58,7 @@ struct aspeed_lpc_snoop_model_data {
};
struct aspeed_lpc_snoop_channel {
+ bool enabled;
struct kfifo fifo;
wait_queue_head_t wq;
struct miscdevice miscdev;
@@ -190,6 +191,9 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
const struct aspeed_lpc_snoop_model_data *model_data =
of_device_get_match_data(dev);
+ if (WARN_ON(lpc_snoop->chan[channel].enabled))
+ return -EBUSY;
+
init_waitqueue_head(&lpc_snoop->chan[channel].wq);
/* Create FIFO datastructure */
rc = kfifo_alloc(&lpc_snoop->chan[channel].fifo,
@@ -236,6 +240,8 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
regmap_update_bits(lpc_snoop->regmap, HICRB,
hicrb_en, hicrb_en);
+ lpc_snoop->chan[channel].enabled = true;
+
return 0;
err_misc_deregister:
@@ -248,6 +254,9 @@ static int aspeed_lpc_enable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
int channel)
{
+ if (!lpc_snoop->chan[channel].enabled)
+ return;
+
switch (channel) {
case 0:
regmap_update_bits(lpc_snoop->regmap, HICR5,
@@ -263,6 +272,8 @@ static void aspeed_lpc_disable_snoop(struct aspeed_lpc_snoop *lpc_snoop,
return;
}
+ lpc_snoop->chan[channel].enabled = false;
+ /* Consider improving safety wrt concurrent reader(s) */
misc_deregister(&lpc_snoop->chan[channel].miscdev);
kfifo_free(&lpc_snoop->chan[channel].fifo);
}
--
2.39.5
Powered by blists - more mailing lists