diff options
Diffstat (limited to 'arch/mips/kernel/signal_n32.c')
-rw-r--r-- | arch/mips/kernel/signal_n32.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index 3544208d4b4b..ec61b2670ba6 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
@@ -15,6 +15,8 @@ | |||
15 | * along with this program; if not, write to the Free Software | 15 | * along with this program; if not, write to the Free Software |
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
17 | */ | 17 | */ |
18 | #include <linux/cache.h> | ||
19 | #include <linux/sched.h> | ||
18 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
19 | #include <linux/mm.h> | 21 | #include <linux/mm.h> |
20 | #include <linux/smp.h> | 22 | #include <linux/smp.h> |
@@ -36,6 +38,7 @@ | |||
36 | #include <asm/system.h> | 38 | #include <asm/system.h> |
37 | #include <asm/fpu.h> | 39 | #include <asm/fpu.h> |
38 | #include <asm/cpu-features.h> | 40 | #include <asm/cpu-features.h> |
41 | #include <asm/war.h> | ||
39 | 42 | ||
40 | #include "signal-common.h" | 43 | #include "signal-common.h" |
41 | 44 | ||
@@ -62,17 +65,18 @@ struct ucontextn32 { | |||
62 | sigset_t uc_sigmask; /* mask last for extensibility */ | 65 | sigset_t uc_sigmask; /* mask last for extensibility */ |
63 | }; | 66 | }; |
64 | 67 | ||
65 | #if PLAT_TRAMPOLINE_STUFF_LINE | ||
66 | #define __tramp __attribute__((aligned(PLAT_TRAMPOLINE_STUFF_LINE))) | ||
67 | #else | ||
68 | #define __tramp | ||
69 | #endif | ||
70 | |||
71 | struct rt_sigframe_n32 { | 68 | struct rt_sigframe_n32 { |
72 | u32 rs_ass[4]; /* argument save space for o32 */ | 69 | u32 rs_ass[4]; /* argument save space for o32 */ |
73 | u32 rs_code[2] __tramp; /* signal trampoline */ | 70 | #if ICACHE_REFILLS_WORKAROUND_WAR |
74 | struct siginfo rs_info __tramp; | 71 | u32 rs_pad[2]; |
72 | #else | ||
73 | u32 rs_code[2]; /* signal trampoline */ | ||
74 | #endif | ||
75 | struct siginfo rs_info; | ||
75 | struct ucontextn32 rs_uc; | 76 | struct ucontextn32 rs_uc; |
77 | #if ICACHE_REFILLS_WORKAROUND_WAR | ||
78 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ | ||
79 | #endif | ||
76 | }; | 80 | }; |
77 | 81 | ||
78 | save_static_function(sysn32_rt_sigreturn); | 82 | save_static_function(sysn32_rt_sigreturn); |
@@ -126,7 +130,7 @@ badframe: | |||
126 | force_sig(SIGSEGV, current); | 130 | force_sig(SIGSEGV, current); |
127 | } | 131 | } |
128 | 132 | ||
129 | void setup_rt_frame_n32(struct k_sigaction * ka, | 133 | int setup_rt_frame_n32(struct k_sigaction * ka, |
130 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) | 134 | struct pt_regs *regs, int signr, sigset_t *set, siginfo_t *info) |
131 | { | 135 | { |
132 | struct rt_sigframe_n32 *frame; | 136 | struct rt_sigframe_n32 *frame; |
@@ -137,17 +141,7 @@ void setup_rt_frame_n32(struct k_sigaction * ka, | |||
137 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) | 141 | if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) |
138 | goto give_sigsegv; | 142 | goto give_sigsegv; |
139 | 143 | ||
140 | /* | 144 | install_sigtramp(frame->rs_code, __NR_N32_rt_sigreturn); |
141 | * Set up the return code ... | ||
142 | * | ||
143 | * li v0, __NR_rt_sigreturn | ||
144 | * syscall | ||
145 | */ | ||
146 | if (PLAT_TRAMPOLINE_STUFF_LINE) | ||
147 | __clear_user(frame->rs_code, PLAT_TRAMPOLINE_STUFF_LINE); | ||
148 | err |= __put_user(0x24020000 + __NR_N32_rt_sigreturn, frame->rs_code + 0); | ||
149 | err |= __put_user(0x0000000c , frame->rs_code + 1); | ||
150 | flush_cache_sigtramp((unsigned long) frame->rs_code); | ||
151 | 145 | ||
152 | /* Create siginfo. */ | 146 | /* Create siginfo. */ |
153 | err |= copy_siginfo_to_user(&frame->rs_info, info); | 147 | err |= copy_siginfo_to_user(&frame->rs_info, info); |
@@ -190,8 +184,9 @@ void setup_rt_frame_n32(struct k_sigaction * ka, | |||
190 | current->comm, current->pid, | 184 | current->comm, current->pid, |
191 | frame, regs->cp0_epc, regs->regs[31]); | 185 | frame, regs->cp0_epc, regs->regs[31]); |
192 | #endif | 186 | #endif |
193 | return; | 187 | return 1; |
194 | 188 | ||
195 | give_sigsegv: | 189 | give_sigsegv: |
196 | force_sigsegv(signr, current); | 190 | force_sigsegv(signr, current); |
191 | return 0; | ||
197 | } | 192 | } |