lkml.org 
[lkml]   [2011]   [Oct]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[06/27] drm/radeon/kms/atom: fix handling of FB scratch indices
    3.0-stable review patch.  If anyone has any objections, please let us know.

    ------------------

    From: Alex Deucher <alexander.deucher@amd.com>

    commit 5a6e8482a16e61250a9121fc9ec719ab0529e760 upstream.

    FB scratch indices are dword indices, but we were treating
    them as byte indices. As such, we were getting the wrong
    FB scratch data for non-0 indices. Fix the indices and
    guard the indexing against indices larger than the scratch
    allocation.

    Fixes memory corruption on some boards if data was written
    past the end of the FB scratch array.

    Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
    Reported-by: Dave Airlie <airlied@redhat.com>
    Tested-by: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Dave Airlie <airlied@redhat.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

    ---
    drivers/gpu/drm/radeon/atom.c | 15 +++++++++++++--
    drivers/gpu/drm/radeon/atom.h | 1 +
    2 files changed, 14 insertions(+), 2 deletions(-)

    --- a/drivers/gpu/drm/radeon/atom.c
    +++ b/drivers/gpu/drm/radeon/atom.c
    @@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_ex
    case ATOM_ARG_FB:
    idx = U8(*ptr);
    (*ptr)++;
    - val = gctx->scratch[((gctx->fb_base + idx) / 4)];
    + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
    + DRM_ERROR("ATOM: fb read beyond scratch region: %d vs. %d\n",
    + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
    + val = 0;
    + } else
    + val = gctx->scratch[(gctx->fb_base / 4) + idx];
    if (print)
    DEBUG("FB[0x%02X]", idx);
    break;
    @@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_conte
    case ATOM_ARG_FB:
    idx = U8(*ptr);
    (*ptr)++;
    - gctx->scratch[((gctx->fb_base + idx) / 4)] = val;
    + if ((gctx->fb_base + (idx * 4)) > gctx->scratch_size_bytes) {
    + DRM_ERROR("ATOM: fb write beyond scratch region: %d vs. %d\n",
    + gctx->fb_base + (idx * 4), gctx->scratch_size_bytes);
    + } else
    + gctx->scratch[(gctx->fb_base / 4) + idx] = val;
    DEBUG("FB[0x%02X]", idx);
    break;
    case ATOM_ARG_PLL:
    @@ -1367,11 +1376,13 @@ int atom_allocate_fb_scratch(struct atom

    usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
    }
    + ctx->scratch_size_bytes = 0;
    if (usage_bytes == 0)
    usage_bytes = 20 * 1024;
    /* allocate some scratch memory */
    ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
    if (!ctx->scratch)
    return -ENOMEM;
    + ctx->scratch_size_bytes = usage_bytes;
    return 0;
    }
    --- a/drivers/gpu/drm/radeon/atom.h
    +++ b/drivers/gpu/drm/radeon/atom.h
    @@ -137,6 +137,7 @@ struct atom_context {
    int cs_equal, cs_above;
    int io_mode;
    uint32_t *scratch;
    + int scratch_size_bytes;
    };

    extern int atom_debug;



    \
     
     \ /
      Last update: 2011-10-23 08:37    [W:0.026 / U:1.148 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site