diff options
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r-- | arch/arm/kernel/signal.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 1ce05ec086c6..83a8d3c95eb3 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -132,6 +132,37 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
132 | return ret; | 132 | return ret; |
133 | } | 133 | } |
134 | 134 | ||
135 | #ifdef CONFIG_CRUNCH | ||
136 | static int preserve_crunch_context(struct crunch_sigframe *frame) | ||
137 | { | ||
138 | char kbuf[sizeof(*frame) + 8]; | ||
139 | struct crunch_sigframe *kframe; | ||
140 | |||
141 | /* the crunch context must be 64 bit aligned */ | ||
142 | kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); | ||
143 | kframe->magic = CRUNCH_MAGIC; | ||
144 | kframe->size = CRUNCH_STORAGE_SIZE; | ||
145 | crunch_task_copy(current_thread_info(), &kframe->storage); | ||
146 | return __copy_to_user(frame, kframe, sizeof(*frame)); | ||
147 | } | ||
148 | |||
149 | static int restore_crunch_context(struct crunch_sigframe *frame) | ||
150 | { | ||
151 | char kbuf[sizeof(*frame) + 8]; | ||
152 | struct crunch_sigframe *kframe; | ||
153 | |||
154 | /* the crunch context must be 64 bit aligned */ | ||
155 | kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); | ||
156 | if (__copy_from_user(kframe, frame, sizeof(*frame))) | ||
157 | return -1; | ||
158 | if (kframe->magic != CRUNCH_MAGIC || | ||
159 | kframe->size != CRUNCH_STORAGE_SIZE) | ||
160 | return -1; | ||
161 | crunch_task_restore(current_thread_info(), &kframe->storage); | ||
162 | return 0; | ||
163 | } | ||
164 | #endif | ||
165 | |||
135 | #ifdef CONFIG_IWMMXT | 166 | #ifdef CONFIG_IWMMXT |
136 | 167 | ||
137 | static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) | 168 | static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) |
@@ -214,6 +245,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) | |||
214 | err |= !valid_user_regs(regs); | 245 | err |= !valid_user_regs(regs); |
215 | 246 | ||
216 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; | 247 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; |
248 | #ifdef CONFIG_CRUNCH | ||
249 | if (err == 0) | ||
250 | err |= restore_crunch_context(&aux->crunch); | ||
251 | #endif | ||
217 | #ifdef CONFIG_IWMMXT | 252 | #ifdef CONFIG_IWMMXT |
218 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) | 253 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) |
219 | err |= restore_iwmmxt_context(&aux->iwmmxt); | 254 | err |= restore_iwmmxt_context(&aux->iwmmxt); |
@@ -333,6 +368,10 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) | |||
333 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); | 368 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); |
334 | 369 | ||
335 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; | 370 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; |
371 | #ifdef CONFIG_CRUNCH | ||
372 | if (err == 0) | ||
373 | err |= preserve_crunch_context(&aux->crunch); | ||
374 | #endif | ||
336 | #ifdef CONFIG_IWMMXT | 375 | #ifdef CONFIG_IWMMXT |
337 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) | 376 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) |
338 | err |= preserve_iwmmxt_context(&aux->iwmmxt); | 377 | err |= preserve_iwmmxt_context(&aux->iwmmxt); |