| Message ID | 20260625003416.15841-1-pengpeng@iscas.ac.cn (mailing list archive) |
|---|---|
| State | New |
| Headers |
Return-Path: <linux-sunxi+bounces-23942-sunxi=pue.re@lists.linux.dev> X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sin.lore.kernel.org (sin.lore.kernel.org [104.64.211.4]) by mxe881.netcup.net (Postfix) with ESMTPS id 2298A1C1BF6 for <noreply@patchwork.local>; Thu, 25 Jun 2026 02:34:38 +0200 (CEST) Authentication-Results: mxe881; spf=pass (sender IP is 104.64.211.4) smtp.mailfrom=linux-sunxi+bounces-23942-noreply=patchwork.local@lists.linux.dev smtp.helo=sin.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 104.64.211.4 as permitted sender) client-ip=104.64.211.4; envelope-from=linux-sunxi+bounces-23942-noreply=patchwork.local@lists.linux.dev; helo=sin.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sin.lore.kernel.org (Postfix) with ESMTP id E935E300C3A6 for <noreply@patchwork.local>; Thu, 25 Jun 2026 00:34:33 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id E396A32E12E; Thu, 25 Jun 2026 00:34:30 +0000 (UTC) X-Original-To: linux-sunxi@lists.linux.dev Received: from cstnet.cn (smtp81.cstnet.cn [159.226.251.81]) (using TLSv1.2 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 001702F12AE for <linux-sunxi@lists.linux.dev>; Thu, 25 Jun 2026 00:34:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=159.226.251.81 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782347670; cv=none; b=cVtHQzrrE13CzC3mRpCepIsr01jz9vR3U8l4KwtF5ffZAhYmA5lcjlPTUMAKmYBJd8lPKMT5AjZKlVMelvevBIZZ2W2Vew4SW6V7NkVH0S4ZUGYtNW/ZCD39kwRBIiysNfh0C+WLtu0pf29qRd7EFPiiL1mmn3V9X+IwBHehYzQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782347670; c=relaxed/simple; bh=swyGRM5GlmdbbMMs2CuiPH4Z8MjFvASgzNQjRbMpx3w=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=f3mwcHc33kCg7822oCSmXJ4kAeIGMy4P/fBWzAic7UogMwRYDh6h34A2FQ/xS/PtJacdT9nFTNieqZOA6oE0ihNtK3cvyrF0ksp9qxn44RA8rWYYYwNJMc4tSDabStr1MT7cj8zIqE+Yx6Zk1mCzoIEhehL0xlWLyjGr6p0dWB8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn; spf=pass smtp.mailfrom=iscas.ac.cn; arc=none smtp.client-ip=159.226.251.81 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=iscas.ac.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=iscas.ac.cn Received: from localhost.localdomain (unknown [111.196.245.140]) by APP-03 (Coremail) with SMTP id rQCowADXwaiJdzxqAdjCFQ--.4213S2; Thu, 25 Jun 2026 08:34:18 +0800 (CST) From: Pengpeng Hou <pengpeng@iscas.ac.cn> To: Chen-Yu Tsai <wens@kernel.org> Cc: pengpeng@iscas.ac.cn, Jernej Skrabec <jernej.skrabec@gmail.com>, Samuel Holland <samuel@sholland.org>, Philipp Zabel <p.zabel@pengutronix.de>, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org Subject: [PATCH] bus: sunxi-rsb: fail hardware init on soft-reset timeout Date: Thu, 25 Jun 2026 08:34:16 +0800 Message-ID: <20260625003416.15841-1-pengpeng@iscas.ac.cn> X-Mailer: git-send-email 2.50.1 Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: <linux-sunxi.lists.linux.dev> List-Subscribe: <mailto:linux-sunxi+subscribe@lists.linux.dev> List-Unsubscribe: <mailto:linux-sunxi+unsubscribe@lists.linux.dev> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-CM-TRANSID: rQCowADXwaiJdzxqAdjCFQ--.4213S2 X-Coremail-Antispam: 1UD129KBjvJXoW7Cr4UCw43ZFWUWF18Xw4kXrb_yoW8Xr4kpa naka47CrWqqF4FqF12yF1jvF15X3Z7KF98C3s8Cwn2vwnYgry8CFyrKFWFg3W5AF48uay5 ZFnFqa1UCF1q9w7anT9S1TB71UUUUU7qnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDU0xBIdaVrnRJUUUkE14x267AKxVW8JVW5JwAFc2x0x2IEx4CE42xK8VAvwI8IcIk0 rVWrJVCq3wAFIxvE14AKwVWUJVWUGwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xGY2AK02 1l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14v26r4j 6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gr 1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv 7VC0I7IYx2IY67AKxVWUXVWUAwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r 1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY1x0262kKe7AK xVWUAVWUtwCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F4 0E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_Jw0_GFyl IxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxV AFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j 6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JUQo7 NUUUUU= X-CM-SenderInfo: pshqw1xhqjqxpvfd2hldfou0/ X-Rspamd-Server: rspamd-worker-8404 X-Spamd-Result: default: False [-0.66 / 15.00]; BAYES_HAM(-5.50)[99.99%]; RBL_SENDERSCORE(2.00)[104.64.211.4:from]; SUSPICIOUS_RECIPS(1.50)[]; MID_CONTAINS_FROM(1.00)[]; R_MISSING_CHARSET(0.50)[]; MAILLIST(-0.15)[generic]; MIME_GOOD(-0.10)[text/plain]; BAD_REP_POLICIES(0.10)[]; HAS_LIST_UNSUB(-0.01)[]; DMARC_NA(0.00)[iscas.ac.cn]; RCPT_COUNT_SEVEN(0.00)[8]; DBL_BLOCKED_OPENRESOLVER(0.00)[iscas.ac.cn:email,sin.lore.kernel.org:rdns,sin.lore.kernel.org:helo]; TAGGED_RCPT(0.00)[]; FREEMAIL_CC(0.00)[iscas.ac.cn,gmail.com,sholland.org,pengutronix.de,lists.infradead.org,lists.linux.dev,vger.kernel.org]; FUZZY_BLOCKED(0.00)[rspamd.com]; PRECEDENCE_BULK(0.00)[]; FROM_HAS_DN(0.00)[]; FORGED_SENDER_MAILLIST(0.00)[]; R_DKIM_NA(0.00)[]; ARC_ALLOW(0.00)[subspace.kernel.org:s=arc-20240116:i=1]; RCVD_TLS_LAST(0.00)[]; FORGED_RECIPIENTS_MAILLIST(0.00)[]; R_SPF_ALLOW(0.00)[+ip4:104.64.211.4]; MIME_TRACE(0.00)[0:+]; ASN(0.00)[asn:63949, ipnet:104.64.192.0/19, country:SG]; TAGGED_FROM(0.00)[bounces-23942-noreply=patchwork.local]; RCVD_COUNT_FIVE(0.00)[5]; FROM_NEQ_ENVFROM(0.00)[pengpeng@iscas.ac.cn,linux-sunxi@lists.linux.dev]; TO_DN_SOME(0.00)[] X-Rspamd-Queue-Id: 2298A1C1BF6 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= |
| Series |
bus: sunxi-rsb: fail hardware init on soft-reset timeout
|
|
Commit Message
Pengpeng Hou
June 25, 2026, 12:34 a.m. UTC
sunxi_rsb_hw_init() issues a controller soft reset and waits for the reset
bit to clear, but it ignores readl_poll_timeout()'s return value.
If the controller never leaves reset, probe can continue to publish child
devices and system resume can report success without a usable RSB
controller.
Return the timeout error, assert reset again, and disable the clock before
leaving the hardware-init path.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/bus/sunxi-rsb.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
Comments
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider: New issues: - [High] Asserting the hardware reset line on soft-reset timeout during system resume leaves the IP in reset, which causes a fatal bus hang when child devices subsequently attempt to access the controller. Pre-existing issues: - [High] If a malformed Device Tree explicitly sets `clock-frequency = <0>;`, it causes a kernel panic due to division by zero. - [High] The IRQ handler is requested before the hardware is initialized and its module clock is enabled, risking a fatal bus error. -- commit 1ad9a12cbc21560f6a2fb1e0bd342a6de275080c Author: Pengpeng Hou <pengpeng@iscas.ac.cn> bus: sunxi-rsb: fail hardware init on soft-reset timeout This commit adds a check for the controller soft reset in sunxi_rsb_hw_init. If the reset times out, the code now asserts the hardware reset line, disables the clock, and returns a timeout error instead of continuing. > diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c > index daf0ea563e477..f83224dea804d 100644 > --- a/drivers/bus/sunxi-rsb.c > +++ b/drivers/bus/sunxi-rsb.c > @@ -669,8 +669,12 @@ static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) > > /* reset the controller */ > writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL); > - readl_poll_timeout(rsb->regs + RSB_CTRL, reg, > - !(reg & RSB_CTRL_SOFT_RST), 1000, 100000); > + ret = readl_poll_timeout(rsb->regs + RSB_CTRL, reg, > + !(reg & RSB_CTRL_SOFT_RST), 1000, 100000); > + if (ret) { > + dev_err(dev, "soft reset timed out\n"); > + goto err_reset_assert; > + } > > /* > * Clock frequency and delay calculation code is from [ ... ] > @@ -696,6 +700,8 @@ static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) > > return 0; > > +err_reset_assert: > + reset_control_assert(rsb->rstc); [Severity: High] If sunxi_rsb_hw_init() fails due to this soft-reset timeout during system resume, it asserts the hardware reset line and returns an error: drivers/bus/sunxi-rsb.c:sunxi_rsb_resume() { struct sunxi_rsb *rsb = dev_get_drvdata(dev); return sunxi_rsb_hw_init(rsb); } The PM core logs the resume error but continues system resume. When child devices, such as PMICs, are subsequently resumed, they attempt to access the RSB bus to restore registers. The driver's runtime resume callback only enables the clock, which means the driver will attempt MMIO access while the controller is still held in hardware reset. Will writing to an IP block held in hardware reset cause a synchronous external abort and fatal bus hang on Allwinner SoCs? > err_clk_disable: > clk_disable_unprepare(rsb->clk); > [Severity: High] This isn't a bug introduced by this patch, but if a malformed Device Tree explicitly sets clock-frequency = <0>, sunxi_rsb_probe() successfully reads the 0 and bypasses the upper boundary check: drivers/bus/sunxi-rsb.c:sunxi_rsb_probe() { ... if (of_property_read_u32(np, "clock-frequency", &clk_freq)) { ... } else if (clk_freq > RSB_MAX_FREQ) { ... } ... } Later, sunxi_rsb_hw_init() uses this unchecked value as a divisor: drivers/bus/sunxi-rsb.c:sunxi_rsb_hw_init() { ... clk_div = p_clk_freq / rsb->clk_freq / 2; ... } Can this cause a fatal division by zero exception when rsb->clk_freq is 0? [Severity: High] This is a pre-existing issue, but devm_request_irq() is called before sunxi_rsb_hw_init() initializes the hardware and enables its module clock: drivers/bus/sunxi-rsb.c:sunxi_rsb_probe() { ... ret = devm_request_irq(dev, irq, sunxi_rsb_irq, 0, RSB_CTRL_NAME, rsb); if (ret) return dev_err_probe(...); ret = sunxi_rsb_hw_init(rsb); ... } If an interrupt fires immediately from a pending state from a previous boot stage, sunxi_rsb_irq() will execute and access the RSB_INTS register using readl() before the clock is enabled: drivers/bus/sunxi-rsb.c:sunxi_rsb_irq() { ... status = readl(rsb->regs + RSB_INTS); ... } Could accessing unclocked or reset MMIO space on Allwinner SoCs cause a fatal synchronous external abort here?
Dne četrtek, 25. junij 2026 ob 02:34:16 Srednjeevropski poletni čas je Pengpeng Hou napisal(a): > sunxi_rsb_hw_init() issues a controller soft reset and waits for the reset > bit to clear, but it ignores readl_poll_timeout()'s return value. > > If the controller never leaves reset, probe can continue to publish child > devices and system resume can report success without a usable RSB > controller. > > Return the timeout error, assert reset again, and disable the clock before > leaving the hardware-init path. > > Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn> Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com> Best regards, Jernej
diff --git a/drivers/bus/sunxi-rsb.c b/drivers/bus/sunxi-rsb.c index daf0ea563..f83224dea 100644 --- a/drivers/bus/sunxi-rsb.c +++ b/drivers/bus/sunxi-rsb.c @@ -669,8 +669,12 @@ static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) /* reset the controller */ writel(RSB_CTRL_SOFT_RST, rsb->regs + RSB_CTRL); - readl_poll_timeout(rsb->regs + RSB_CTRL, reg, - !(reg & RSB_CTRL_SOFT_RST), 1000, 100000); + ret = readl_poll_timeout(rsb->regs + RSB_CTRL, reg, + !(reg & RSB_CTRL_SOFT_RST), 1000, 100000); + if (ret) { + dev_err(dev, "soft reset timed out\n"); + goto err_reset_assert; + } /* * Clock frequency and delay calculation code is from @@ -696,6 +700,8 @@ static int sunxi_rsb_hw_init(struct sunxi_rsb *rsb) return 0; +err_reset_assert: + reset_control_assert(rsb->rstc); err_clk_disable: clk_disable_unprepare(rsb->clk);