lkml.org 
[lkml]   [2022]   [Jun]   [27]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 127/135] memory: samsung: exynos5422-dmc: Fix refcount leak in of_get_dram_timings
    Date
    From: Miaoqian Lin <linmq006@gmail.com>

    commit 1332661e09304b7b8e84e5edc11811ba08d12abe upstream.

    of_parse_phandle() returns a node pointer with refcount
    incremented, we should use of_node_put() on it when not need anymore.
    This function doesn't call of_node_put() in some error paths.
    To unify the structure, Add put_node label and goto it on errors.

    Fixes: 6e7674c3c6df ("memory: Add DMC driver for Exynos5422")
    Signed-off-by: Miaoqian Lin <linmq006@gmail.com>
    Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
    Link: https://lore.kernel.org/r/20220602041721.64348-1-linmq006@gmail.com
    Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/memory/samsung/exynos5422-dmc.c | 29 ++++++++++++++++++-----------
    1 file changed, 18 insertions(+), 11 deletions(-)

    --- a/drivers/memory/samsung/exynos5422-dmc.c
    +++ b/drivers/memory/samsung/exynos5422-dmc.c
    @@ -1187,33 +1187,39 @@ static int of_get_dram_timings(struct ex

    dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
    sizeof(u32), GFP_KERNEL);
    - if (!dmc->timing_row)
    - return -ENOMEM;
    + if (!dmc->timing_row) {
    + ret = -ENOMEM;
    + goto put_node;
    + }

    dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
    sizeof(u32), GFP_KERNEL);
    - if (!dmc->timing_data)
    - return -ENOMEM;
    + if (!dmc->timing_data) {
    + ret = -ENOMEM;
    + goto put_node;
    + }

    dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
    sizeof(u32), GFP_KERNEL);
    - if (!dmc->timing_power)
    - return -ENOMEM;
    + if (!dmc->timing_power) {
    + ret = -ENOMEM;
    + goto put_node;
    + }

    dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev,
    DDR_TYPE_LPDDR3,
    &dmc->timings_arr_size);
    if (!dmc->timings) {
    - of_node_put(np_ddr);
    dev_warn(dmc->dev, "could not get timings from DT\n");
    - return -EINVAL;
    + ret = -EINVAL;
    + goto put_node;
    }

    dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev);
    if (!dmc->min_tck) {
    - of_node_put(np_ddr);
    dev_warn(dmc->dev, "could not get tck from DT\n");
    - return -EINVAL;
    + ret = -EINVAL;
    + goto put_node;
    }

    /* Sorted array of OPPs with frequency ascending */
    @@ -1227,13 +1233,14 @@ static int of_get_dram_timings(struct ex
    clk_period_ps);
    }

    - of_node_put(np_ddr);

    /* Take the highest frequency's timings as 'bypass' */
    dmc->bypass_timing_row = dmc->timing_row[idx - 1];
    dmc->bypass_timing_data = dmc->timing_data[idx - 1];
    dmc->bypass_timing_power = dmc->timing_power[idx - 1];

    +put_node:
    + of_node_put(np_ddr);
    return ret;
    }


    \
     
     \ /
      Last update: 2022-06-27 13:46    [W:4.129 / U:0.176 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site