Commit 5a6e8482 authored by Alex Deucher's avatar Alex Deucher Committed by Dave Airlie

drm/radeon/kms/atom: fix handling of FB scratch indices

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: default avatarAlex Deucher <alexander.deucher@amd.com>
Reported-by: default avatarDave Airlie <airlied@redhat.com>
Tested-by: default avatarDave Airlie <airlied@redhat.com>
Cc: stable@kernel.org
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent a4863ca9
...@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr, ...@@ -277,7 +277,12 @@ static uint32_t atom_get_src_int(atom_exec_context *ctx, uint8_t attr,
case ATOM_ARG_FB: case ATOM_ARG_FB:
idx = U8(*ptr); idx = U8(*ptr);
(*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) if (print)
DEBUG("FB[0x%02X]", idx); DEBUG("FB[0x%02X]", idx);
break; break;
...@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr, ...@@ -531,7 +536,11 @@ static void atom_put_dst(atom_exec_context *ctx, int arg, uint8_t attr,
case ATOM_ARG_FB: case ATOM_ARG_FB:
idx = U8(*ptr); idx = U8(*ptr);
(*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); DEBUG("FB[0x%02X]", idx);
break; break;
case ATOM_ARG_PLL: case ATOM_ARG_PLL:
...@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx) ...@@ -1370,11 +1379,13 @@ int atom_allocate_fb_scratch(struct atom_context *ctx)
usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024; usage_bytes = firmware_usage->asFirmwareVramReserveInfo[0].usFirmwareUseInKb * 1024;
} }
ctx->scratch_size_bytes = 0;
if (usage_bytes == 0) if (usage_bytes == 0)
usage_bytes = 20 * 1024; usage_bytes = 20 * 1024;
/* allocate some scratch memory */ /* allocate some scratch memory */
ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL); ctx->scratch = kzalloc(usage_bytes, GFP_KERNEL);
if (!ctx->scratch) if (!ctx->scratch)
return -ENOMEM; return -ENOMEM;
ctx->scratch_size_bytes = usage_bytes;
return 0; return 0;
} }
...@@ -137,6 +137,7 @@ struct atom_context { ...@@ -137,6 +137,7 @@ struct atom_context {
int cs_equal, cs_above; int cs_equal, cs_above;
int io_mode; int io_mode;
uint32_t *scratch; uint32_t *scratch;
int scratch_size_bytes;
}; };
extern int atom_debug; extern int atom_debug;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment