diff options
| author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-29 15:19:15 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-10-29 15:19:15 -0400 |
| commit | e9d52234e35b27ea4ea5f2ab64ca47b1a0c740ab (patch) | |
| tree | 318d37a7d55c79e6f7d86163fb28e0eccbb0fe83 /arch/mips/kernel/signal-common.h | |
| parent | 955c5038823748e529a49f0e33ab635d92843500 (diff) | |
| parent | 09af7b443c257460d45cb6c1896d29f173fef35b (diff) | |
Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-linus
Diffstat (limited to 'arch/mips/kernel/signal-common.h')
| -rw-r--r-- | arch/mips/kernel/signal-common.h | 90 |
1 files changed, 80 insertions, 10 deletions
diff --git a/arch/mips/kernel/signal-common.h b/arch/mips/kernel/signal-common.h index f9234df532..0f66ae5838 100644 --- a/arch/mips/kernel/signal-common.h +++ b/arch/mips/kernel/signal-common.h | |||
| @@ -8,13 +8,14 @@ | |||
| 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. | 8 | * Copyright (C) 1999, 2000 Silicon Graphics, Inc. |
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include <linux/config.h> | ||
| 12 | |||
| 11 | static inline int | 13 | static inline int |
| 12 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 14 | setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
| 13 | { | 15 | { |
| 14 | int err = 0; | 16 | int err = 0; |
| 15 | 17 | ||
| 16 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); | 18 | err |= __put_user(regs->cp0_epc, &sc->sc_pc); |
| 17 | err |= __put_user(regs->cp0_status, &sc->sc_status); | ||
| 18 | 19 | ||
| 19 | #define save_gp_reg(i) do { \ | 20 | #define save_gp_reg(i) do { \ |
| 20 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ | 21 | err |= __put_user(regs->regs[i], &sc->sc_regs[i]); \ |
| @@ -30,10 +31,32 @@ setup_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
| 30 | save_gp_reg(31); | 31 | save_gp_reg(31); |
| 31 | #undef save_gp_reg | 32 | #undef save_gp_reg |
| 32 | 33 | ||
| 34 | #ifdef CONFIG_32BIT | ||
| 33 | err |= __put_user(regs->hi, &sc->sc_mdhi); | 35 | err |= __put_user(regs->hi, &sc->sc_mdhi); |
| 34 | err |= __put_user(regs->lo, &sc->sc_mdlo); | 36 | err |= __put_user(regs->lo, &sc->sc_mdlo); |
| 35 | err |= __put_user(regs->cp0_cause, &sc->sc_cause); | 37 | if (cpu_has_dsp) { |
| 36 | err |= __put_user(regs->cp0_badvaddr, &sc->sc_badvaddr); | 38 | err |= __put_user(mfhi1(), &sc->sc_hi1); |
| 39 | err |= __put_user(mflo1(), &sc->sc_lo1); | ||
| 40 | err |= __put_user(mfhi2(), &sc->sc_hi2); | ||
| 41 | err |= __put_user(mflo2(), &sc->sc_lo2); | ||
| 42 | err |= __put_user(mfhi3(), &sc->sc_hi3); | ||
| 43 | err |= __put_user(mflo3(), &sc->sc_lo3); | ||
| 44 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
| 45 | } | ||
| 46 | #endif | ||
| 47 | #ifdef CONFIG_64BIT | ||
| 48 | err |= __put_user(regs->hi, &sc->sc_hi[0]); | ||
| 49 | err |= __put_user(regs->lo, &sc->sc_lo[0]); | ||
| 50 | if (cpu_has_dsp) { | ||
| 51 | err |= __put_user(mfhi1(), &sc->sc_hi[1]); | ||
| 52 | err |= __put_user(mflo1(), &sc->sc_lo[1]); | ||
| 53 | err |= __put_user(mfhi2(), &sc->sc_hi[2]); | ||
| 54 | err |= __put_user(mflo2(), &sc->sc_lo[2]); | ||
| 55 | err |= __put_user(mfhi3(), &sc->sc_hi[3]); | ||
| 56 | err |= __put_user(mflo3(), &sc->sc_lo[3]); | ||
| 57 | err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); | ||
| 58 | } | ||
| 59 | #endif | ||
| 37 | 60 | ||
| 38 | err |= __put_user(!!used_math(), &sc->sc_used_math); | 61 | err |= __put_user(!!used_math(), &sc->sc_used_math); |
| 39 | 62 | ||
| @@ -61,15 +84,40 @@ out: | |||
| 61 | static inline int | 84 | static inline int |
| 62 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | 85 | restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) |
| 63 | { | 86 | { |
| 64 | int err = 0; | ||
| 65 | unsigned int used_math; | 87 | unsigned int used_math; |
| 88 | unsigned long treg; | ||
| 89 | int err = 0; | ||
| 66 | 90 | ||
| 67 | /* Always make any pending restarted system calls return -EINTR */ | 91 | /* Always make any pending restarted system calls return -EINTR */ |
| 68 | current_thread_info()->restart_block.fn = do_no_restart_syscall; | 92 | current_thread_info()->restart_block.fn = do_no_restart_syscall; |
| 69 | 93 | ||
| 70 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); | 94 | err |= __get_user(regs->cp0_epc, &sc->sc_pc); |
| 95 | #ifdef CONFIG_32BIT | ||
| 71 | err |= __get_user(regs->hi, &sc->sc_mdhi); | 96 | err |= __get_user(regs->hi, &sc->sc_mdhi); |
| 72 | err |= __get_user(regs->lo, &sc->sc_mdlo); | 97 | err |= __get_user(regs->lo, &sc->sc_mdlo); |
| 98 | if (cpu_has_dsp) { | ||
| 99 | err |= __get_user(treg, &sc->sc_hi1); mthi1(treg); | ||
| 100 | err |= __get_user(treg, &sc->sc_lo1); mtlo1(treg); | ||
| 101 | err |= __get_user(treg, &sc->sc_hi2); mthi2(treg); | ||
| 102 | err |= __get_user(treg, &sc->sc_lo2); mtlo2(treg); | ||
| 103 | err |= __get_user(treg, &sc->sc_hi3); mthi3(treg); | ||
| 104 | err |= __get_user(treg, &sc->sc_lo3); mtlo3(treg); | ||
| 105 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
| 106 | } | ||
| 107 | #endif | ||
| 108 | #ifdef CONFIG_64BIT | ||
| 109 | err |= __get_user(regs->hi, &sc->sc_hi[0]); | ||
| 110 | err |= __get_user(regs->lo, &sc->sc_lo[0]); | ||
| 111 | if (cpu_has_dsp) { | ||
| 112 | err |= __get_user(treg, &sc->sc_hi[1]); mthi1(treg); | ||
| 113 | err |= __get_user(treg, &sc->sc_lo[1]); mthi1(treg); | ||
| 114 | err |= __get_user(treg, &sc->sc_hi[2]); mthi2(treg); | ||
| 115 | err |= __get_user(treg, &sc->sc_lo[2]); mthi2(treg); | ||
| 116 | err |= __get_user(treg, &sc->sc_hi[3]); mthi3(treg); | ||
| 117 | err |= __get_user(treg, &sc->sc_lo[3]); mthi3(treg); | ||
| 118 | err |= __get_user(treg, &sc->sc_dsp); wrdsp(treg, DSP_MASK); | ||
| 119 | } | ||
| 120 | #endif | ||
| 73 | 121 | ||
| 74 | #define restore_gp_reg(i) do { \ | 122 | #define restore_gp_reg(i) do { \ |
| 75 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ | 123 | err |= __get_user(regs->regs[i], &sc->sc_regs[i]); \ |
| @@ -112,7 +160,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) | |||
| 112 | static inline void * | 160 | static inline void * |
| 113 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | 161 | get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) |
| 114 | { | 162 | { |
| 115 | unsigned long sp, almask; | 163 | unsigned long sp; |
| 116 | 164 | ||
| 117 | /* Default to using normal stack */ | 165 | /* Default to using normal stack */ |
| 118 | sp = regs->regs[29]; | 166 | sp = regs->regs[29]; |
| @@ -128,10 +176,32 @@ get_sigframe(struct k_sigaction *ka, struct pt_regs *regs, size_t frame_size) | |||
| 128 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) | 176 | if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags (sp) == 0)) |
| 129 | sp = current->sas_ss_sp + current->sas_ss_size; | 177 | sp = current->sas_ss_sp + current->sas_ss_size; |
| 130 | 178 | ||
| 131 | if (PLAT_TRAMPOLINE_STUFF_LINE) | 179 | return (void *)((sp - frame_size) & (ICACHE_REFILLS_WORKAROUND_WAR ? 32 : ALMASK)); |
| 132 | almask = ~(PLAT_TRAMPOLINE_STUFF_LINE - 1); | 180 | } |
| 133 | else | 181 | |
| 134 | almask = ALMASK; | 182 | static inline int install_sigtramp(unsigned int __user *tramp, |
| 183 | unsigned int syscall) | ||
| 184 | { | ||
| 185 | int err; | ||
| 186 | |||
| 187 | /* | ||
| 188 | * Set up the return code ... | ||
| 189 | * | ||
| 190 | * li v0, __NR__foo_sigreturn | ||
| 191 | * syscall | ||
| 192 | */ | ||
| 193 | |||
| 194 | err = __put_user(0x24020000 + syscall, tramp + 0); | ||
| 195 | err |= __put_user(0x0000000c , tramp + 1); | ||
| 196 | if (ICACHE_REFILLS_WORKAROUND_WAR) { | ||
| 197 | err |= __put_user(0, tramp + 2); | ||
| 198 | err |= __put_user(0, tramp + 3); | ||
| 199 | err |= __put_user(0, tramp + 4); | ||
| 200 | err |= __put_user(0, tramp + 5); | ||
| 201 | err |= __put_user(0, tramp + 6); | ||
| 202 | err |= __put_user(0, tramp + 7); | ||
| 203 | } | ||
| 204 | flush_cache_sigtramp((unsigned long) tramp); | ||
| 135 | 205 | ||
| 136 | return (void *)((sp - frame_size) & almask); | 206 | return err; |
| 137 | } | 207 | } |
