diff options
author | Arnd Bergmann <arnd@arndb.de> | 2006-11-20 18:45:08 +0100 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2006-12-04 20:40:02 +1100 |
commit | ee2d7340cbf3b123e1c3b7454f3e2b7e65d33bb2 (patch) | |
tree | 2953689e0efdb35195e46c75148bfb91030f71fa /arch/powerpc/platforms/cell/spufs/inode.c | |
parent | 3692dc66149dc17cd82ec785a06478322c0eddff (diff) |
[POWERPC] spufs: Use SPU master control to prevent wild SPU execution
When the user changes the runcontrol register, an SPU might be
running without a process being attached to it and waiting for
events. In order to prevent this, make sure we always disable
the priv1 master control when we're not inside of spu_run.
Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/platforms/cell/spufs/inode.c')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/inode.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index 9e457be140e..1fbcc536924 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c @@ -248,8 +248,13 @@ static int spu_setup_isolated(struct spu_context *ctx) if (!isolated_loader) return -ENODEV; - if ((ret = spu_acquire_exclusive(ctx)) != 0) - return ret; + /* prevent concurrent operation with spu_run */ + down(&ctx->run_sema); + ctx->ops->master_start(ctx); + + ret = spu_acquire_exclusive(ctx); + if (ret) + goto out; mfc_cntl = &ctx->spu->priv2->mfc_control_RW; @@ -315,12 +320,14 @@ out_drop_priv: out_unlock: spu_release_exclusive(ctx); +out: + ctx->ops->master_stop(ctx); + up(&ctx->run_sema); return ret; } int spu_recycle_isolated(struct spu_context *ctx) { - ctx->ops->runcntl_stop(ctx); return spu_setup_isolated(ctx); } @@ -435,6 +442,8 @@ out: if (ret >= 0 && (flags & SPU_CREATE_ISOLATE)) { int setup_err = spu_setup_isolated( SPUFS_I(dentry->d_inode)->i_ctx); + /* FIXME: clean up context again on failure to avoid + leak. */ if (setup_err) ret = setup_err; } |