diff options
Diffstat (limited to 'arch/mips/kernel/signal_n32.c')
-rw-r--r-- | arch/mips/kernel/signal_n32.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/arch/mips/kernel/signal_n32.c b/arch/mips/kernel/signal_n32.c index a67c18555ed3..7ca2a078841f 100644 --- a/arch/mips/kernel/signal_n32.c +++ b/arch/mips/kernel/signal_n32.c | |||
@@ -31,6 +31,7 @@ | |||
31 | 31 | ||
32 | #include <asm/asm.h> | 32 | #include <asm/asm.h> |
33 | #include <asm/cacheflush.h> | 33 | #include <asm/cacheflush.h> |
34 | #include <asm/compat-signal.h> | ||
34 | #include <asm/sim.h> | 35 | #include <asm/sim.h> |
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
36 | #include <asm/ucontext.h> | 37 | #include <asm/ucontext.h> |
@@ -47,9 +48,9 @@ | |||
47 | #define __NR_N32_rt_sigreturn 6211 | 48 | #define __NR_N32_rt_sigreturn 6211 |
48 | #define __NR_N32_restart_syscall 6214 | 49 | #define __NR_N32_restart_syscall 6214 |
49 | 50 | ||
50 | #define DEBUG_SIG 0 | 51 | extern int setup_sigcontext(struct pt_regs *, struct sigcontext __user *); |
52 | extern int restore_sigcontext(struct pt_regs *, struct sigcontext __user *); | ||
51 | 53 | ||
52 | #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) | ||
53 | 54 | ||
54 | /* IRIX compatible stack_t */ | 55 | /* IRIX compatible stack_t */ |
55 | typedef struct sigaltstack32 { | 56 | typedef struct sigaltstack32 { |
@@ -63,28 +64,33 @@ struct ucontextn32 { | |||
63 | s32 uc_link; | 64 | s32 uc_link; |
64 | stack32_t uc_stack; | 65 | stack32_t uc_stack; |
65 | struct sigcontext uc_mcontext; | 66 | struct sigcontext uc_mcontext; |
66 | sigset_t uc_sigmask; /* mask last for extensibility */ | 67 | compat_sigset_t uc_sigmask; /* mask last for extensibility */ |
67 | }; | 68 | }; |
68 | 69 | ||
70 | #if ICACHE_REFILLS_WORKAROUND_WAR == 0 | ||
71 | |||
69 | struct rt_sigframe_n32 { | 72 | struct rt_sigframe_n32 { |
70 | u32 rs_ass[4]; /* argument save space for o32 */ | 73 | u32 rs_ass[4]; /* argument save space for o32 */ |
71 | #if ICACHE_REFILLS_WORKAROUND_WAR | ||
72 | u32 rs_pad[2]; | ||
73 | #else | ||
74 | u32 rs_code[2]; /* signal trampoline */ | 74 | u32 rs_code[2]; /* signal trampoline */ |
75 | #endif | ||
76 | struct siginfo rs_info; | 75 | struct siginfo rs_info; |
77 | struct ucontextn32 rs_uc; | 76 | struct ucontextn32 rs_uc; |
78 | #if ICACHE_REFILLS_WORKAROUND_WAR | 77 | }; |
78 | |||
79 | #else /* ICACHE_REFILLS_WORKAROUND_WAR */ | ||
80 | |||
81 | struct rt_sigframe_n32 { | ||
82 | u32 rs_ass[4]; /* argument save space for o32 */ | ||
83 | u32 rs_pad[2]; | ||
84 | struct siginfo rs_info; | ||
85 | struct ucontextn32 rs_uc; | ||
79 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ | 86 | u32 rs_code[8] ____cacheline_aligned; /* signal trampoline */ |
80 | #endif | ||
81 | }; | 87 | }; |
82 | 88 | ||
89 | #endif /* !ICACHE_REFILLS_WORKAROUND_WAR */ | ||
90 | |||
83 | extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); | 91 | extern void sigset_from_compat (sigset_t *set, compat_sigset_t *compat); |
84 | 92 | ||
85 | save_static_function(sysn32_rt_sigsuspend); | 93 | asmlinkage int sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) |
86 | __attribute_used__ noinline static int | ||
87 | _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | ||
88 | { | 94 | { |
89 | compat_sigset_t __user *unewset; | 95 | compat_sigset_t __user *unewset; |
90 | compat_sigset_t uset; | 96 | compat_sigset_t uset; |
@@ -105,7 +111,7 @@ _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | |||
105 | spin_lock_irq(¤t->sighand->siglock); | 111 | spin_lock_irq(¤t->sighand->siglock); |
106 | current->saved_sigmask = current->blocked; | 112 | current->saved_sigmask = current->blocked; |
107 | current->blocked = newset; | 113 | current->blocked = newset; |
108 | recalc_sigpending(); | 114 | recalc_sigpending(); |
109 | spin_unlock_irq(¤t->sighand->siglock); | 115 | spin_unlock_irq(¤t->sighand->siglock); |
110 | 116 | ||
111 | current->state = TASK_INTERRUPTIBLE; | 117 | current->state = TASK_INTERRUPTIBLE; |
@@ -114,9 +120,7 @@ _sysn32_rt_sigsuspend(nabi_no_regargs struct pt_regs regs) | |||
114 | return -ERESTARTNOHAND; | 120 | return -ERESTARTNOHAND; |
115 | } | 121 | } |
116 | 122 | ||
117 | save_static_function(sysn32_rt_sigreturn); | 123 | asmlinkage void sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) |
118 | __attribute_used__ noinline static void | ||
119 | _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | ||
120 | { | 124 | { |
121 | struct rt_sigframe_n32 __user *frame; | 125 | struct rt_sigframe_n32 __user *frame; |
122 | sigset_t set; | 126 | sigset_t set; |
@@ -126,7 +130,7 @@ _sysn32_rt_sigreturn(nabi_no_regargs struct pt_regs regs) | |||
126 | frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; | 130 | frame = (struct rt_sigframe_n32 __user *) regs.regs[29]; |
127 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) | 131 | if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) |
128 | goto badframe; | 132 | goto badframe; |
129 | if (__copy_from_user(&set, &frame->rs_uc.uc_sigmask, sizeof(set))) | 133 | if (__copy_conv_sigset_from_user(&set, &frame->rs_uc.uc_sigmask)) |
130 | goto badframe; | 134 | goto badframe; |
131 | 135 | ||
132 | sigdelsetmask(&set, ~_BLOCKABLE); | 136 | sigdelsetmask(&set, ~_BLOCKABLE); |
@@ -184,7 +188,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka, | |||
184 | /* Create the ucontext. */ | 188 | /* Create the ucontext. */ |
185 | err |= __put_user(0, &frame->rs_uc.uc_flags); | 189 | err |= __put_user(0, &frame->rs_uc.uc_flags); |
186 | err |= __put_user(0, &frame->rs_uc.uc_link); | 190 | err |= __put_user(0, &frame->rs_uc.uc_link); |
187 | sp = (int) (long) current->sas_ss_sp; | 191 | sp = (int) (long) current->sas_ss_sp; |
188 | err |= __put_user(sp, | 192 | err |= __put_user(sp, |
189 | &frame->rs_uc.uc_stack.ss_sp); | 193 | &frame->rs_uc.uc_stack.ss_sp); |
190 | err |= __put_user(sas_ss_flags(regs->regs[29]), | 194 | err |= __put_user(sas_ss_flags(regs->regs[29]), |
@@ -192,7 +196,7 @@ int setup_rt_frame_n32(struct k_sigaction * ka, | |||
192 | err |= __put_user(current->sas_ss_size, | 196 | err |= __put_user(current->sas_ss_size, |
193 | &frame->rs_uc.uc_stack.ss_size); | 197 | &frame->rs_uc.uc_stack.ss_size); |
194 | err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); | 198 | err |= setup_sigcontext(regs, &frame->rs_uc.uc_mcontext); |
195 | err |= __copy_to_user(&frame->rs_uc.uc_sigmask, set, sizeof(*set)); | 199 | err |= __copy_conv_sigset_to_user(&frame->rs_uc.uc_sigmask, set); |
196 | 200 | ||
197 | if (err) | 201 | if (err) |
198 | goto give_sigsegv; | 202 | goto give_sigsegv; |
@@ -214,11 +218,10 @@ int setup_rt_frame_n32(struct k_sigaction * ka, | |||
214 | regs->regs[31] = (unsigned long) frame->rs_code; | 218 | regs->regs[31] = (unsigned long) frame->rs_code; |
215 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; | 219 | regs->cp0_epc = regs->regs[25] = (unsigned long) ka->sa.sa_handler; |
216 | 220 | ||
217 | #if DEBUG_SIG | 221 | DEBUGP("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%lx\n", |
218 | printk("SIG deliver (%s:%d): sp=0x%p pc=0x%lx ra=0x%p\n", | ||
219 | current->comm, current->pid, | 222 | current->comm, current->pid, |
220 | frame, regs->cp0_epc, regs->regs[31]); | 223 | frame, regs->cp0_epc, regs->regs[31]); |
221 | #endif | 224 | |
222 | return 0; | 225 | return 0; |
223 | 226 | ||
224 | give_sigsegv: | 227 | give_sigsegv: |