diff options
Diffstat (limited to 'arch/arm/kernel/signal.c')
-rw-r--r-- | arch/arm/kernel/signal.c | 207 |
1 files changed, 82 insertions, 125 deletions
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index f094277485c8..1ce05ec086c6 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c | |||
@@ -134,17 +134,6 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, | |||
134 | 134 | ||
135 | #ifdef CONFIG_IWMMXT | 135 | #ifdef CONFIG_IWMMXT |
136 | 136 | ||
137 | /* iwmmxt_area is 0x98 bytes long, preceeded by 8 bytes of signature */ | ||
138 | #define IWMMXT_STORAGE_SIZE (0x98 + 8) | ||
139 | #define IWMMXT_MAGIC0 0x12ef842a | ||
140 | #define IWMMXT_MAGIC1 0x1c07ca71 | ||
141 | |||
142 | struct iwmmxt_sigframe { | ||
143 | unsigned long magic0; | ||
144 | unsigned long magic1; | ||
145 | unsigned long storage[0x98/4]; | ||
146 | }; | ||
147 | |||
148 | static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) | 137 | static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) |
149 | { | 138 | { |
150 | char kbuf[sizeof(*frame) + 8]; | 139 | char kbuf[sizeof(*frame) + 8]; |
@@ -152,8 +141,8 @@ static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) | |||
152 | 141 | ||
153 | /* the iWMMXt context must be 64 bit aligned */ | 142 | /* the iWMMXt context must be 64 bit aligned */ |
154 | kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); | 143 | kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); |
155 | kframe->magic0 = IWMMXT_MAGIC0; | 144 | kframe->magic = IWMMXT_MAGIC; |
156 | kframe->magic1 = IWMMXT_MAGIC1; | 145 | kframe->size = IWMMXT_STORAGE_SIZE; |
157 | iwmmxt_task_copy(current_thread_info(), &kframe->storage); | 146 | iwmmxt_task_copy(current_thread_info(), &kframe->storage); |
158 | return __copy_to_user(frame, kframe, sizeof(*frame)); | 147 | return __copy_to_user(frame, kframe, sizeof(*frame)); |
159 | } | 148 | } |
@@ -167,8 +156,8 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) | |||
167 | kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); | 156 | kframe = (struct iwmmxt_sigframe *)((unsigned long)(kbuf + 8) & ~7); |
168 | if (__copy_from_user(kframe, frame, sizeof(*frame))) | 157 | if (__copy_from_user(kframe, frame, sizeof(*frame))) |
169 | return -1; | 158 | return -1; |
170 | if (kframe->magic0 != IWMMXT_MAGIC0 || | 159 | if (kframe->magic != IWMMXT_MAGIC || |
171 | kframe->magic1 != IWMMXT_MAGIC1) | 160 | kframe->size != IWMMXT_STORAGE_SIZE) |
172 | return -1; | 161 | return -1; |
173 | iwmmxt_task_restore(current_thread_info(), &kframe->storage); | 162 | iwmmxt_task_restore(current_thread_info(), &kframe->storage); |
174 | return 0; | 163 | return 0; |
@@ -177,70 +166,61 @@ static int restore_iwmmxt_context(struct iwmmxt_sigframe *frame) | |||
177 | #endif | 166 | #endif |
178 | 167 | ||
179 | /* | 168 | /* |
180 | * Auxiliary signal frame. This saves stuff like FP state. | ||
181 | * The layout of this structure is not part of the user ABI. | ||
182 | */ | ||
183 | struct aux_sigframe { | ||
184 | #ifdef CONFIG_IWMMXT | ||
185 | struct iwmmxt_sigframe iwmmxt; | ||
186 | #endif | ||
187 | #ifdef CONFIG_VFP | ||
188 | union vfp_state vfp; | ||
189 | #endif | ||
190 | }; | ||
191 | |||
192 | /* | ||
193 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. | 169 | * Do a signal return; undo the signal stack. These are aligned to 64-bit. |
194 | */ | 170 | */ |
195 | struct sigframe { | 171 | struct sigframe { |
196 | struct sigcontext sc; | 172 | struct ucontext uc; |
197 | unsigned long extramask[_NSIG_WORDS-1]; | ||
198 | unsigned long retcode[2]; | 173 | unsigned long retcode[2]; |
199 | struct aux_sigframe aux __attribute__((aligned(8))); | ||
200 | }; | 174 | }; |
201 | 175 | ||
202 | struct rt_sigframe { | 176 | struct rt_sigframe { |
203 | struct siginfo __user *pinfo; | ||
204 | void __user *puc; | ||
205 | struct siginfo info; | 177 | struct siginfo info; |
206 | struct ucontext uc; | 178 | struct sigframe sig; |
207 | unsigned long retcode[2]; | ||
208 | struct aux_sigframe aux __attribute__((aligned(8))); | ||
209 | }; | 179 | }; |
210 | 180 | ||
211 | static int | 181 | static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) |
212 | restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | ||
213 | struct aux_sigframe __user *aux) | ||
214 | { | 182 | { |
215 | int err = 0; | 183 | struct aux_sigframe __user *aux; |
184 | sigset_t set; | ||
185 | int err; | ||
186 | |||
187 | err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set)); | ||
188 | if (err == 0) { | ||
189 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
190 | spin_lock_irq(¤t->sighand->siglock); | ||
191 | current->blocked = set; | ||
192 | recalc_sigpending(); | ||
193 | spin_unlock_irq(¤t->sighand->siglock); | ||
194 | } | ||
216 | 195 | ||
217 | __get_user_error(regs->ARM_r0, &sc->arm_r0, err); | 196 | __get_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); |
218 | __get_user_error(regs->ARM_r1, &sc->arm_r1, err); | 197 | __get_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); |
219 | __get_user_error(regs->ARM_r2, &sc->arm_r2, err); | 198 | __get_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); |
220 | __get_user_error(regs->ARM_r3, &sc->arm_r3, err); | 199 | __get_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); |
221 | __get_user_error(regs->ARM_r4, &sc->arm_r4, err); | 200 | __get_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); |
222 | __get_user_error(regs->ARM_r5, &sc->arm_r5, err); | 201 | __get_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); |
223 | __get_user_error(regs->ARM_r6, &sc->arm_r6, err); | 202 | __get_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); |
224 | __get_user_error(regs->ARM_r7, &sc->arm_r7, err); | 203 | __get_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); |
225 | __get_user_error(regs->ARM_r8, &sc->arm_r8, err); | 204 | __get_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); |
226 | __get_user_error(regs->ARM_r9, &sc->arm_r9, err); | 205 | __get_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); |
227 | __get_user_error(regs->ARM_r10, &sc->arm_r10, err); | 206 | __get_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); |
228 | __get_user_error(regs->ARM_fp, &sc->arm_fp, err); | 207 | __get_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); |
229 | __get_user_error(regs->ARM_ip, &sc->arm_ip, err); | 208 | __get_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); |
230 | __get_user_error(regs->ARM_sp, &sc->arm_sp, err); | 209 | __get_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); |
231 | __get_user_error(regs->ARM_lr, &sc->arm_lr, err); | 210 | __get_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); |
232 | __get_user_error(regs->ARM_pc, &sc->arm_pc, err); | 211 | __get_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); |
233 | __get_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); | 212 | __get_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); |
234 | 213 | ||
235 | err |= !valid_user_regs(regs); | 214 | err |= !valid_user_regs(regs); |
236 | 215 | ||
216 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; | ||
237 | #ifdef CONFIG_IWMMXT | 217 | #ifdef CONFIG_IWMMXT |
238 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) | 218 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) |
239 | err |= restore_iwmmxt_context(&aux->iwmmxt); | 219 | err |= restore_iwmmxt_context(&aux->iwmmxt); |
240 | #endif | 220 | #endif |
241 | #ifdef CONFIG_VFP | 221 | #ifdef CONFIG_VFP |
242 | // if (err == 0) | 222 | // if (err == 0) |
243 | // err |= vfp_restore_state(&aux->vfp); | 223 | // err |= vfp_restore_state(&sf->aux.vfp); |
244 | #endif | 224 | #endif |
245 | 225 | ||
246 | return err; | 226 | return err; |
@@ -249,7 +229,6 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | |||
249 | asmlinkage int sys_sigreturn(struct pt_regs *regs) | 229 | asmlinkage int sys_sigreturn(struct pt_regs *regs) |
250 | { | 230 | { |
251 | struct sigframe __user *frame; | 231 | struct sigframe __user *frame; |
252 | sigset_t set; | ||
253 | 232 | ||
254 | /* Always make any pending restarted system calls return -EINTR */ | 233 | /* Always make any pending restarted system calls return -EINTR */ |
255 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 234 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
@@ -266,19 +245,8 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs) | |||
266 | 245 | ||
267 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) | 246 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) |
268 | goto badframe; | 247 | goto badframe; |
269 | if (__get_user(set.sig[0], &frame->sc.oldmask) | ||
270 | || (_NSIG_WORDS > 1 | ||
271 | && __copy_from_user(&set.sig[1], &frame->extramask, | ||
272 | sizeof(frame->extramask)))) | ||
273 | goto badframe; | ||
274 | |||
275 | sigdelsetmask(&set, ~_BLOCKABLE); | ||
276 | spin_lock_irq(¤t->sighand->siglock); | ||
277 | current->blocked = set; | ||
278 | recalc_sigpending(); | ||
279 | spin_unlock_irq(¤t->sighand->siglock); | ||
280 | 248 | ||
281 | if (restore_sigcontext(regs, &frame->sc, &frame->aux)) | 249 | if (restore_sigframe(regs, frame)) |
282 | goto badframe; | 250 | goto badframe; |
283 | 251 | ||
284 | /* Send SIGTRAP if we're single-stepping */ | 252 | /* Send SIGTRAP if we're single-stepping */ |
@@ -297,7 +265,6 @@ badframe: | |||
297 | asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) | 265 | asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) |
298 | { | 266 | { |
299 | struct rt_sigframe __user *frame; | 267 | struct rt_sigframe __user *frame; |
300 | sigset_t set; | ||
301 | 268 | ||
302 | /* Always make any pending restarted system calls return -EINTR */ | 269 | /* Always make any pending restarted system calls return -EINTR */ |
303 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 270 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
@@ -314,19 +281,11 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) | |||
314 | 281 | ||
315 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) | 282 | if (!access_ok(VERIFY_READ, frame, sizeof (*frame))) |
316 | goto badframe; | 283 | goto badframe; |
317 | if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) | ||
318 | goto badframe; | ||
319 | 284 | ||
320 | sigdelsetmask(&set, ~_BLOCKABLE); | 285 | if (restore_sigframe(regs, &frame->sig)) |
321 | spin_lock_irq(¤t->sighand->siglock); | ||
322 | current->blocked = set; | ||
323 | recalc_sigpending(); | ||
324 | spin_unlock_irq(¤t->sighand->siglock); | ||
325 | |||
326 | if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux)) | ||
327 | goto badframe; | 286 | goto badframe; |
328 | 287 | ||
329 | if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) | 288 | if (do_sigaltstack(&frame->sig.uc.uc_stack, NULL, regs->ARM_sp) == -EFAULT) |
330 | goto badframe; | 289 | goto badframe; |
331 | 290 | ||
332 | /* Send SIGTRAP if we're single-stepping */ | 291 | /* Send SIGTRAP if we're single-stepping */ |
@@ -343,42 +302,46 @@ badframe: | |||
343 | } | 302 | } |
344 | 303 | ||
345 | static int | 304 | static int |
346 | setup_sigcontext(struct sigcontext __user *sc, struct aux_sigframe __user *aux, | 305 | setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) |
347 | struct pt_regs *regs, unsigned long mask) | ||
348 | { | 306 | { |
307 | struct aux_sigframe __user *aux; | ||
349 | int err = 0; | 308 | int err = 0; |
350 | 309 | ||
351 | __put_user_error(regs->ARM_r0, &sc->arm_r0, err); | 310 | __put_user_error(regs->ARM_r0, &sf->uc.uc_mcontext.arm_r0, err); |
352 | __put_user_error(regs->ARM_r1, &sc->arm_r1, err); | 311 | __put_user_error(regs->ARM_r1, &sf->uc.uc_mcontext.arm_r1, err); |
353 | __put_user_error(regs->ARM_r2, &sc->arm_r2, err); | 312 | __put_user_error(regs->ARM_r2, &sf->uc.uc_mcontext.arm_r2, err); |
354 | __put_user_error(regs->ARM_r3, &sc->arm_r3, err); | 313 | __put_user_error(regs->ARM_r3, &sf->uc.uc_mcontext.arm_r3, err); |
355 | __put_user_error(regs->ARM_r4, &sc->arm_r4, err); | 314 | __put_user_error(regs->ARM_r4, &sf->uc.uc_mcontext.arm_r4, err); |
356 | __put_user_error(regs->ARM_r5, &sc->arm_r5, err); | 315 | __put_user_error(regs->ARM_r5, &sf->uc.uc_mcontext.arm_r5, err); |
357 | __put_user_error(regs->ARM_r6, &sc->arm_r6, err); | 316 | __put_user_error(regs->ARM_r6, &sf->uc.uc_mcontext.arm_r6, err); |
358 | __put_user_error(regs->ARM_r7, &sc->arm_r7, err); | 317 | __put_user_error(regs->ARM_r7, &sf->uc.uc_mcontext.arm_r7, err); |
359 | __put_user_error(regs->ARM_r8, &sc->arm_r8, err); | 318 | __put_user_error(regs->ARM_r8, &sf->uc.uc_mcontext.arm_r8, err); |
360 | __put_user_error(regs->ARM_r9, &sc->arm_r9, err); | 319 | __put_user_error(regs->ARM_r9, &sf->uc.uc_mcontext.arm_r9, err); |
361 | __put_user_error(regs->ARM_r10, &sc->arm_r10, err); | 320 | __put_user_error(regs->ARM_r10, &sf->uc.uc_mcontext.arm_r10, err); |
362 | __put_user_error(regs->ARM_fp, &sc->arm_fp, err); | 321 | __put_user_error(regs->ARM_fp, &sf->uc.uc_mcontext.arm_fp, err); |
363 | __put_user_error(regs->ARM_ip, &sc->arm_ip, err); | 322 | __put_user_error(regs->ARM_ip, &sf->uc.uc_mcontext.arm_ip, err); |
364 | __put_user_error(regs->ARM_sp, &sc->arm_sp, err); | 323 | __put_user_error(regs->ARM_sp, &sf->uc.uc_mcontext.arm_sp, err); |
365 | __put_user_error(regs->ARM_lr, &sc->arm_lr, err); | 324 | __put_user_error(regs->ARM_lr, &sf->uc.uc_mcontext.arm_lr, err); |
366 | __put_user_error(regs->ARM_pc, &sc->arm_pc, err); | 325 | __put_user_error(regs->ARM_pc, &sf->uc.uc_mcontext.arm_pc, err); |
367 | __put_user_error(regs->ARM_cpsr, &sc->arm_cpsr, err); | 326 | __put_user_error(regs->ARM_cpsr, &sf->uc.uc_mcontext.arm_cpsr, err); |
368 | 327 | ||
369 | __put_user_error(current->thread.trap_no, &sc->trap_no, err); | 328 | __put_user_error(current->thread.trap_no, &sf->uc.uc_mcontext.trap_no, err); |
370 | __put_user_error(current->thread.error_code, &sc->error_code, err); | 329 | __put_user_error(current->thread.error_code, &sf->uc.uc_mcontext.error_code, err); |
371 | __put_user_error(current->thread.address, &sc->fault_address, err); | 330 | __put_user_error(current->thread.address, &sf->uc.uc_mcontext.fault_address, err); |
372 | __put_user_error(mask, &sc->oldmask, err); | 331 | __put_user_error(set->sig[0], &sf->uc.uc_mcontext.oldmask, err); |
373 | 332 | ||
333 | err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); | ||
334 | |||
335 | aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; | ||
374 | #ifdef CONFIG_IWMMXT | 336 | #ifdef CONFIG_IWMMXT |
375 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) | 337 | if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) |
376 | err |= preserve_iwmmxt_context(&aux->iwmmxt); | 338 | err |= preserve_iwmmxt_context(&aux->iwmmxt); |
377 | #endif | 339 | #endif |
378 | #ifdef CONFIG_VFP | 340 | #ifdef CONFIG_VFP |
379 | // if (err == 0) | 341 | // if (err == 0) |
380 | // err |= vfp_save_state(&aux->vfp); | 342 | // err |= vfp_save_state(&sf->aux.vfp); |
381 | #endif | 343 | #endif |
344 | __put_user_error(0, &aux->end_magic, err); | ||
382 | 345 | ||
383 | return err; | 346 | return err; |
384 | } | 347 | } |
@@ -487,13 +450,12 @@ setup_frame(int usig, struct k_sigaction *ka, sigset_t *set, struct pt_regs *reg | |||
487 | if (!frame) | 450 | if (!frame) |
488 | return 1; | 451 | return 1; |
489 | 452 | ||
490 | err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); | 453 | /* |
491 | 454 | * Set uc.uc_flags to a value which sc.trap_no would never have. | |
492 | if (_NSIG_WORDS > 1) { | 455 | */ |
493 | err |= __copy_to_user(frame->extramask, &set->sig[1], | 456 | __put_user_error(0x5ac3c35a, &frame->uc.uc_flags, err); |
494 | sizeof(frame->extramask)); | ||
495 | } | ||
496 | 457 | ||
458 | err |= setup_sigframe(frame, regs, set); | ||
497 | if (err == 0) | 459 | if (err == 0) |
498 | err = setup_return(regs, ka, frame->retcode, frame, usig); | 460 | err = setup_return(regs, ka, frame->retcode, frame, usig); |
499 | 461 | ||
@@ -511,25 +473,20 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, | |||
511 | if (!frame) | 473 | if (!frame) |
512 | return 1; | 474 | return 1; |
513 | 475 | ||
514 | __put_user_error(&frame->info, &frame->pinfo, err); | ||
515 | __put_user_error(&frame->uc, &frame->puc, err); | ||
516 | err |= copy_siginfo_to_user(&frame->info, info); | 476 | err |= copy_siginfo_to_user(&frame->info, info); |
517 | 477 | ||
518 | __put_user_error(0, &frame->uc.uc_flags, err); | 478 | __put_user_error(0, &frame->sig.uc.uc_flags, err); |
519 | __put_user_error(NULL, &frame->uc.uc_link, err); | 479 | __put_user_error(NULL, &frame->sig.uc.uc_link, err); |
520 | 480 | ||
521 | memset(&stack, 0, sizeof(stack)); | 481 | memset(&stack, 0, sizeof(stack)); |
522 | stack.ss_sp = (void __user *)current->sas_ss_sp; | 482 | stack.ss_sp = (void __user *)current->sas_ss_sp; |
523 | stack.ss_flags = sas_ss_flags(regs->ARM_sp); | 483 | stack.ss_flags = sas_ss_flags(regs->ARM_sp); |
524 | stack.ss_size = current->sas_ss_size; | 484 | stack.ss_size = current->sas_ss_size; |
525 | err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); | 485 | err |= __copy_to_user(&frame->sig.uc.uc_stack, &stack, sizeof(stack)); |
526 | |||
527 | err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux, | ||
528 | regs, set->sig[0]); | ||
529 | err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); | ||
530 | 486 | ||
487 | err |= setup_sigframe(&frame->sig, regs, set); | ||
531 | if (err == 0) | 488 | if (err == 0) |
532 | err = setup_return(regs, ka, frame->retcode, frame, usig); | 489 | err = setup_return(regs, ka, frame->sig.retcode, frame, usig); |
533 | 490 | ||
534 | if (err == 0) { | 491 | if (err == 0) { |
535 | /* | 492 | /* |
@@ -538,7 +495,7 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, | |||
538 | * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06 | 495 | * -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06 |
539 | */ | 496 | */ |
540 | regs->ARM_r1 = (unsigned long)&frame->info; | 497 | regs->ARM_r1 = (unsigned long)&frame->info; |
541 | regs->ARM_r2 = (unsigned long)&frame->uc; | 498 | regs->ARM_r2 = (unsigned long)&frame->sig.uc; |
542 | } | 499 | } |
543 | 500 | ||
544 | return err; | 501 | return err; |