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); | 
