summaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorAndre Detsch <adetsch@br.ibm.com>2007-12-20 16:39:59 +0900
committerPaul Mackerras <paulus@samba.org>2007-12-21 19:46:21 +1100
commit18789fb1c3311dd8c25acb6eb5ccab05771843f2 (patch)
treef3b39752fe624f37de34966908be8829840ce850 /arch/powerpc
parent90608a2928a86b9464a8698275a1138e82e3a010 (diff)
downloadblackbird-op-linux-18789fb1c3311dd8c25acb6eb5ccab05771843f2.tar.gz
blackbird-op-linux-18789fb1c3311dd8c25acb6eb5ccab05771843f2.zip
[POWERPC] spufs: DMA Restart after SIGSEGV
This fixes the behavior of spufs when a spu tries a DMA operation based on a wrong / unavailable address. Instead of just generating a SIGBUS signal, spufs now generates a SIGSEGV signal and restarts the problematic DMA operation after the execution of the application's signal handler. This allows applications to employ user-level paging systems. Although the restart_dma function is called before the application's signal handler, the operation is not actually performed at this time, since the spu context is already stopped. The operation only takes place when spu_run is restarted (which happens automatically). Signed-off-by: Andre Detsch <adetsch@br.ibm.com> Signed-off-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c2
-rw-r--r--arch/powerpc/platforms/cell/spufs/fault.c5
2 files changed, 4 insertions, 3 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index d4495531e5b2..50d98a154aaf 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -373,7 +373,7 @@ static int spu_backing_send_mfc_command(struct spu_context *ctx,
static void spu_backing_restart_dma(struct spu_context *ctx)
{
- /* nothing to do here */
+ ctx->csa.priv2.mfc_control_RW |= MFC_CNTL_RESTART_DMA_COMMAND;
}
struct spu_context_ops spu_backing_ops = {
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c
index 825001c2b095..eff4d291ba85 100644
--- a/arch/powerpc/platforms/cell/spufs/fault.c
+++ b/arch/powerpc/platforms/cell/spufs/fault.c
@@ -53,9 +53,10 @@ static void spufs_handle_event(struct spu_context *ctx,
info.si_code = BUS_OBJERR;
break;
case SPE_EVENT_SPE_DATA_STORAGE:
- info.si_signo = SIGBUS;
+ info.si_signo = SIGSEGV;
info.si_addr = (void __user *)ea;
- info.si_code = BUS_ADRERR;
+ info.si_code = SEGV_ACCERR;
+ ctx->ops->restart_dma(ctx);
break;
case SPE_EVENT_DMA_ALIGNMENT:
info.si_signo = SIGBUS;
OpenPOWER on IntegriCloud