Received: by 2002:ad5:474a:0:0:0:0:0 with SMTP id i10csp16565imu; Wed, 2 Jan 2019 01:09:33 -0800 (PST) X-Google-Smtp-Source: ALg8bN7QAYSo4fqQ0EzbjB5uyD3jA1BFo5FzepoJUfBthYcpXjUhXl0L6BmoWqOnYyrzVK7CPwQZ X-Received: by 2002:a17:902:8607:: with SMTP id f7mr41723458plo.123.1546420173573; Wed, 02 Jan 2019 01:09:33 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1546420173; cv=none; d=google.com; s=arc-20160816; b=bme1oF7HY99t8kZguQPg6TNa/+AvnsG/HhH+xNgj/SbuugrtExzFANdLfk3H+u02cC 6lf4n31tICyhzyvEWQxJV1Gq39PQg0kzURPvNJ5CdBwDv6LmDUD2mU7JxM+RbKe8+xP/ pirhJ81UV0TGHWayETE1LY8lbiVtEYHR/wonUsnizs5KxoCFG4q/+43eyowss01kCOqg ECQL36e6auQSNWajs7NxIZn8wtatyT6++3Jy581fD2jhScOFVimVscuHS4nJc9GV0WUz Tjbpajc4GmcwGHWilZw1siProqHX7qhApfUP/H1H/n9z5xxG4pvRINYIeXFIfPwpOJ7o vnRw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from; bh=MrbWeOdf7KF1d7FVsYUAA4bVvtEEs4P4aXdgBJvKMsw=; b=m9vpfM94w1S2FrXqcYZdWghgbRkagNfbvMaOSjvLmdeZ/CAeFa8qY1OE+k3o9PLOUZ P53E/h+VkXpQY6BVxoJiDYSki/sQz+5KzNZkZEoU6TpOguHVSS6Hin1dTLmEMGwjM1f4 TH2dFcTwxs4LmpZ94x3fUE1a0x291pLU1oV0fnHeH041NlRDLMoQxtK3+YoVrBQMdV5a 8dlzQdV0uwn6AyTYa6u7AWimqLLUw/E4S7mQM/hVc/AT8+UTSHzsFixcKmYvPAZ948Hu NUznypMpIb+nwb0ejemayOmtZ0vuAJ36IEOtmnvyPSKqQM3zLrmhLdNfPXIE0QWroil7 RNkw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 31si14168656plz.263.2019.01.02.01.08.57; Wed, 02 Jan 2019 01:09:33 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728722AbfABIFI (ORCPT + 99 others); Wed, 2 Jan 2019 03:05:08 -0500 Received: from out1.zte.com.cn ([202.103.147.172]:36504 "EHLO mxct.zte.com.cn" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727799AbfABIFI (ORCPT ); Wed, 2 Jan 2019 03:05:08 -0500 Received: from mse01.zte.com.cn (unknown [10.30.3.20]) by Forcepoint Email with ESMTPS id 7BD6B711B2E03792D48B; Wed, 2 Jan 2019 16:04:58 +0800 (CST) Received: from notes_smtp.zte.com.cn ([10.30.1.239]) by mse01.zte.com.cn with ESMTP id x02808QX044007; Wed, 2 Jan 2019 16:00:08 +0800 (GMT-8) (envelope-from peng.hao2@zte.com.cn) Received: from localhost.localdomain.localdomain ([10.74.120.59]) by szsmtp06.zte.com.cn (Lotus Domino Release 8.5.3FP6) with ESMTP id 2019010216002997-20033780 ; Wed, 2 Jan 2019 16:00:29 +0800 From: Peng Hao To: qiang.zhao@nxp.com, leoyang.li@nxp.com Cc: linux-kernel@vger.kernel.org, Wen Yang , Julia Lawall , "David S. Miller" , netdev@vger.kernel.org, linuxppc-dev@lists.ozlabs.org Subject: [PATCH v5] soc/fsl/qe: fix err handling of ucc_of_parse_tdm Date: Thu, 3 Jan 2019 00:23:43 +0800 Message-Id: <1546446223-17184-1-git-send-email-peng.hao2@zte.com.cn> X-Mailer: git-send-email 1.8.3.1 X-MIMETrack: Itemize by SMTP Server on SZSMTP06/server/zte_ltd(Release 8.5.3FP6|November 21, 2013) at 2019-01-02 16:00:30, Serialize by Router on notes_smtp/zte_ltd(Release 9.0.1FP7|August 17, 2016) at 2019-01-02 16:00:00, Serialize complete at 2019-01-02 16:00:00 X-MAIL: mse01.zte.com.cn x02808QX044007 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Wen Yang Currently there are some issues with the ucc_of_parse_tdm function: 1, a possible null pointer dereference in ucc_of_parse_tdm, detected by the semantic patch deref_null.cocci, with the following warning: drivers/soc/fsl/qe/qe_tdm.c:177:21-24: ERROR: pdev is NULL but dereferenced. 2, dev gets modified, so in any case that devm_iounmap() will fail even when the new pdev is valid, because the iomap was done with a different pdev. 3, there is no driver bind with the "fsl,t1040-qe-si" or "fsl,t1040-qe-siram" device. So allocating resources using devm_*() with these devices won't provide a cleanup path for these resources when the caller fails. This patch fixes them. Suggested-by: Li Yang Suggested-by: Christophe LEROY Signed-off-by: Wen Yang Reviewed-by: Peng Hao CC: Julia Lawall CC: Zhao Qiang CC: David S. Miller CC: netdev@vger.kernel.org CC: linuxppc-dev@lists.ozlabs.org CC: linux-kernel@vger.kernel.org --- drivers/net/wan/fsl_ucc_hdlc.c | 62 +++++++++++++++++++++++++++++++++++++++++- drivers/soc/fsl/qe/qe_tdm.c | 55 ------------------------------------- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 839fa77..f30a040 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -1057,6 +1057,54 @@ static const struct net_device_ops uhdlc_ops = { .ndo_tx_timeout = uhdlc_tx_timeout, }; +static int hdlc_map_iomem(char *name, int init_flag, void __iomem **ptr) +{ + struct device_node *np; + struct platform_device *pdev; + struct resource *res; + static int siram_init_flag; + int ret = 0; + + np = of_find_compatible_node(NULL, NULL, name); + if (!np) + return -EINVAL; + + pdev = of_find_device_by_node(np); + if (!pdev) { + pr_err("%pOFn: failed to lookup pdev\n", np); + of_node_put(np); + return -EINVAL; + } + + of_node_put(np); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -EINVAL; + goto error_put_device; + } + *ptr = ioremap(res->start, resource_size(res)); + if (!*ptr) { + ret = -ENOMEM; + goto error_put_device; + } + + /* We've remapped the addresses, and we don't need the device any + * more, so we should release it. + */ + put_device(&pdev->dev); + + if (init_flag && siram_init_flag == 0) { + memset_io(*ptr, 0, resource_size(res)); + siram_init_flag = 1; + } + return 0; + +error_put_device: + put_device(&pdev->dev); + + return ret; +} + static int ucc_hdlc_probe(struct platform_device *pdev) { struct device_node *np = pdev->dev.of_node; @@ -1151,6 +1199,15 @@ static int ucc_hdlc_probe(struct platform_device *pdev) ret = ucc_of_parse_tdm(np, utdm, ut_info); if (ret) goto free_utdm; + + ret = hdlc_map_iomem("fsl,t1040-qe-si", 0, + (void __iomem **)&utdm->si_regs); + if (ret) + goto free_utdm; + ret = hdlc_map_iomem("fsl,t1040-qe-siram", 1, + (void __iomem **)&utdm->siram); + if (ret) + goto unmap_si_regs; } if (of_property_read_u16(np, "fsl,hmask", &uhdlc_priv->hmask)) @@ -1159,7 +1216,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) ret = uhdlc_init(uhdlc_priv); if (ret) { dev_err(&pdev->dev, "Failed to init uhdlc\n"); - goto free_utdm; + goto undo_uhdlc_init; } dev = alloc_hdlcdev(uhdlc_priv); @@ -1188,6 +1245,9 @@ static int ucc_hdlc_probe(struct platform_device *pdev) free_dev: free_netdev(dev); undo_uhdlc_init: + iounmap(utdm->siram); +unmap_si_regs: + iounmap(utdm->si_regs); free_utdm: if (uhdlc_priv->tsa) kfree(utdm); diff --git a/drivers/soc/fsl/qe/qe_tdm.c b/drivers/soc/fsl/qe/qe_tdm.c index f78c346..76480df 100644 --- a/drivers/soc/fsl/qe/qe_tdm.c +++ b/drivers/soc/fsl/qe/qe_tdm.c @@ -44,10 +44,6 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm, const char *sprop; int ret = 0; u32 val; - struct resource *res; - struct device_node *np2; - static int siram_init_flag; - struct platform_device *pdev; sprop = of_get_property(np, "fsl,rx-sync-clock", NULL); if (sprop) { @@ -124,57 +120,6 @@ int ucc_of_parse_tdm(struct device_node *np, struct ucc_tdm *utdm, utdm->siram_entry_id = val; set_si_param(utdm, ut_info); - - np2 = of_find_compatible_node(NULL, NULL, "fsl,t1040-qe-si"); - if (!np2) - return -EINVAL; - - pdev = of_find_device_by_node(np2); - if (!pdev) { - pr_err("%pOFn: failed to lookup pdev\n", np2); - of_node_put(np2); - return -EINVAL; - } - - of_node_put(np2); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - utdm->si_regs = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(utdm->si_regs)) { - ret = PTR_ERR(utdm->si_regs); - goto err_miss_siram_property; - } - - np2 = of_find_compatible_node(NULL, NULL, "fsl,t1040-qe-siram"); - if (!np2) { - ret = -EINVAL; - goto err_miss_siram_property; - } - - pdev = of_find_device_by_node(np2); - if (!pdev) { - ret = -EINVAL; - pr_err("%pOFn: failed to lookup pdev\n", np2); - of_node_put(np2); - goto err_miss_siram_property; - } - - of_node_put(np2); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - utdm->siram = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(utdm->siram)) { - ret = PTR_ERR(utdm->siram); - goto err_miss_siram_property; - } - - if (siram_init_flag == 0) { - memset_io(utdm->siram, 0, resource_size(res)); - siram_init_flag = 1; - } - - return ret; - -err_miss_siram_property: - devm_iounmap(&pdev->dev, utdm->si_regs); return ret; } EXPORT_SYMBOL(ucc_of_parse_tdm); -- 2.9.5