video: tegra: host: Fix error paths in user hwctx
Terje Bergstrom [Mon, 4 Mar 2013 07:31:55 +0000 (09:31 +0200)]
Plug the unhandled error paths in code that sets a new context save /
restore sequence.

Change-Id: I5fd70c3e337f72414c38302a70336356352d06da
Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com>
Reviewed-on: http://git-master/r/205843
Reviewed-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-by: Automatic_Commit_Validation_User
Reviewed-by: Juha Tukkinen <jtukkinen@nvidia.com>

drivers/video/tegra/host/bus_client.c
drivers/video/tegra/host/user_hwctx.c
drivers/video/tegra/host/user_hwctx.h

index 13fdda7..ba2397c 100644 (file)
@@ -581,8 +581,10 @@ static int nvhost_ioctl_channel_set_ctxswitch(
        }
 
        nhwctx = ctxhandler->alloc(ctxhandler, ctx->ch);
-       if (!nhwctx)
-               return -ENOMEM;
+       if (!nhwctx) {
+               err = -ENOMEM;
+               goto fail_hwctx;
+       }
        hwctx = to_user_hwctx(nhwctx);
 
        trace_nvhost_ioctl_channel_set_ctxswitch(ctx->ch->dev->name, nhwctx,
@@ -593,11 +595,15 @@ static int nvhost_ioctl_channel_set_ctxswitch(
                        save_incr.syncpt_incrs, restore_incr.syncpt_incrs);
 
        nhwctx->memmgr = ctx->hwctx->memmgr;
-       user_hwctx_set_restore(hwctx, cmdbuf_restore.mem,
+       err = user_hwctx_set_restore(hwctx, cmdbuf_restore.mem,
                        cmdbuf_restore.offset, cmdbuf_restore.words);
+       if (err)
+               goto fail_set_restore;
 
-       user_hwctx_set_save(hwctx, cmdbuf_save.mem,
+       err = user_hwctx_set_save(hwctx, cmdbuf_save.mem,
                        cmdbuf_save.offset, cmdbuf_save.words, &reloc);
+       if (err)
+               goto fail_set_save;
 
        hwctx->hwctx.save_incrs = save_incr.syncpt_incrs;
        hwctx->hwctx.restore_incrs = restore_incr.syncpt_incrs;
@@ -608,6 +614,11 @@ static int nvhost_ioctl_channel_set_ctxswitch(
 
        return 0;
 
+fail_set_save:
+fail_set_restore:
+       ctxhandler->put(&hwctx->hwctx);
+fail_hwctx:
+       user_ctxhandler_free(ctxhandler);
 fail:
        return err;
 }
index 74d229f..104e105 100644 (file)
@@ -56,7 +56,7 @@ static void user_hwctx_free(struct kref *ref)
                container_of(ref, struct nvhost_hwctx, ref);
        struct user_hwctx *uhwctx = to_user_hwctx(hwctx);
 
-       kfree(to_user_hwctx_handler(hwctx->h));
+       user_ctxhandler_free(hwctx->h);
 
        if (uhwctx->save_sgt)
                nvhost_memmgr_unpin(hwctx->memmgr,
@@ -186,3 +186,8 @@ struct nvhost_hwctx_handler *user_ctxhandler_init(u32 syncpt,
 
        return &p->h;
 }
+
+void user_ctxhandler_free(struct nvhost_hwctx_handler *h)
+{
+       kfree(to_user_hwctx_handler(h));
+}
index 854eb90..22ef63d 100644 (file)
@@ -57,6 +57,7 @@ struct user_hwctx_handler {
 
 struct nvhost_hwctx_handler *user_ctxhandler_init(u32 syncpt,
                u32 waitbase, struct nvhost_channel *ch);
+void user_ctxhandler_free(struct nvhost_hwctx_handler *h);
 int user_hwctx_set_restore(struct user_hwctx *ctx,
                u32 mem, u32 offset, u32 words);
 int user_hwctx_set_save(struct user_hwctx *ctx,