aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/ia32/ia32_signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/ia32/ia32_signal.c')
-rw-r--r--arch/x86/ia32/ia32_signal.c472
1 files changed, 236 insertions, 236 deletions
diff --git a/arch/x86/ia32/ia32_signal.c b/arch/x86/ia32/ia32_signal.c
index 6ea19c25f90d..1c0503bdfb1a 100644
--- a/arch/x86/ia32/ia32_signal.c
+++ b/arch/x86/ia32/ia32_signal.c
@@ -29,9 +29,8 @@
29#include <asm/ia32_unistd.h> 29#include <asm/ia32_unistd.h>
30#include <asm/user32.h> 30#include <asm/user32.h>
31#include <asm/sigcontext32.h> 31#include <asm/sigcontext32.h>
32#include <asm/fpu32.h>
33#include <asm/proto.h> 32#include <asm/proto.h>
34#include <asm/vsyscall32.h> 33#include <asm/vdso.h>
35 34
36#define DEBUG_SIG 0 35#define DEBUG_SIG 0
37 36
@@ -43,7 +42,8 @@ void signal_fault(struct pt_regs *regs, void __user *frame, char *where);
43int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from) 42int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
44{ 43{
45 int err; 44 int err;
46 if (!access_ok (VERIFY_WRITE, to, sizeof(compat_siginfo_t))) 45
46 if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))
47 return -EFAULT; 47 return -EFAULT;
48 48
49 /* If you change siginfo_t structure, please make sure that 49 /* If you change siginfo_t structure, please make sure that
@@ -53,16 +53,19 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
53 3 ints plus the relevant union member. */ 53 3 ints plus the relevant union member. */
54 err = __put_user(from->si_signo, &to->si_signo); 54 err = __put_user(from->si_signo, &to->si_signo);
55 err |= __put_user(from->si_errno, &to->si_errno); 55 err |= __put_user(from->si_errno, &to->si_errno);
56 err |= __put_user((short)from->si_code, &to->si_code); 56 err |= __put_user((short)from->si_code, &to->si_code);
57 57
58 if (from->si_code < 0) { 58 if (from->si_code < 0) {
59 err |= __put_user(from->si_pid, &to->si_pid); 59 err |= __put_user(from->si_pid, &to->si_pid);
60 err |= __put_user(from->si_uid, &to->si_uid); 60 err |= __put_user(from->si_uid, &to->si_uid);
61 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr); 61 err |= __put_user(ptr_to_compat(from->si_ptr), &to->si_ptr);
62 } else { 62 } else {
63 /* First 32bits of unions are always present: 63 /*
64 * si_pid === si_band === si_tid === si_addr(LS half) */ 64 * First 32bits of unions are always present:
65 err |= __put_user(from->_sifields._pad[0], &to->_sifields._pad[0]); 65 * si_pid === si_band === si_tid === si_addr(LS half)
66 */
67 err |= __put_user(from->_sifields._pad[0],
68 &to->_sifields._pad[0]);
66 switch (from->si_code >> 16) { 69 switch (from->si_code >> 16) {
67 case __SI_FAULT >> 16: 70 case __SI_FAULT >> 16:
68 break; 71 break;
@@ -76,14 +79,15 @@ int copy_siginfo_to_user32(compat_siginfo_t __user *to, siginfo_t *from)
76 err |= __put_user(from->si_uid, &to->si_uid); 79 err |= __put_user(from->si_uid, &to->si_uid);
77 break; 80 break;
78 case __SI_POLL >> 16: 81 case __SI_POLL >> 16:
79 err |= __put_user(from->si_fd, &to->si_fd); 82 err |= __put_user(from->si_fd, &to->si_fd);
80 break; 83 break;
81 case __SI_TIMER >> 16: 84 case __SI_TIMER >> 16:
82 err |= __put_user(from->si_overrun, &to->si_overrun); 85 err |= __put_user(from->si_overrun, &to->si_overrun);
83 err |= __put_user(ptr_to_compat(from->si_ptr), 86 err |= __put_user(ptr_to_compat(from->si_ptr),
84 &to->si_ptr); 87 &to->si_ptr);
85 break; 88 break;
86 case __SI_RT >> 16: /* This is not generated by the kernel as of now. */ 89 /* This is not generated by the kernel as of now. */
90 case __SI_RT >> 16:
87 case __SI_MESGQ >> 16: 91 case __SI_MESGQ >> 16:
88 err |= __put_user(from->si_uid, &to->si_uid); 92 err |= __put_user(from->si_uid, &to->si_uid);
89 err |= __put_user(from->si_int, &to->si_int); 93 err |= __put_user(from->si_int, &to->si_int);
@@ -97,7 +101,8 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
97{ 101{
98 int err; 102 int err;
99 u32 ptr32; 103 u32 ptr32;
100 if (!access_ok (VERIFY_READ, from, sizeof(compat_siginfo_t))) 104
105 if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))
101 return -EFAULT; 106 return -EFAULT;
102 107
103 err = __get_user(to->si_signo, &from->si_signo); 108 err = __get_user(to->si_signo, &from->si_signo);
@@ -112,8 +117,7 @@ int copy_siginfo_from_user32(siginfo_t *to, compat_siginfo_t __user *from)
112 return err; 117 return err;
113} 118}
114 119
115asmlinkage long 120asmlinkage long sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
116sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
117{ 121{
118 mask &= _BLOCKABLE; 122 mask &= _BLOCKABLE;
119 spin_lock_irq(&current->sighand->siglock); 123 spin_lock_irq(&current->sighand->siglock);
@@ -128,36 +132,37 @@ sys32_sigsuspend(int history0, int history1, old_sigset_t mask)
128 return -ERESTARTNOHAND; 132 return -ERESTARTNOHAND;
129} 133}
130 134
131asmlinkage long 135asmlinkage long sys32_sigaltstack(const stack_ia32_t __user *uss_ptr,
132sys32_sigaltstack(const stack_ia32_t __user *uss_ptr, 136 stack_ia32_t __user *uoss_ptr,
133 stack_ia32_t __user *uoss_ptr, 137 struct pt_regs *regs)
134 struct pt_regs *regs)
135{ 138{
136 stack_t uss,uoss; 139 stack_t uss, uoss;
137 int ret; 140 int ret;
138 mm_segment_t seg; 141 mm_segment_t seg;
139 if (uss_ptr) { 142
143 if (uss_ptr) {
140 u32 ptr; 144 u32 ptr;
141 memset(&uss,0,sizeof(stack_t)); 145
142 if (!access_ok(VERIFY_READ,uss_ptr,sizeof(stack_ia32_t)) || 146 memset(&uss, 0, sizeof(stack_t));
147 if (!access_ok(VERIFY_READ, uss_ptr, sizeof(stack_ia32_t)) ||
143 __get_user(ptr, &uss_ptr->ss_sp) || 148 __get_user(ptr, &uss_ptr->ss_sp) ||
144 __get_user(uss.ss_flags, &uss_ptr->ss_flags) || 149 __get_user(uss.ss_flags, &uss_ptr->ss_flags) ||
145 __get_user(uss.ss_size, &uss_ptr->ss_size)) 150 __get_user(uss.ss_size, &uss_ptr->ss_size))
146 return -EFAULT; 151 return -EFAULT;
147 uss.ss_sp = compat_ptr(ptr); 152 uss.ss_sp = compat_ptr(ptr);
148 } 153 }
149 seg = get_fs(); 154 seg = get_fs();
150 set_fs(KERNEL_DS); 155 set_fs(KERNEL_DS);
151 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->rsp); 156 ret = do_sigaltstack(uss_ptr ? &uss : NULL, &uoss, regs->sp);
152 set_fs(seg); 157 set_fs(seg);
153 if (ret >= 0 && uoss_ptr) { 158 if (ret >= 0 && uoss_ptr) {
154 if (!access_ok(VERIFY_WRITE,uoss_ptr,sizeof(stack_ia32_t)) || 159 if (!access_ok(VERIFY_WRITE, uoss_ptr, sizeof(stack_ia32_t)) ||
155 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) || 160 __put_user(ptr_to_compat(uoss.ss_sp), &uoss_ptr->ss_sp) ||
156 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) || 161 __put_user(uoss.ss_flags, &uoss_ptr->ss_flags) ||
157 __put_user(uoss.ss_size, &uoss_ptr->ss_size)) 162 __put_user(uoss.ss_size, &uoss_ptr->ss_size))
158 ret = -EFAULT; 163 ret = -EFAULT;
159 } 164 }
160 return ret; 165 return ret;
161} 166}
162 167
163/* 168/*
@@ -186,87 +191,85 @@ struct rt_sigframe
186 char retcode[8]; 191 char retcode[8];
187}; 192};
188 193
189static int 194#define COPY(x) { \
190ia32_restore_sigcontext(struct pt_regs *regs, struct sigcontext_ia32 __user *sc, unsigned int *peax) 195 unsigned int reg; \
196 err |= __get_user(reg, &sc->x); \
197 regs->x = reg; \
198}
199
200#define RELOAD_SEG(seg,mask) \
201 { unsigned int cur; \
202 unsigned short pre; \
203 err |= __get_user(pre, &sc->seg); \
204 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \
205 pre |= mask; \
206 if (pre != cur) loadsegment(seg, pre); }
207
208static int ia32_restore_sigcontext(struct pt_regs *regs,
209 struct sigcontext_ia32 __user *sc,
210 unsigned int *peax)
191{ 211{
192 unsigned int err = 0; 212 unsigned int tmpflags, gs, oldgs, err = 0;
193 213 struct _fpstate_ia32 __user *buf;
214 u32 tmp;
215
194 /* Always make any pending restarted system calls return -EINTR */ 216 /* Always make any pending restarted system calls return -EINTR */
195 current_thread_info()->restart_block.fn = do_no_restart_syscall; 217 current_thread_info()->restart_block.fn = do_no_restart_syscall;
196 218
197#if DEBUG_SIG 219#if DEBUG_SIG
198 printk("SIG restore_sigcontext: sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n", 220 printk(KERN_DEBUG "SIG restore_sigcontext: "
199 sc, sc->err, sc->eip, sc->cs, sc->eflags); 221 "sc=%p err(%x) eip(%x) cs(%x) flg(%x)\n",
222 sc, sc->err, sc->ip, sc->cs, sc->flags);
200#endif 223#endif
201#define COPY(x) { \
202 unsigned int reg; \
203 err |= __get_user(reg, &sc->e ##x); \
204 regs->r ## x = reg; \
205}
206 224
207#define RELOAD_SEG(seg,mask) \ 225 /*
208 { unsigned int cur; \ 226 * Reload fs and gs if they have changed in the signal
209 unsigned short pre; \ 227 * handler. This does not handle long fs/gs base changes in
210 err |= __get_user(pre, &sc->seg); \ 228 * the handler, but does not clobber them at least in the
211 asm volatile("movl %%" #seg ",%0" : "=r" (cur)); \ 229 * normal case.
212 pre |= mask; \ 230 */
213 if (pre != cur) loadsegment(seg,pre); } 231 err |= __get_user(gs, &sc->gs);
214 232 gs |= 3;
215 /* Reload fs and gs if they have changed in the signal handler. 233 asm("movl %%gs,%0" : "=r" (oldgs));
216 This does not handle long fs/gs base changes in the handler, but 234 if (gs != oldgs)
217 does not clobber them at least in the normal case. */ 235 load_gs_index(gs);
218 236
219 { 237 RELOAD_SEG(fs, 3);
220 unsigned gs, oldgs; 238 RELOAD_SEG(ds, 3);
221 err |= __get_user(gs, &sc->gs); 239 RELOAD_SEG(es, 3);
222 gs |= 3;
223 asm("movl %%gs,%0" : "=r" (oldgs));
224 if (gs != oldgs)
225 load_gs_index(gs);
226 }
227 RELOAD_SEG(fs,3);
228 RELOAD_SEG(ds,3);
229 RELOAD_SEG(es,3);
230 240
231 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx); 241 COPY(di); COPY(si); COPY(bp); COPY(sp); COPY(bx);
232 COPY(dx); COPY(cx); COPY(ip); 242 COPY(dx); COPY(cx); COPY(ip);
233 /* Don't touch extended registers */ 243 /* Don't touch extended registers */
234 244
235 err |= __get_user(regs->cs, &sc->cs); 245 err |= __get_user(regs->cs, &sc->cs);
236 regs->cs |= 3; 246 regs->cs |= 3;
237 err |= __get_user(regs->ss, &sc->ss); 247 err |= __get_user(regs->ss, &sc->ss);
238 regs->ss |= 3; 248 regs->ss |= 3;
239 249
240 { 250 err |= __get_user(tmpflags, &sc->flags);
241 unsigned int tmpflags; 251 regs->flags = (regs->flags & ~0x40DD5) | (tmpflags & 0x40DD5);
242 err |= __get_user(tmpflags, &sc->eflags); 252 /* disable syscall checks */
243 regs->eflags = (regs->eflags & ~0x40DD5) | (tmpflags & 0x40DD5); 253 regs->orig_ax = -1;
244 regs->orig_rax = -1; /* disable syscall checks */ 254
245 } 255 err |= __get_user(tmp, &sc->fpstate);
256 buf = compat_ptr(tmp);
257 if (buf) {
258 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
259 goto badframe;
260 err |= restore_i387_ia32(buf);
261 } else {
262 struct task_struct *me = current;
246 263
247 { 264 if (used_math()) {
248 u32 tmp; 265 clear_fpu(me);
249 struct _fpstate_ia32 __user * buf; 266 clear_used_math();
250 err |= __get_user(tmp, &sc->fpstate);
251 buf = compat_ptr(tmp);
252 if (buf) {
253 if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
254 goto badframe;
255 err |= restore_i387_ia32(current, buf, 0);
256 } else {
257 struct task_struct *me = current;
258 if (used_math()) {
259 clear_fpu(me);
260 clear_used_math();
261 }
262 } 267 }
263 } 268 }
264 269
265 { 270 err |= __get_user(tmp, &sc->ax);
266 u32 tmp; 271 *peax = tmp;
267 err |= __get_user(tmp, &sc->eax); 272
268 *peax = tmp;
269 }
270 return err; 273 return err;
271 274
272badframe: 275badframe:
@@ -275,15 +278,16 @@ badframe:
275 278
276asmlinkage long sys32_sigreturn(struct pt_regs *regs) 279asmlinkage long sys32_sigreturn(struct pt_regs *regs)
277{ 280{
278 struct sigframe __user *frame = (struct sigframe __user *)(regs->rsp-8); 281 struct sigframe __user *frame = (struct sigframe __user *)(regs->sp-8);
279 sigset_t set; 282 sigset_t set;
280 unsigned int eax; 283 unsigned int ax;
281 284
282 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 285 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
283 goto badframe; 286 goto badframe;
284 if (__get_user(set.sig[0], &frame->sc.oldmask) 287 if (__get_user(set.sig[0], &frame->sc.oldmask)
285 || (_COMPAT_NSIG_WORDS > 1 288 || (_COMPAT_NSIG_WORDS > 1
286 && __copy_from_user((((char *) &set.sig) + 4), &frame->extramask, 289 && __copy_from_user((((char *) &set.sig) + 4),
290 &frame->extramask,
287 sizeof(frame->extramask)))) 291 sizeof(frame->extramask))))
288 goto badframe; 292 goto badframe;
289 293
@@ -292,24 +296,24 @@ asmlinkage long sys32_sigreturn(struct pt_regs *regs)
292 current->blocked = set; 296 current->blocked = set;
293 recalc_sigpending(); 297 recalc_sigpending();
294 spin_unlock_irq(&current->sighand->siglock); 298 spin_unlock_irq(&current->sighand->siglock);
295 299
296 if (ia32_restore_sigcontext(regs, &frame->sc, &eax)) 300 if (ia32_restore_sigcontext(regs, &frame->sc, &ax))
297 goto badframe; 301 goto badframe;
298 return eax; 302 return ax;
299 303
300badframe: 304badframe:
301 signal_fault(regs, frame, "32bit sigreturn"); 305 signal_fault(regs, frame, "32bit sigreturn");
302 return 0; 306 return 0;
303} 307}
304 308
305asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs) 309asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
306{ 310{
307 struct rt_sigframe __user *frame; 311 struct rt_sigframe __user *frame;
308 sigset_t set; 312 sigset_t set;
309 unsigned int eax; 313 unsigned int ax;
310 struct pt_regs tregs; 314 struct pt_regs tregs;
311 315
312 frame = (struct rt_sigframe __user *)(regs->rsp - 4); 316 frame = (struct rt_sigframe __user *)(regs->sp - 4);
313 317
314 if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) 318 if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
315 goto badframe; 319 goto badframe;
@@ -321,28 +325,28 @@ asmlinkage long sys32_rt_sigreturn(struct pt_regs *regs)
321 current->blocked = set; 325 current->blocked = set;
322 recalc_sigpending(); 326 recalc_sigpending();
323 spin_unlock_irq(&current->sighand->siglock); 327 spin_unlock_irq(&current->sighand->siglock);
324 328
325 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &eax)) 329 if (ia32_restore_sigcontext(regs, &frame->uc.uc_mcontext, &ax))
326 goto badframe; 330 goto badframe;
327 331
328 tregs = *regs; 332 tregs = *regs;
329 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT) 333 if (sys32_sigaltstack(&frame->uc.uc_stack, NULL, &tregs) == -EFAULT)
330 goto badframe; 334 goto badframe;
331 335
332 return eax; 336 return ax;
333 337
334badframe: 338badframe:
335 signal_fault(regs,frame,"32bit rt sigreturn"); 339 signal_fault(regs, frame, "32bit rt sigreturn");
336 return 0; 340 return 0;
337} 341}
338 342
339/* 343/*
340 * Set up a signal frame. 344 * Set up a signal frame.
341 */ 345 */
342 346
343static int 347static int ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc,
344ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __user *fpstate, 348 struct _fpstate_ia32 __user *fpstate,
345 struct pt_regs *regs, unsigned int mask) 349 struct pt_regs *regs, unsigned int mask)
346{ 350{
347 int tmp, err = 0; 351 int tmp, err = 0;
348 352
@@ -356,26 +360,26 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
356 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp)); 360 __asm__("movl %%es,%0" : "=r"(tmp): "0"(tmp));
357 err |= __put_user(tmp, (unsigned int __user *)&sc->es); 361 err |= __put_user(tmp, (unsigned int __user *)&sc->es);
358 362
359 err |= __put_user((u32)regs->rdi, &sc->edi); 363 err |= __put_user((u32)regs->di, &sc->di);
360 err |= __put_user((u32)regs->rsi, &sc->esi); 364 err |= __put_user((u32)regs->si, &sc->si);
361 err |= __put_user((u32)regs->rbp, &sc->ebp); 365 err |= __put_user((u32)regs->bp, &sc->bp);
362 err |= __put_user((u32)regs->rsp, &sc->esp); 366 err |= __put_user((u32)regs->sp, &sc->sp);
363 err |= __put_user((u32)regs->rbx, &sc->ebx); 367 err |= __put_user((u32)regs->bx, &sc->bx);
364 err |= __put_user((u32)regs->rdx, &sc->edx); 368 err |= __put_user((u32)regs->dx, &sc->dx);
365 err |= __put_user((u32)regs->rcx, &sc->ecx); 369 err |= __put_user((u32)regs->cx, &sc->cx);
366 err |= __put_user((u32)regs->rax, &sc->eax); 370 err |= __put_user((u32)regs->ax, &sc->ax);
367 err |= __put_user((u32)regs->cs, &sc->cs); 371 err |= __put_user((u32)regs->cs, &sc->cs);
368 err |= __put_user((u32)regs->ss, &sc->ss); 372 err |= __put_user((u32)regs->ss, &sc->ss);
369 err |= __put_user(current->thread.trap_no, &sc->trapno); 373 err |= __put_user(current->thread.trap_no, &sc->trapno);
370 err |= __put_user(current->thread.error_code, &sc->err); 374 err |= __put_user(current->thread.error_code, &sc->err);
371 err |= __put_user((u32)regs->rip, &sc->eip); 375 err |= __put_user((u32)regs->ip, &sc->ip);
372 err |= __put_user((u32)regs->eflags, &sc->eflags); 376 err |= __put_user((u32)regs->flags, &sc->flags);
373 err |= __put_user((u32)regs->rsp, &sc->esp_at_signal); 377 err |= __put_user((u32)regs->sp, &sc->sp_at_signal);
374 378
375 tmp = save_i387_ia32(current, fpstate, regs, 0); 379 tmp = save_i387_ia32(fpstate);
376 if (tmp < 0) 380 if (tmp < 0)
377 err = -EFAULT; 381 err = -EFAULT;
378 else { 382 else {
379 clear_used_math(); 383 clear_used_math();
380 stts(); 384 stts();
381 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL), 385 err |= __put_user(ptr_to_compat(tmp ? fpstate : NULL),
@@ -392,40 +396,53 @@ ia32_setup_sigcontext(struct sigcontext_ia32 __user *sc, struct _fpstate_ia32 __
392/* 396/*
393 * Determine which stack to use.. 397 * Determine which stack to use..
394 */ 398 */
395static void __user * 399static void __user *get_sigframe(struct k_sigaction *ka, struct pt_regs *regs,
396get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) 400 size_t frame_size)
397{ 401{
398 unsigned long rsp; 402 unsigned long sp;
399 403
400 /* Default to using normal stack */ 404 /* Default to using normal stack */
401 rsp = regs->rsp; 405 sp = regs->sp;
402 406
403 /* This is the X/Open sanctioned signal stack switching. */ 407 /* This is the X/Open sanctioned signal stack switching. */
404 if (ka->sa.sa_flags & SA_ONSTACK) { 408 if (ka->sa.sa_flags & SA_ONSTACK) {
405 if (sas_ss_flags(rsp) == 0) 409 if (sas_ss_flags(sp) == 0)
406 rsp = current->sas_ss_sp + current->sas_ss_size; 410 sp = current->sas_ss_sp + current->sas_ss_size;
407 } 411 }
408 412
409 /* This is the legacy signal stack switching. */ 413 /* This is the legacy signal stack switching. */
410 else if ((regs->ss & 0xffff) != __USER_DS && 414 else if ((regs->ss & 0xffff) != __USER_DS &&
411 !(ka->sa.sa_flags & SA_RESTORER) && 415 !(ka->sa.sa_flags & SA_RESTORER) &&
412 ka->sa.sa_restorer) { 416 ka->sa.sa_restorer)
413 rsp = (unsigned long) ka->sa.sa_restorer; 417 sp = (unsigned long) ka->sa.sa_restorer;
414 }
415 418
416 rsp -= frame_size; 419 sp -= frame_size;
417 /* Align the stack pointer according to the i386 ABI, 420 /* Align the stack pointer according to the i386 ABI,
418 * i.e. so that on function entry ((sp + 4) & 15) == 0. */ 421 * i.e. so that on function entry ((sp + 4) & 15) == 0. */
419 rsp = ((rsp + 4) & -16ul) - 4; 422 sp = ((sp + 4) & -16ul) - 4;
420 return (void __user *) rsp; 423 return (void __user *) sp;
421} 424}
422 425
423int ia32_setup_frame(int sig, struct k_sigaction *ka, 426int ia32_setup_frame(int sig, struct k_sigaction *ka,
424 compat_sigset_t *set, struct pt_regs * regs) 427 compat_sigset_t *set, struct pt_regs *regs)
425{ 428{
426 struct sigframe __user *frame; 429 struct sigframe __user *frame;
430 void __user *restorer;
427 int err = 0; 431 int err = 0;
428 432
433 /* copy_to_user optimizes that into a single 8 byte store */
434 static const struct {
435 u16 poplmovl;
436 u32 val;
437 u16 int80;
438 u16 pad;
439 } __attribute__((packed)) code = {
440 0xb858, /* popl %eax ; movl $...,%eax */
441 __NR_ia32_sigreturn,
442 0x80cd, /* int $0x80 */
443 0,
444 };
445
429 frame = get_sigframe(ka, regs, sizeof(*frame)); 446 frame = get_sigframe(ka, regs, sizeof(*frame));
430 447
431 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 448 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
@@ -443,64 +460,53 @@ int ia32_setup_frame(int sig, struct k_sigaction *ka,
443 if (_COMPAT_NSIG_WORDS > 1) { 460 if (_COMPAT_NSIG_WORDS > 1) {
444 err |= __copy_to_user(frame->extramask, &set->sig[1], 461 err |= __copy_to_user(frame->extramask, &set->sig[1],
445 sizeof(frame->extramask)); 462 sizeof(frame->extramask));
463 if (err)
464 goto give_sigsegv;
446 } 465 }
447 if (err)
448 goto give_sigsegv;
449 466
450 /* Return stub is in 32bit vsyscall page */ 467 if (ka->sa.sa_flags & SA_RESTORER) {
451 { 468 restorer = ka->sa.sa_restorer;
452 void __user *restorer; 469 } else {
470 /* Return stub is in 32bit vsyscall page */
453 if (current->binfmt->hasvdso) 471 if (current->binfmt->hasvdso)
454 restorer = VSYSCALL32_SIGRETURN; 472 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
473 sigreturn);
455 else 474 else
456 restorer = (void *)&frame->retcode; 475 restorer = &frame->retcode;
457 if (ka->sa.sa_flags & SA_RESTORER)
458 restorer = ka->sa.sa_restorer;
459 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
460 }
461 /* These are actually not used anymore, but left because some
462 gdb versions depend on them as a marker. */
463 {
464 /* copy_to_user optimizes that into a single 8 byte store */
465 static const struct {
466 u16 poplmovl;
467 u32 val;
468 u16 int80;
469 u16 pad;
470 } __attribute__((packed)) code = {
471 0xb858, /* popl %eax ; movl $...,%eax */
472 __NR_ia32_sigreturn,
473 0x80cd, /* int $0x80 */
474 0,
475 };
476 err |= __copy_to_user(frame->retcode, &code, 8);
477 } 476 }
477 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
478
479 /*
480 * These are actually not used anymore, but left because some
481 * gdb versions depend on them as a marker.
482 */
483 err |= __copy_to_user(frame->retcode, &code, 8);
478 if (err) 484 if (err)
479 goto give_sigsegv; 485 goto give_sigsegv;
480 486
481 /* Set up registers for signal handler */ 487 /* Set up registers for signal handler */
482 regs->rsp = (unsigned long) frame; 488 regs->sp = (unsigned long) frame;
483 regs->rip = (unsigned long) ka->sa.sa_handler; 489 regs->ip = (unsigned long) ka->sa.sa_handler;
484 490
485 /* Make -mregparm=3 work */ 491 /* Make -mregparm=3 work */
486 regs->rax = sig; 492 regs->ax = sig;
487 regs->rdx = 0; 493 regs->dx = 0;
488 regs->rcx = 0; 494 regs->cx = 0;
489 495
490 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 496 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
491 asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 497 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
492 498
493 regs->cs = __USER32_CS; 499 regs->cs = __USER32_CS;
494 regs->ss = __USER32_DS; 500 regs->ss = __USER32_DS;
495 501
496 set_fs(USER_DS); 502 set_fs(USER_DS);
497 regs->eflags &= ~TF_MASK; 503 regs->flags &= ~X86_EFLAGS_TF;
498 if (test_thread_flag(TIF_SINGLESTEP)) 504 if (test_thread_flag(TIF_SINGLESTEP))
499 ptrace_notify(SIGTRAP); 505 ptrace_notify(SIGTRAP);
500 506
501#if DEBUG_SIG 507#if DEBUG_SIG
502 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", 508 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
503 current->comm, current->pid, frame, regs->rip, frame->pretcode); 509 current->comm, current->pid, frame, regs->ip, frame->pretcode);
504#endif 510#endif
505 511
506 return 0; 512 return 0;
@@ -511,25 +517,34 @@ give_sigsegv:
511} 517}
512 518
513int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, 519int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
514 compat_sigset_t *set, struct pt_regs * regs) 520 compat_sigset_t *set, struct pt_regs *regs)
515{ 521{
516 struct rt_sigframe __user *frame; 522 struct rt_sigframe __user *frame;
523 struct exec_domain *ed = current_thread_info()->exec_domain;
524 void __user *restorer;
517 int err = 0; 525 int err = 0;
518 526
527 /* __copy_to_user optimizes that into a single 8 byte store */
528 static const struct {
529 u8 movl;
530 u32 val;
531 u16 int80;
532 u16 pad;
533 u8 pad2;
534 } __attribute__((packed)) code = {
535 0xb8,
536 __NR_ia32_rt_sigreturn,
537 0x80cd,
538 0,
539 };
540
519 frame = get_sigframe(ka, regs, sizeof(*frame)); 541 frame = get_sigframe(ka, regs, sizeof(*frame));
520 542
521 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 543 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
522 goto give_sigsegv; 544 goto give_sigsegv;
523 545
524 { 546 err |= __put_user((ed && ed->signal_invmap && sig < 32
525 struct exec_domain *ed = current_thread_info()->exec_domain; 547 ? ed->signal_invmap[sig] : sig), &frame->sig);
526 err |= __put_user((ed
527 && ed->signal_invmap
528 && sig < 32
529 ? ed->signal_invmap[sig]
530 : sig),
531 &frame->sig);
532 }
533 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo); 548 err |= __put_user(ptr_to_compat(&frame->info), &frame->pinfo);
534 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc); 549 err |= __put_user(ptr_to_compat(&frame->uc), &frame->puc);
535 err |= copy_siginfo_to_user32(&frame->info, info); 550 err |= copy_siginfo_to_user32(&frame->info, info);
@@ -540,73 +555,58 @@ int ia32_setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
540 err |= __put_user(0, &frame->uc.uc_flags); 555 err |= __put_user(0, &frame->uc.uc_flags);
541 err |= __put_user(0, &frame->uc.uc_link); 556 err |= __put_user(0, &frame->uc.uc_link);
542 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp); 557 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
543 err |= __put_user(sas_ss_flags(regs->rsp), 558 err |= __put_user(sas_ss_flags(regs->sp),
544 &frame->uc.uc_stack.ss_flags); 559 &frame->uc.uc_stack.ss_flags);
545 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size); 560 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
546 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate, 561 err |= ia32_setup_sigcontext(&frame->uc.uc_mcontext, &frame->fpstate,
547 regs, set->sig[0]); 562 regs, set->sig[0]);
548 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); 563 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
549 if (err) 564 if (err)
550 goto give_sigsegv; 565 goto give_sigsegv;
551 566
552 567 if (ka->sa.sa_flags & SA_RESTORER)
553 { 568 restorer = ka->sa.sa_restorer;
554 void __user *restorer = VSYSCALL32_RTSIGRETURN; 569 else
555 if (ka->sa.sa_flags & SA_RESTORER) 570 restorer = VDSO32_SYMBOL(current->mm->context.vdso,
556 restorer = ka->sa.sa_restorer; 571 rt_sigreturn);
557 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode); 572 err |= __put_user(ptr_to_compat(restorer), &frame->pretcode);
558 } 573
559 574 /*
560 /* This is movl $,%eax ; int $0x80 */ 575 * Not actually used anymore, but left because some gdb
561 /* Not actually used anymore, but left because some gdb versions 576 * versions need it.
562 need it. */ 577 */
563 { 578 err |= __copy_to_user(frame->retcode, &code, 8);
564 /* __copy_to_user optimizes that into a single 8 byte store */
565 static const struct {
566 u8 movl;
567 u32 val;
568 u16 int80;
569 u16 pad;
570 u8 pad2;
571 } __attribute__((packed)) code = {
572 0xb8,
573 __NR_ia32_rt_sigreturn,
574 0x80cd,
575 0,
576 };
577 err |= __copy_to_user(frame->retcode, &code, 8);
578 }
579 if (err) 579 if (err)
580 goto give_sigsegv; 580 goto give_sigsegv;
581 581
582 /* Set up registers for signal handler */ 582 /* Set up registers for signal handler */
583 regs->rsp = (unsigned long) frame; 583 regs->sp = (unsigned long) frame;
584 regs->rip = (unsigned long) ka->sa.sa_handler; 584 regs->ip = (unsigned long) ka->sa.sa_handler;
585 585
586 /* Make -mregparm=3 work */ 586 /* Make -mregparm=3 work */
587 regs->rax = sig; 587 regs->ax = sig;
588 regs->rdx = (unsigned long) &frame->info; 588 regs->dx = (unsigned long) &frame->info;
589 regs->rcx = (unsigned long) &frame->uc; 589 regs->cx = (unsigned long) &frame->uc;
590 590
591 /* Make -mregparm=3 work */ 591 /* Make -mregparm=3 work */
592 regs->rax = sig; 592 regs->ax = sig;
593 regs->rdx = (unsigned long) &frame->info; 593 regs->dx = (unsigned long) &frame->info;
594 regs->rcx = (unsigned long) &frame->uc; 594 regs->cx = (unsigned long) &frame->uc;
595
596 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS));
597 asm volatile("movl %0,%%es" :: "r" (__USER32_DS));
595 598
596 asm volatile("movl %0,%%ds" :: "r" (__USER32_DS)); 599 regs->cs = __USER32_CS;
597 asm volatile("movl %0,%%es" :: "r" (__USER32_DS)); 600 regs->ss = __USER32_DS;
598
599 regs->cs = __USER32_CS;
600 regs->ss = __USER32_DS;
601 601
602 set_fs(USER_DS); 602 set_fs(USER_DS);
603 regs->eflags &= ~TF_MASK; 603 regs->flags &= ~X86_EFLAGS_TF;
604 if (test_thread_flag(TIF_SINGLESTEP)) 604 if (test_thread_flag(TIF_SINGLESTEP))
605 ptrace_notify(SIGTRAP); 605 ptrace_notify(SIGTRAP);
606 606
607#if DEBUG_SIG 607#if DEBUG_SIG
608 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n", 608 printk(KERN_DEBUG "SIG deliver (%s:%d): sp=%p pc=%lx ra=%u\n",
609 current->comm, current->pid, frame, regs->rip, frame->pretcode); 609 current->comm, current->pid, frame, regs->ip, frame->pretcode);
610#endif 610#endif
611 611
612 return 0; 612 return 0;