aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2006-01-04 14:31:21 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-08 23:44:35 -0500
commit762cf6dac2623473e83bb271f2bbe97d2355c64d (patch)
tree51871b65240062fc9442965923f710f0782b4e34 /arch
parentc902be71dc6d5e8473bd021feafc8c3608e2b82a (diff)
[PATCH] spufs: fix locking in spu_acquire_runnable
We need to check for validity of owner under down_write, down_read is not enough. Noticed by Al Viro. Signed-off-by: Arnd Bergmann <arndb@de.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 1758cec58bc7..903c35d19577 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -120,27 +120,29 @@ int spu_acquire_runnable(struct spu_context *ctx)
120 ctx->spu->prio = current->prio; 120 ctx->spu->prio = current->prio;
121 return 0; 121 return 0;
122 } 122 }
123 up_read(&ctx->state_sema);
124
125 down_write(&ctx->state_sema);
123 /* ctx is about to be freed, can't acquire any more */ 126 /* ctx is about to be freed, can't acquire any more */
124 if (!ctx->owner) { 127 if (!ctx->owner) {
125 ret = -EINVAL; 128 ret = -EINVAL;
126 goto out; 129 goto out;
127 } 130 }
128 up_read(&ctx->state_sema);
129 131
130 down_write(&ctx->state_sema);
131 if (ctx->state == SPU_STATE_SAVED) { 132 if (ctx->state == SPU_STATE_SAVED) {
132 ret = spu_activate(ctx, 0); 133 ret = spu_activate(ctx, 0);
133 ctx->state = SPU_STATE_RUNNABLE; 134 ctx->state = SPU_STATE_RUNNABLE;
134 } 135 }
135 downgrade_write(&ctx->state_sema);
136 if (ret) 136 if (ret)
137 goto out; 137 goto out;
138 138
139 downgrade_write(&ctx->state_sema);
139 /* On success, we return holding the lock */ 140 /* On success, we return holding the lock */
141
140 return ret; 142 return ret;
141out: 143out:
142 /* Release here, to simplify calling code. */ 144 /* Release here, to simplify calling code. */
143 up_read(&ctx->state_sema); 145 up_write(&ctx->state_sema);
144 146
145 return ret; 147 return ret;
146} 148}