DF-1542 / fix.diff
diff --git a/sys/dev/drm/amd/amdgpu/atom.c b/sys/dev/drm/amd/amdgpu/atom.c --- a/sys/dev/drm/amd/amdgpu/atom.c +++ b/sys/dev/drm/amd/amdgpu/atom.c @@ -60,10 +60,12 @@ unsigned last_jump; unsigned long last_jump_jiffies; bool abort; + int recursion_depth; } atom_exec_context; int amdgpu_atom_debug = 0; -static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params); +static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, + uint32_t * params, int recursion_depth); static uint32_t atom_arg_mask[8] = { 0xFFFFFFFF, 0xFFFF, 0xFFFF00, 0xFFFF0000, 0xFF, 0xFF00, 0xFF0000, @@ -617,7 +619,8 @@ else SDEBUG(" table: %d\n", idx); if (U16(ctx->ctx->cmd_table + 4 + 2 * idx)) - r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift); + r = amdgpu_atom_execute_table_locked(ctx->ctx, idx, ctx->ps + ctx->ps_shift, + ctx->recursion_depth + 1); if (r) { ctx->abort = true; } @@ -1195,7 +1198,8 @@ atom_op_div32, ATOM_ARG_WS}, }; -static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, uint32_t * params) +static int amdgpu_atom_execute_table_locked(struct atom_context *ctx, int index, + uint32_t * params, int recursion_depth) { int base = CU16(ctx->cmd_table + 4 + 2 * index); int len, ws, ps, ptr; @@ -1203,6 +1207,9 @@ atom_exec_context ectx; int ret = 0; + if (recursion_depth > 20) + return -EINVAL; + if (!base) return -EINVAL; @@ -1272,7 +1279,7 @@ /* reset divmul */ ctx->divmul[0] = 0; ctx->divmul[1] = 0; - r = amdgpu_atom_execute_table_locked(ctx, index, params); + r = amdgpu_atom_execute_table_locked(ctx, index, params, 0); mutex_unlock(&ctx->mutex); return r; } |