[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: Jeremy Kerr <jk@ozlabs.org> Signed-off-by: Arnd Bergmann <arnd.bergmann@de.ibm.com>
This commit is contained in:
parent
57dace2391
commit
c8a1e9393a
@ -97,28 +97,46 @@ bad_area:
|
|||||||
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)
|
|||||||
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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user