aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/kernel/signal32.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/kernel/signal32.c')
-rw-r--r--arch/mips/kernel/signal32.c34
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
335static int restore_sigcontext32(struct pt_regs *regs, struct sigcontext32 *sc) 336static 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
616static inline void setup_frame(struct k_sigaction * ka, struct pt_regs *regs, 634void 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
669static inline void setup_rt_frame(struct k_sigaction * ka, 687void 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(&current->sighand->siglock); 782 spin_lock_irq(&current->sighand->siglock);
767 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask); 783 sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);