[POWERPC] spufs: streamline locking for isolated spu setup
[powerpc.git] / arch / powerpc / platforms / cell / spufs / run.c
index f95a611..7df5202 100644 (file)
@@ -63,13 +63,18 @@ static int spu_setup_isolated(struct spu_context *ctx)
        const u32 status_loading = SPU_STATUS_RUNNING
                | SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS;
 
+       ret = -ENODEV;
        if (!isolated_loader)
-               return -ENODEV;
-
-       ret = spu_acquire_exclusive(ctx);
-       if (ret)
                goto out;
 
+       /*
+        * We need to exclude userspace access to the context.
+        *
+        * To protect against memory access we invalidate all ptes
+        * and make sure the pagefault handlers block on the mutex.
+        */
+       spu_unmap_mappings(ctx);
+
        mfc_cntl = &ctx->spu->priv2->mfc_control_RW;
 
        /* purge the MFC DMA queue to ensure no spurious accesses before we
@@ -82,7 +87,7 @@ static int spu_setup_isolated(struct spu_context *ctx)
                        printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n",
                                        __FUNCTION__);
                        ret = -EIO;
-                       goto out_unlock;
+                       goto out;
                }
                cond_resched();
        }
@@ -119,12 +124,15 @@ static int spu_setup_isolated(struct spu_context *ctx)
                pr_debug("%s: isolated LOAD failed\n", __FUNCTION__);
                ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
                ret = -EACCES;
+               goto out_drop_priv;
+       }
 
-       } else if (!(status & SPU_STATUS_ISOLATED_STATE)) {
+       if (!(status & SPU_STATUS_ISOLATED_STATE)) {
                /* This isn't allowed by the CBEA, but check anyway */
                pr_debug("%s: SPU fell out of isolated mode?\n", __FUNCTION__);
                ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_STOP);
                ret = -EINVAL;
+               goto out_drop_priv;
        }
 
 out_drop_priv:
@@ -132,8 +140,6 @@ out_drop_priv:
        sr1 |= MFC_STATE1_PROBLEM_STATE_MASK;
        spu_mfc_sr1_set(ctx->spu, sr1);
 
-out_unlock:
-       spu_release(ctx);
 out:
        return ret;
 }
@@ -149,13 +155,9 @@ static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
 
        if (ctx->flags & SPU_CREATE_ISOLATE) {
                if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
-                       /* Need to release ctx, because spu_setup_isolated will
-                        * acquire it exclusively.
-                        */
-                       spu_release(ctx);
                        ret = spu_setup_isolated(ctx);
-                       if (!ret)
-                               ret = spu_acquire_runnable(ctx, 0);
+                       if (ret)
+                               spu_release(ctx);
                }
 
                /* if userspace has set the runcntrl register (eg, to issue an