[Cbe-oss-dev] [patch 3/3] cell: prevent alignment interrupt on local store

Akinobu Mita mita at fixstars.com
Wed Apr 11 13:06:56 EST 2007


On Tue, Apr 10, 2007 at 02:52:33PM +0200, Segher Boessenkool wrote:
> >An Alignment interrupt occurs when the instruction is lmw, stmw, lswi, 
> >lswx,
> >stswi, or stswx, and the operand is in local store.
> >
> >GCC generated such instructions to handle memcpy() instead of kernel
> >defined memcpy() without -mno-string option.
> 
> >+# An Alignment interrupt occurs when the instruction is lmw, stmw, 
> >lswi, lswx,
> >+# stswi, or stswx, and the operand is in local store.
> >+CFLAGS_run.o := -mno-string
> >+CFLAGS_file.o := -mno-string
> 
> NAK.  Please use memcpy_fromio() and friends instead,
> that's what they're there for.  I believe Arnd was working
> on this?
> 
> Your patch is only a partial solution, you'd need -mno-multiple
> -mno-algebraic -mno-dcbz too (and two of those don't even
> exist).

This is the patch which fix the problem with using memcpy_fromio/toio()
on LS. It seems better than adding many -mno-* options to specific
files.

From: Akinobu Mita <mita at fixstars.com>
Subject: spufs: use memcpy_fromio() to copy from local store

GCC may generates inline copy loop to handle memcpy() function
instead of kernel defined memcpy(). But this inlined version of memcpy()
causes an alignment interrupt when copying from local store.

This patch uses memcpy_fromio() and memcpy_toio to copy local store
to prevent memcpy() being inlined.

Signed-off-by: Akinobu Mita <mita at fixstars.com>

---
 arch/powerpc/platforms/cell/spufs/run.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

Index: 2.6-git-ps3/arch/powerpc/platforms/cell/spufs/run.c
===================================================================
--- 2.6-git-ps3.orig/arch/powerpc/platforms/cell/spufs/run.c
+++ 2.6-git-ps3/arch/powerpc/platforms/cell/spufs/run.c
@@ -260,10 +260,10 @@ int spu_process_callback(struct spu_cont
 	/* get syscall block from local store */
 	npc = ctx->ops->npc_read(ctx);
 	ls = ctx->ops->get_ls(ctx);
-	ls_pointer = *(u32*)(ls + npc);
+	ls_pointer = *(u32 *)(ls + npc);
 	if (ls_pointer > (LS_SIZE - sizeof(s)))
 		return -EFAULT;
-	memcpy(&s, ls + ls_pointer, sizeof (s));
+	memcpy_fromio(&s, ls + ls_pointer, sizeof(s));
 
 	/* do actual syscall without pinning the spu */
 	ret = 0;
@@ -283,7 +283,7 @@ int spu_process_callback(struct spu_cont
 	}
 
 	/* write result, jump over indirect pointer */
-	memcpy(ls + ls_pointer, &spu_ret, sizeof (spu_ret));
+	memcpy_toio(ls + ls_pointer, &spu_ret, sizeof(spu_ret));
 	ctx->ops->npc_write(ctx, npc);
 	ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
 	return ret;



More information about the cbe-oss-dev mailing list