summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorDave Airlie <[email protected]>2019-04-04 11:18:26 +1000
committerDave Airlie <[email protected]>2019-04-05 09:57:44 +1000
commit0ea386128b8fe4a4c0dc32101c4d4dd565723341 (patch)
treeae0745ae9556005c513335b2e8694a982fc52ff4 /src/gallium/drivers
parent42f63e6334c925f0eb11805f8b9279e4f449d976 (diff)
iris: avoid use after free in shader destruction
While playing with compute shaders, I was getting a random crash, noticed that bind_state was using the old shader info for comparision, but gallium allows the shader to be deleted while bound, so this could lead to a use after free. This can't happen using the cso cache. As it tracks all of this. Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/iris/iris_program.c56
1 files changed, 49 insertions, 7 deletions
diff --git a/src/gallium/drivers/iris/iris_program.c b/src/gallium/drivers/iris/iris_program.c
index ebddcc2fb58..3ac917c6e76 100644
--- a/src/gallium/drivers/iris/iris_program.c
+++ b/src/gallium/drivers/iris/iris_program.c
@@ -1620,14 +1620,56 @@ iris_create_compute_state(struct pipe_context *ctx,
* Frees the iris_uncompiled_shader.
*/
static void
-iris_delete_shader_state(struct pipe_context *ctx, void *state)
+iris_delete_shader_state(struct pipe_context *ctx, void *state, gl_shader_stage stage)
{
struct iris_uncompiled_shader *ish = state;
+ struct iris_context *ice = (void *) ctx;
+
+ if (ice->shaders.uncompiled[stage] == ish) {
+ ice->shaders.uncompiled[stage] = NULL;
+ ice->state.dirty |= IRIS_DIRTY_UNCOMPILED_VS << stage;
+ }
ralloc_free(ish->nir);
free(ish);
}
+static void
+iris_delete_vs_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_VERTEX);
+}
+
+static void
+iris_delete_tcs_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_TESS_CTRL);
+}
+
+static void
+iris_delete_tes_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_TESS_EVAL);
+}
+
+static void
+iris_delete_gs_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_GEOMETRY);
+}
+
+static void
+iris_delete_fs_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_FRAGMENT);
+}
+
+static void
+iris_delete_cs_state(struct pipe_context *ctx, void *state)
+{
+ iris_delete_shader_state(ctx, state, MESA_SHADER_COMPUTE);
+}
+
/**
* The pipe->bind_[stage]_state() driver hook.
*
@@ -1737,12 +1779,12 @@ iris_init_program_functions(struct pipe_context *ctx)
ctx->create_fs_state = iris_create_fs_state;
ctx->create_compute_state = iris_create_compute_state;
- ctx->delete_vs_state = iris_delete_shader_state;
- ctx->delete_tcs_state = iris_delete_shader_state;
- ctx->delete_tes_state = iris_delete_shader_state;
- ctx->delete_gs_state = iris_delete_shader_state;
- ctx->delete_fs_state = iris_delete_shader_state;
- ctx->delete_compute_state = iris_delete_shader_state;
+ ctx->delete_vs_state = iris_delete_vs_state;
+ ctx->delete_tcs_state = iris_delete_tcs_state;
+ ctx->delete_tes_state = iris_delete_tes_state;
+ ctx->delete_gs_state = iris_delete_gs_state;
+ ctx->delete_fs_state = iris_delete_fs_state;
+ ctx->delete_compute_state = iris_delete_cs_state;
ctx->bind_vs_state = iris_bind_vs_state;
ctx->bind_tcs_state = iris_bind_tcs_state;