lkml.org 
[lkml]   [2020]   [Sep]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH AUTOSEL 5.4 143/330] drm/amd/display: dal_ddc_i2c_payloads_create can fail causing panic
    Date
    From: Aric Cyr <aric.cyr@amd.com>

    [ Upstream commit 6a6c4a4d459ecacc9013c45dcbf2bc9747fdbdbd ]

    [Why]
    Since the i2c payload allocation can fail need to check return codes

    [How]
    Clean up i2c payload allocations and check for errors

    Signed-off-by: Aric Cyr <aric.cyr@amd.com>
    Reviewed-by: Joshua Aberback <Joshua.Aberback@amd.com>
    Acked-by: Rodrigo Siqueira <Rodrigo.Siqueira@amd.com>
    Acked-by: Harry Wentland <harry.wentland@amd.com>
    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    .../gpu/drm/amd/display/dc/core/dc_link_ddc.c | 52 +++++++++----------
    1 file changed, 25 insertions(+), 27 deletions(-)

    diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
    index 51991bf26a93c..4c90d68db2307 100644
    --- a/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
    +++ b/drivers/gpu/drm/amd/display/dc/core/dc_link_ddc.c
    @@ -126,22 +126,16 @@ struct aux_payloads {
    struct vector payloads;
    };

    -static struct i2c_payloads *dal_ddc_i2c_payloads_create(struct dc_context *ctx, uint32_t count)
    +static bool dal_ddc_i2c_payloads_create(
    + struct dc_context *ctx,
    + struct i2c_payloads *payloads,
    + uint32_t count)
    {
    - struct i2c_payloads *payloads;
    -
    - payloads = kzalloc(sizeof(struct i2c_payloads), GFP_KERNEL);
    -
    - if (!payloads)
    - return NULL;
    -
    if (dal_vector_construct(
    &payloads->payloads, ctx, count, sizeof(struct i2c_payload)))
    - return payloads;
    -
    - kfree(payloads);
    - return NULL;
    + return true;

    + return false;
    }

    static struct i2c_payload *dal_ddc_i2c_payloads_get(struct i2c_payloads *p)
    @@ -154,14 +148,12 @@ static uint32_t dal_ddc_i2c_payloads_get_count(struct i2c_payloads *p)
    return p->payloads.count;
    }

    -static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads **p)
    +static void dal_ddc_i2c_payloads_destroy(struct i2c_payloads *p)
    {
    - if (!p || !*p)
    + if (!p)
    return;
    - dal_vector_destruct(&(*p)->payloads);
    - kfree(*p);
    - *p = NULL;

    + dal_vector_destruct(&p->payloads);
    }

    #define DDC_MIN(a, b) (((a) < (b)) ? (a) : (b))
    @@ -521,9 +513,13 @@ bool dal_ddc_service_query_ddc_data(

    uint32_t payloads_num = write_payloads + read_payloads;

    +
    if (write_size > EDID_SEGMENT_SIZE || read_size > EDID_SEGMENT_SIZE)
    return false;

    + if (!payloads_num)
    + return false;
    +
    /*TODO: len of payload data for i2c and aux is uint8!!!!,
    * but we want to read 256 over i2c!!!!*/
    if (dal_ddc_service_is_in_aux_transaction_mode(ddc)) {
    @@ -556,23 +552,25 @@ bool dal_ddc_service_query_ddc_data(

    ret = dc_link_aux_transfer_with_retries(ddc, &read_payload);
    } else {
    - struct i2c_payloads *payloads =
    - dal_ddc_i2c_payloads_create(ddc->ctx, payloads_num);
    + struct i2c_command command = {0};
    + struct i2c_payloads payloads;
    +
    + if (!dal_ddc_i2c_payloads_create(ddc->ctx, &payloads, payloads_num))
    + return false;

    - struct i2c_command command = {
    - .payloads = dal_ddc_i2c_payloads_get(payloads),
    - .number_of_payloads = 0,
    - .engine = DDC_I2C_COMMAND_ENGINE,
    - .speed = ddc->ctx->dc->caps.i2c_speed_in_khz };
    + command.payloads = dal_ddc_i2c_payloads_get(&payloads);
    + command.number_of_payloads = 0;
    + command.engine = DDC_I2C_COMMAND_ENGINE;
    + command.speed = ddc->ctx->dc->caps.i2c_speed_in_khz;

    dal_ddc_i2c_payloads_add(
    - payloads, address, write_size, write_buf, true);
    + &payloads, address, write_size, write_buf, true);

    dal_ddc_i2c_payloads_add(
    - payloads, address, read_size, read_buf, false);
    + &payloads, address, read_size, read_buf, false);

    command.number_of_payloads =
    - dal_ddc_i2c_payloads_get_count(payloads);
    + dal_ddc_i2c_payloads_get_count(&payloads);

    ret = dm_helpers_submit_i2c(
    ddc->ctx,
    --
    2.25.1
    \
     
     \ /
      Last update: 2020-09-18 05:06    [W:4.050 / U:0.308 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site