Function behaves like alloc_spu_context() but instead of current-> init
task's informations are used and the problem state bit is removed.

Signed-off-by: Sebastian Siewior <[EMAIL PROTECTED]>
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -32,7 +32,8 @@
 
 atomic_t nr_spu_contexts = ATOMIC_INIT(0);
 
-struct spu_context *alloc_spu_context(struct spu_gang *gang)
+static struct spu_context *__alloc_spu_context(struct spu_gang *gang,
+               struct mm_struct *mm)
 {
        struct spu_context *ctx;
        ctx = kzalloc(sizeof *ctx, GFP_KERNEL);
@@ -54,7 +55,7 @@ struct spu_context *alloc_spu_context(st
        init_waitqueue_head(&ctx->mfc_wq);
        ctx->state = SPU_STATE_SAVED;
        ctx->ops = &spu_backing_ops;
-       ctx->owner = get_task_mm(current);
+       ctx->owner = mm;
        INIT_LIST_HEAD(&ctx->rq);
        INIT_LIST_HEAD(&ctx->aff_list);
        if (gang)
@@ -73,6 +74,37 @@ out:
        return ctx;
 }
 
+struct spu_context *alloc_spu_context(struct spu_gang *gang)
+{
+       struct mm_struct *mm;
+       struct spu_context *ctx;
+
+       mm = get_task_mm(current);
+       ctx = __alloc_spu_context(gang, mm);
+       if (!ctx)
+               mmput(mm);
+       return ctx;
+}
+
+struct spu_context *kspu_alloc_context(void)
+{
+       struct spu_context *ctx;
+
+       /* for priviliged spu context, we borrow all the task specific
+        * informations from init_task.
+        */
+       atomic_inc(&init_mm.mm_users);
+       ctx = __alloc_spu_context(NULL, &init_mm);
+       if (!ctx) {
+               mmput(&init_mm);
+               return ctx;
+       }
+
+       /* remove problem state bit in order to access kernel memory */
+       ctx->csa.priv1.mfc_sr1_RW &= ~MFC_STATE1_PROBLEM_STATE_MASK;
+       return ctx;
+}
+
 void destroy_spu_context(struct kref *kref)
 {
        struct spu_context *ctx;
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -232,6 +232,7 @@ static inline void spu_release(struct sp
 }
 
 struct spu_context * alloc_spu_context(struct spu_gang *gang);
+struct spu_context *kspu_alloc_context(void);
 void destroy_spu_context(struct kref *kref);
 struct spu_context * get_spu_context(struct spu_context *ctx);
 int put_spu_context(struct spu_context *ctx);

-- 

-
To unsubscribe from this list: send the line "unsubscribe linux-crypto" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to