From: ChunYuZhiQiang When the FlexCAN interface is down, can_fill_info() still calls flexcan_get_berr_counter() to fill the error counters for a netlink dump. This function calls pm_runtime_resume_and_get(), which only enables the clocks via flexcan_runtime_resume(), but does not clear the MCR[MDIS] bit. Since the interface has never been opened, the FlexCAN module is still disabled (MDIS=1) from register_flexcandev(). Accessing the ECR register then triggers a synchronous external abort. This can be reproduced on an i.MX8QXP board by simply running `ip link show` without ever bringing the CAN interface up: Internal error: synchronous external abort: 0000000096000210 [#1] PREEMPT SMP pc : flexcan_read_le+0x0/0x18 lr : flexcan_get_berr_counter+0x4c/0x8c Call trace: flexcan_read_le+0x0/0x18 can_fill_info+0x1f8/0x434 rtnl_fill_ifinfo+0x8fc/0xbb4 rtnl_dump_ifinfo+0x364/0x448 ... ftrace shows the exact path: can_fill_info() { flexcan_get_berr_counter() { __pm_runtime_resume() { rpm_resume() rpm_callback() __rpm_callback() pm_generic_runtime_resume() flexcan_runtime_resume() flexcan_clks_enable() { clk_prepare(); clk_enable(); ... } } do_mem_abort() { do_sea() ... } } } Fix this by returning early if the interface is not running. Tested on i.MX8QXP: after the patch, `ip link show` no longer triggers the abort. Cc: stable@vger.kernel.org Signed-off-by: ChunYuZhiQiang --- drivers/net/can/flexcan/flexcan-core.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/net/can/flexcan/flexcan-core.c b/drivers/net/can/flexcan/flexcan-core.c index 06d5d35fc..b08779ee2 100644 --- a/drivers/net/can/flexcan/flexcan-core.c +++ b/drivers/net/can/flexcan/flexcan-core.c @@ -765,6 +765,9 @@ static int flexcan_get_berr_counter(const struct net_device *dev, const struct flexcan_priv *priv = netdev_priv(dev); int err; + if (!netif_running(dev)) + return 0; + err = pm_runtime_resume_and_get(priv->dev); if (err < 0) return err; -- 2.47.3