Commit c8a1e939 authored by Jeremy Kerr's avatar Jeremy Kerr Committed by Arnd Bergmann

[POWERPC] spufs: provide siginfo for SPE faults

This change populates a siginfo struct for SPE application exceptions
(ie, invalid DMAs and illegal instructions).

Tested on an IBM Cell Blade.
Signed-off-by: default avatarJeremy Kerr <jk@ozlabs.org>
Signed-off-by: default avatarArnd Bergmann <arnd.bergmann@de.ibm.com>
parent 57dace23
...@@ -97,28 +97,46 @@ static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned ...@@ -97,28 +97,46 @@ static int spu_handle_mm_fault(struct mm_struct *mm, unsigned long ea, unsigned
return -EFAULT; return -EFAULT;
} }
static void spufs_handle_dma_error(struct spu_context *ctx, int type) static void spufs_handle_dma_error(struct spu_context *ctx,
unsigned long ea, int type)
{ {
if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) {
ctx->event_return |= type; ctx->event_return |= type;
wake_up_all(&ctx->stop_wq); wake_up_all(&ctx->stop_wq);
} else { } else {
siginfo_t info;
memset(&info, 0, sizeof(info));
switch (type) { switch (type) {
case SPE_EVENT_DMA_ALIGNMENT:
case SPE_EVENT_SPE_DATA_STORAGE:
case SPE_EVENT_INVALID_DMA: case SPE_EVENT_INVALID_DMA:
force_sig(SIGBUS, /* info, */ current); info.si_signo = SIGBUS;
info.si_code = BUS_OBJERR;
break;
case SPE_EVENT_SPE_DATA_STORAGE:
info.si_signo = SIGBUS;
info.si_addr = (void __user *)ea;
info.si_code = BUS_ADRERR;
break;
case SPE_EVENT_DMA_ALIGNMENT:
info.si_signo = SIGBUS;
/* DAR isn't set for an alignment fault :( */
info.si_code = BUS_ADRALN;
break; break;
case SPE_EVENT_SPE_ERROR: case SPE_EVENT_SPE_ERROR:
force_sig(SIGILL, /* info */ current); info.si_signo = SIGILL;
info.si_addr = (void __user *)(unsigned long)
ctx->ops->npc_read(ctx) - 4;
info.si_code = ILL_ILLOPC;
break; break;
} }
if (info.si_signo)
force_sig_info(info.si_signo, &info, current);
} }
} }
void spufs_dma_callback(struct spu *spu, int type) void spufs_dma_callback(struct spu *spu, int type)
{ {
spufs_handle_dma_error(spu->ctx, type); spufs_handle_dma_error(spu->ctx, spu->dar, type);
} }
EXPORT_SYMBOL_GPL(spufs_dma_callback); EXPORT_SYMBOL_GPL(spufs_dma_callback);
...@@ -186,7 +204,7 @@ int spufs_handle_class1(struct spu_context *ctx) ...@@ -186,7 +204,7 @@ int spufs_handle_class1(struct spu_context *ctx)
if (ctx->spu) if (ctx->spu)
ctx->ops->restart_dma(ctx); ctx->ops->restart_dma(ctx);
} else } else
spufs_handle_dma_error(ctx, SPE_EVENT_SPE_DATA_STORAGE); spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE);
return ret; return ret;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment