lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20240703163250.47887-1-shenwei.wang@nxp.com>
Date: Wed,  3 Jul 2024 11:32:50 -0500
From: Shenwei Wang <shenwei.wang@....com>
To: Thomas Gleixner <tglx@...utronix.de>,
	Shawn Guo <shawnguo@...nel.org>,
	Sascha Hauer <s.hauer@...gutronix.de>
Cc: Pengutronix Kernel Team <kernel@...gutronix.de>,
	Fabio Estevam <festevam@...il.com>,
	linux-kernel@...r.kernel.org,
	imx@...ts.linux.dev,
	linux-imx@....com,
	Shenwei Wang <shenwei.wang@....com>
Subject: [PATCH] irqchip/imx-irqsteer: Add irq_bus_lock/sync_unlock handlers

Add irq_bus_lock/sync_unlock handlers.

Without these handlers, the power domain is automatically activated during
clk_prepare. However, on certain platforms like i.MX8QM and i.MX8QXP, the
power-on phase may involve sleep function calls, which can lead to random
system dumps during driver probes at system boot.

By adding these handlers, the actual power-on actions are moved to occur
before clk_prepare, thus resolving the system dump issue.

The following is the example of system dump on i.MX8QM MEK.

[    3.135799] BUG: scheduling while atomic: kworker/u13:1/48/0x00000002
[    3.142270] Modules linked in:
[    3.145349] CPU: 0 PID: 48 Comm: kworker/u13:1 Not tainted 6.6.3-lts-next-g5a913c7fc95d #1
[    3.153616] Hardware name: Freescale i.MX8QM MEK (DT)
[    3.158678] Workqueue: events_unbound deferred_probe_work_func
[    3.164529] Call trace:
[    3.166981]  dump_backtrace+0x90/0xe8
[    3.170652]  show_stack+0x18/0x24
[    3.173971]  dump_stack_lvl+0x48/0x60
[    3.177644]  dump_stack+0x18/0x24
[    3.180964]  __schedule_bug+0x54/0x6c
[    3.184628]  __schedule+0x7f0/0xa94
[    3.188121]  schedule+0x5c/0xc4
[    3.191266]  schedule_preempt_disabled+0x24/0x40
[    3.195887]  __mutex_lock.constprop.0+0x2c0/0x540
[    3.200596]  __mutex_lock_slowpath+0x14/0x20
[    3.204870]  mutex_lock+0x48/0x54
[    3.208189]  clk_prepare_lock+0x44/0xa0
[    3.212040]  clk_prepare+0x20/0x44
[    3.215452]  imx_irqsteer_resume+0x28/0xe0
[    3.219552]  pm_generic_runtime_resume+0x2c/0x44
[    3.224174]  __genpd_runtime_resume+0x30/0x80
[    3.228535]  genpd_runtime_resume+0xc8/0x2c0
[    3.232809]  __rpm_callback+0x48/0x1d8
[    3.236562]  rpm_callback+0x6c/0x78
[    3.240055]  rpm_resume+0x490/0x6b4
[    3.243549]  __pm_runtime_resume+0x50/0x94
[    3.247648]  irq_chip_pm_get+0x2c/0xa0
[    3.251401]  __irq_do_set_handler+0x178/0x24c
[    3.255762]  irq_set_chained_handler_and_data+0x60/0xa4
[    3.260992]  mxc_gpio_probe+0x160/0x4b0
[    3.264840]  platform_probe+0x68/0xc8
[    3.268506]  really_probe+0x148/0x2b0
[    3.272172]  __driver_probe_device+0x78/0x12c
[    3.276536]  driver_probe_device+0xd8/0x15c
[    3.280721]  __device_attach_driver+0xb8/0x134
[    3.285169]  bus_for_each_drv+0x88/0xe8
[    3.289009]  __device_attach+0xa0/0x190
[    3.292849]  device_initial_probe+0x14/0x20
[    3.297036]  bus_probe_device+0xac/0xb0
[    3.300876]  deferred_probe_work_func+0x80/0xb8
[    3.305411]  process_one_work+0x138/0x248
[    3.309427]  worker_thread+0x320/0x438
[    3.313177]  kthread+0x110/0x114
[    3.316409]  ret_from_fork+0x10/0x20

Signed-off-by: Shenwei Wang <shenwei.wang@....com>
---
 drivers/irqchip/irq-imx-irqsteer.c | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/drivers/irqchip/irq-imx-irqsteer.c b/drivers/irqchip/irq-imx-irqsteer.c
index 20cf7a9e9ece..f81e4ff3aec3 100644
--- a/drivers/irqchip/irq-imx-irqsteer.c
+++ b/drivers/irqchip/irq-imx-irqsteer.c
@@ -36,6 +36,7 @@ struct irqsteer_data {
 	int			channel;
 	struct irq_domain	*domain;
 	u32			*saved_reg;
+	struct device		*dev;
 };
 
 static int imx_irqsteer_get_reg_index(struct irqsteer_data *data,
@@ -72,10 +73,26 @@ static void imx_irqsteer_irq_mask(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&data->lock, flags);
 }
 
+static void imx_irqsteer_irq_bus_lock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_get_sync(data->dev);
+}
+
+static void imx_irqsteer_irq_bus_sync_unlock(struct irq_data *d)
+{
+	struct irqsteer_data *data = d->chip_data;
+
+	pm_runtime_put_autosuspend(data->dev);
+}
+
 static const struct irq_chip imx_irqsteer_irq_chip = {
 	.name		= "irqsteer",
 	.irq_mask	= imx_irqsteer_irq_mask,
 	.irq_unmask	= imx_irqsteer_irq_unmask,
+	.irq_bus_lock		= imx_irqsteer_irq_bus_lock,
+	.irq_bus_sync_unlock	= imx_irqsteer_irq_bus_sync_unlock,
 };
 
 static int imx_irqsteer_irq_map(struct irq_domain *h, unsigned int irq,
@@ -150,6 +167,7 @@ static int imx_irqsteer_probe(struct platform_device *pdev)
 	if (!data)
 		return -ENOMEM;
 
+	data->dev = &pdev->dev;
 	data->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->regs)) {
 		dev_err(&pdev->dev, "failed to initialize reg\n");
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ