diff options
Diffstat (limited to 'arch/mips/kernel/signal32.c')
-rw-r--r-- | arch/mips/kernel/signal32.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c index 5e7d0fa02672..8639e24732a5 100644 --- a/arch/mips/kernel/signal32.c +++ b/arch/mips/kernel/signal32.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/suspend.h> | 21 | #include <linux/suspend.h> |
22 | #include <linux/compiler.h> | 22 | #include <linux/compiler.h> |
23 | 23 | ||
24 | #include <asm/abi.h> | ||
24 | #include <asm/asm.h> | 25 | #include <asm/asm.h> |
25 | #include <linux/bitops.h> | 26 | #include <linux/bitops.h> |
26 | #include <asm/cacheflush.h> | 27 | #include <asm/cacheflush.h> |
@@ -334,8 +335,9 @@ asmlinkage int sys32_sigaltstack(nabi_no_regargs struct pt_regs regs) | |||
334 | 335 | ||
335 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) | 336 | static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) |
336 | { | 337 | { |
338 | u32 used_math; | ||
337 | int err = 0; | 339 | int err = 0; |
338 | __u32 used_math; | 340 | s32 treg; |
339 | 341 | ||
340 | /* Always make any pending restarted system calls return -EINTR */ | 342 | /* Always make any pending restarted system calls return -EINTR */ |
341 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 343 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
@@ -343,6 +345,15 @@ static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) | |||
343 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); | 345 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
344 | err |= __get_user(regs->hi, &sc->sc_mdhi); | 346 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
345 | err |= __get_user(regs->lo, &sc->sc_mdlo); | 347 | err |= __get_user(regs->lo, &sc->sc_mdlo); |
348 | if (cpu_has_dsp) { | ||
349 | err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); | ||
350 | err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); | ||
351 | err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); | ||
352 | err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); | ||
353 | err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); | ||
354 | err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); | ||
355 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
356 | } | ||
346 | 357 | ||
347 | #define restore_gp_reg(i) do { \ | 358 | #define restore_gp_reg(i) do { \ |
348 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ | 359 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
@@ -562,8 +573,15 @@ static inline int setup_sigcontext32(struct pt_regs *regs, | |||
562 | 573 | ||
563 | err |= __put_user(regs->hi, &sc->sc_mdhi); | 574 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
564 | err |= __put_user(regs->lo, &sc->sc_mdlo); | 575 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
565 | err |= __put_user(regs->cp0_cause, &sc->sc_cause); | 576 | if (cpu_has_dsp) { |
566 | err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | 577 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_hi1); |
578 | err |= __put_user(mfhi1(), &sc->sc_hi1); | ||
579 | err |= __put_user(mflo1(), &sc->sc_lo1); | ||
580 | err |= __put_user(mfhi2(), &sc->sc_hi2); | ||
581 | err |= __put_user(mflo2(), &sc->sc_lo2); | ||
582 | err |= __put_user(mfhi3(), &sc->sc_hi3); | ||
583 | err |= __put_user(mflo3(), &sc->sc_lo3); | ||
584 | } | ||
567 | 585 | ||
568 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 586 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
569 | 587 | ||
@@ -613,7 +631,7 @@ static inline void *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, | |||
613 | return (void *)((sp - frame_size) & ALMASK); | 631 | return (void *)((sp - frame_size) & ALMASK); |
614 | } | 632 | } |
615 | 633 | ||
616 | static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, | 634 | void setup_frame_32(struct k_sigaction * ka, struct pt_regs *regs, |
617 | int signr, sigset_t *set) | 635 | int signr, sigset_t *set) |
618 | { | 636 | { |
619 | struct sigframe *frame; | 637 | struct sigframe *frame; |
@@ -666,9 +684,7 @@ give_sigsegv: | |||
666 | force_sigsegv(signr, current); | 684 | force_sigsegv(signr, current); |
667 | } | 685 | } |
668 | 686 | ||
669 | static inline void setup_rt_frame(struct k_sigaction * ka, | 687 | void setup_rt_frame_32(struct k_sigaction * ka, struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) |
670 | struct pt_regs *regs, int signr, | ||
671 | sigset_t *set, siginfo_t *info) | ||
672 | { | 688 | { |
673 | struct rt_sigframe32 *frame; | 689 | struct rt_sigframe32 *frame; |
674 | int err = 0; | 690 | int err = 0; |
@@ -759,9 +775,9 @@ static inline void handle_signal(unsigned long sig, siginfo_t *info, | |||
759 | regs->regs[0] = 0; /* Don't deal with this again. */ | 775 | regs->regs[0] = 0; /* Don't deal with this again. */ |
760 | 776 | ||
761 | if (ka->sa.sa_flags & SA_SIGINFO) | 777 | if (ka->sa.sa_flags & SA_SIGINFO) |
762 | setup_rt_frame(ka, regs, sig, oldset, info); | 778 | current->thread.abi->setup_rt_frame(ka, regs, sig, oldset, info); |
763 | else | 779 | else |
764 | setup_frame(ka, regs, sig, oldset); | 780 | current->thread.abi->setup_frame(ka, regs, sig, oldset); |
765 | 781 | ||
766 | spin_lock_irq(¤t->sighand->siglock); | 782 | spin_lock_irq(¤t->sighand->siglock); |
767 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); | 783 | sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); |