diff options
author | Jeremy Kerr <jk@ozlabs.org> | 2007-04-23 15:08:16 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@klappe.arndb.de> | 2007-04-23 15:18:55 -0400 |
commit | c8a1e9393a86f862ab9c8bc0db9b8a1822226f84 (patch) | |
tree | 9ff1d8d44d5b5caa98770457297ec26382e1c9f5 /arch/powerpc | |
parent | 57dace2391ba10135e38457904121e7ef34d0c83 (diff) |
[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>
Diffstat (limited to 'arch/powerpc')
-rw-r--r-- | arch/powerpc/platforms/cell/spufs/fault.c | 32 |
1 files changed, 25 insertions, 7 deletions
diff --git a/arch/powerpc/platforms/cell/spufs/fault.c b/arch/powerpc/platforms/cell/spufs/fault.c index 182dc914cbc9..0f75c07e29d8 100644 --- a/arch/powerpc/platforms/cell/spufs/fault.c +++ b/arch/powerpc/platforms/cell/spufs/fault.c | |||
@@ -97,28 +97,46 @@ bad_area: | |||
97 | return -EFAULT; | 97 | return -EFAULT; |
98 | } | 98 | } |
99 | 99 | ||
100 | static void spufs_handle_dma_error(struct spu_context *ctx, int type) | 100 | static void spufs_handle_dma_error(struct spu_context *ctx, |
101 | unsigned long ea, int type) | ||
101 | { | 102 | { |
102 | if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { | 103 | if (ctx->flags & SPU_CREATE_EVENTS_ENABLED) { |
103 | ctx->event_return |= type; | 104 | ctx->event_return |= type; |
104 | wake_up_all(&ctx->stop_wq); | 105 | wake_up_all(&ctx->stop_wq); |
105 | } else { | 106 | } else { |
107 | siginfo_t info; | ||
108 | memset(&info, 0, sizeof(info)); | ||
109 | |||
106 | switch (type) { | 110 | switch (type) { |
107 | case SPE_EVENT_DMA_ALIGNMENT: | ||
108 | case SPE_EVENT_SPE_DATA_STORAGE: | ||
109 | case SPE_EVENT_INVALID_DMA: | 111 | case SPE_EVENT_INVALID_DMA: |
110 | force_sig(SIGBUS, /* info, */ current); | 112 | info.si_signo = SIGBUS; |
113 | info.si_code = BUS_OBJERR; | ||
114 | break; | ||
115 | case SPE_EVENT_SPE_DATA_STORAGE: | ||
116 | info.si_signo = SIGBUS; | ||
117 | info.si_addr = (void __user *)ea; | ||
118 | info.si_code = BUS_ADRERR; | ||
119 | break; | ||
120 | case SPE_EVENT_DMA_ALIGNMENT: | ||
121 | info.si_signo = SIGBUS; | ||
122 | /* DAR isn't set for an alignment fault :( */ | ||
123 | info.si_code = BUS_ADRALN; | ||
111 | break; | 124 | break; |
112 | case SPE_EVENT_SPE_ERROR: | 125 | case SPE_EVENT_SPE_ERROR: |
113 | force_sig(SIGILL, /* info */ current); | 126 | info.si_signo = SIGILL; |
127 | info.si_addr = (void __user *)(unsigned long) | ||
128 | ctx->ops->npc_read(ctx) - 4; | ||
129 | info.si_code = ILL_ILLOPC; | ||
114 | break; | 130 | break; |
115 | } | 131 | } |
132 | if (info.si_signo) | ||
133 | force_sig_info(info.si_signo, &info, current); | ||
116 | } | 134 | } |
117 | } | 135 | } |
118 | 136 | ||
119 | void spufs_dma_callback(struct spu *spu, int type) | 137 | void spufs_dma_callback(struct spu *spu, int type) |
120 | { | 138 | { |
121 | spufs_handle_dma_error(spu->ctx, type); | 139 | spufs_handle_dma_error(spu->ctx, spu->dar, type); |
122 | } | 140 | } |
123 | EXPORT_SYMBOL_GPL(spufs_dma_callback); | 141 | EXPORT_SYMBOL_GPL(spufs_dma_callback); |
124 | 142 | ||
@@ -186,7 +204,7 @@ int spufs_handle_class1(struct spu_context *ctx) | |||
186 | if (ctx->spu) | 204 | if (ctx->spu) |
187 | ctx->ops->restart_dma(ctx); | 205 | ctx->ops->restart_dma(ctx); |
188 | } else | 206 | } else |
189 | spufs_handle_dma_error(ctx, SPE_EVENT_SPE_DATA_STORAGE); | 207 | spufs_handle_dma_error(ctx, ea, SPE_EVENT_SPE_DATA_STORAGE); |
190 | 208 | ||
191 | return ret; | 209 | return ret; |
192 | } | 210 | } |