File: /usr/src/linux/arch/ia64/ia32/ia32_signal.c
1 /*
2 * IA32 Architecture-specific signal handling support.
3 *
4 * Copyright (C) 1999 Hewlett-Packard Co
5 * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
6 * Copyright (C) 1999 Arun Sharma <arun.sharma@intel.com>
7 * Copyright (C) 2000 VA Linux Co
8 * Copyright (C) 2000 Don Dugger <n0ano@valinux.com>
9 *
10 * Derived from i386 and Alpha versions.
11 */
12
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/ptrace.h>
17 #include <linux/sched.h>
18 #include <linux/signal.h>
19 #include <linux/smp.h>
20 #include <linux/smp_lock.h>
21 #include <linux/stddef.h>
22 #include <linux/unistd.h>
23 #include <linux/wait.h>
24
25 #include <asm/uaccess.h>
26 #include <asm/rse.h>
27 #include <asm/sigcontext.h>
28 #include <asm/segment.h>
29 #include <asm/ia32.h>
30
31 #define DEBUG_SIG 0
32 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
33
34
35 struct sigframe_ia32
36 {
37 int pretcode;
38 int sig;
39 struct sigcontext_ia32 sc;
40 struct _fpstate_ia32 fpstate;
41 unsigned int extramask[_IA32_NSIG_WORDS-1];
42 char retcode[8];
43 };
44
45 struct rt_sigframe_ia32
46 {
47 int pretcode;
48 int sig;
49 int pinfo;
50 int puc;
51 siginfo_t32 info;
52 struct ucontext_ia32 uc;
53 struct _fpstate_ia32 fpstate;
54 char retcode[8];
55 };
56
57 static int
58 copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from)
59 {
60 int err;
61
62 if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t32)))
63 return -EFAULT;
64
65 /* If you change siginfo_t structure, please be sure
66 this code is fixed accordingly.
67 It should never copy any pad contained in the structure
68 to avoid security leaks, but must copy the generic
69 3 ints plus the relevant union member.
70 This routine must convert siginfo from 64bit to 32bit as well
71 at the same time. */
72 err = __put_user(from->si_signo, &to->si_signo);
73 err |= __put_user(from->si_errno, &to->si_errno);
74 err |= __put_user((short)from->si_code, &to->si_code);
75 if (from->si_code < 0)
76 err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
77 else {
78 switch (from->si_code >> 16) {
79 case __SI_CHLD >> 16:
80 err |= __put_user(from->si_utime, &to->si_utime);
81 err |= __put_user(from->si_stime, &to->si_stime);
82 err |= __put_user(from->si_status, &to->si_status);
83 default:
84 err |= __put_user(from->si_pid, &to->si_pid);
85 err |= __put_user(from->si_uid, &to->si_uid);
86 break;
87 case __SI_FAULT >> 16:
88 err |= __put_user((long)from->si_addr, &to->si_addr);
89 break;
90 case __SI_POLL >> 16:
91 err |= __put_user(from->si_band, &to->si_band);
92 err |= __put_user(from->si_fd, &to->si_fd);
93 break;
94 /* case __SI_RT: This is not generated by the kernel as of now. */
95 }
96 }
97 return err;
98 }
99
100
101
102 static int
103 setup_sigcontext_ia32(struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
104 struct pt_regs *regs, unsigned long mask)
105 {
106 int err = 0;
107 unsigned long flag;
108
109 err |= __put_user((regs->r16 >> 32) & 0xffff , (unsigned int *)&sc->fs);
110 err |= __put_user((regs->r16 >> 48) & 0xffff , (unsigned int *)&sc->gs);
111
112 err |= __put_user((regs->r16 >> 56) & 0xffff, (unsigned int *)&sc->es);
113 err |= __put_user(regs->r16 & 0xffff, (unsigned int *)&sc->ds);
114 err |= __put_user(regs->r15, &sc->edi);
115 err |= __put_user(regs->r14, &sc->esi);
116 err |= __put_user(regs->r13, &sc->ebp);
117 err |= __put_user(regs->r12, &sc->esp);
118 err |= __put_user(regs->r11, &sc->ebx);
119 err |= __put_user(regs->r10, &sc->edx);
120 err |= __put_user(regs->r9, &sc->ecx);
121 err |= __put_user(regs->r8, &sc->eax);
122 #if 0
123 err |= __put_user(current->tss.trap_no, &sc->trapno);
124 err |= __put_user(current->tss.error_code, &sc->err);
125 #endif
126 err |= __put_user(regs->cr_iip, &sc->eip);
127 err |= __put_user(regs->r17 & 0xffff, (unsigned int *)&sc->cs);
128 /*
129 * `eflags' is in an ar register for this context
130 */
131 asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
132 err |= __put_user((unsigned int)flag, &sc->eflags);
133
134 err |= __put_user(regs->r12, &sc->esp_at_signal);
135 err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int *)&sc->ss);
136
137 #if 0
138 tmp = save_i387(fpstate);
139 if (tmp < 0)
140 err = 1;
141 else
142 err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
143
144 /* non-iBCS2 extensions.. */
145 #endif
146 err |= __put_user(mask, &sc->oldmask);
147 #if 0
148 err |= __put_user(current->tss.cr2, &sc->cr2);
149 #endif
150
151 return err;
152 }
153
154 static int
155 restore_sigcontext_ia32(struct pt_regs *regs, struct sigcontext_ia32 *sc, int *peax)
156 {
157 unsigned int err = 0;
158
159 #define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x)
160
161 #define copyseg_gs(tmp) (regs->r16 |= (unsigned long) tmp << 48)
162 #define copyseg_fs(tmp) (regs->r16 |= (unsigned long) tmp << 32)
163 #define copyseg_cs(tmp) (regs->r17 |= tmp)
164 #define copyseg_ss(tmp) (regs->r17 |= (unsigned long) tmp << 16)
165 #define copyseg_es(tmp) (regs->r16 |= (unsigned long) tmp << 16)
166 #define copyseg_ds(tmp) (regs->r16 |= tmp)
167
168 #define COPY_SEG(seg) \
169 { unsigned short tmp; \
170 err |= __get_user(tmp, &sc->seg); \
171 copyseg_##seg(tmp); }
172
173 #define COPY_SEG_STRICT(seg) \
174 { unsigned short tmp; \
175 err |= __get_user(tmp, &sc->seg); \
176 copyseg_##seg(tmp|3); }
177
178 /* To make COPY_SEGs easier, we zero r16, r17 */
179 regs->r16 = 0;
180 regs->r17 = 0;
181
182 COPY_SEG(gs);
183 COPY_SEG(fs);
184 COPY_SEG(es);
185 COPY_SEG(ds);
186 COPY(r15, edi);
187 COPY(r14, esi);
188 COPY(r13, ebp);
189 COPY(r12, esp);
190 COPY(r11, ebx);
191 COPY(r10, edx);
192 COPY(r9, ecx);
193 COPY(cr_iip, eip);
194 COPY_SEG_STRICT(cs);
195 COPY_SEG_STRICT(ss);
196 {
197 unsigned int tmpflags;
198 unsigned long flag;
199
200 /*
201 * IA32 `eflags' is not part of `pt_regs', it's
202 * in an ar register which is part of the thread
203 * context. Fortunately, we are executing in the
204 * IA32 process's context.
205 */
206 err |= __get_user(tmpflags, &sc->eflags);
207 asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
208 flag &= ~0x40DD5;
209 flag |= (tmpflags & 0x40DD5);
210 asm volatile ("mov ar.eflag=%0 ;;" :: "r"(flag));
211
212 regs->r1 = -1; /* disable syscall checks, r1 is orig_eax */
213 }
214
215 #if 0
216 {
217 struct _fpstate * buf;
218 err |= __get_user(buf, &sc->fpstate);
219 if (buf) {
220 if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
221 goto badframe;
222 err |= restore_i387(buf);
223 }
224 }
225 #endif
226
227 err |= __get_user(*peax, &sc->eax);
228 return err;
229
230 #if 0
231 badframe:
232 return 1;
233 #endif
234
235 }
236
237 /*
238 * Determine which stack to use..
239 */
240 static inline void *
241 get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
242 {
243 unsigned long esp;
244 unsigned int xss;
245
246 /* Default to using normal stack */
247 esp = regs->r12;
248 xss = regs->r16 >> 16;
249
250 /* This is the X/Open sanctioned signal stack switching. */
251 if (ka->sa.sa_flags & SA_ONSTACK) {
252 if (! on_sig_stack(esp))
253 esp = current->sas_ss_sp + current->sas_ss_size;
254 }
255 /* Legacy stack switching not supported */
256
257 return (void *)((esp - frame_size) & -8ul);
258 }
259
260 static int
261 setup_frame_ia32(int sig, struct k_sigaction *ka, sigset_t *set,
262 struct pt_regs * regs)
263 {
264 struct sigframe_ia32 *frame;
265 int err = 0;
266
267 frame = get_sigframe(ka, regs, sizeof(*frame));
268
269 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
270 goto give_sigsegv;
271
272 err |= __put_user((current->exec_domain
273 && current->exec_domain->signal_invmap
274 && sig < 32
275 ? (int)(current->exec_domain->signal_invmap[sig])
276 : sig),
277 &frame->sig);
278
279 err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
280
281 if (_IA32_NSIG_WORDS > 1) {
282 err |= __copy_to_user(frame->extramask, &set->sig[1],
283 sizeof(frame->extramask));
284 }
285
286 /* Set up to return from userspace. If provided, use a stub
287 already in userspace. */
288 err |= __put_user((long)frame->retcode, &frame->pretcode);
289 /* This is popl %eax ; movl $,%eax ; int $0x80 */
290 err |= __put_user(0xb858, (short *)(frame->retcode+0));
291 #define __IA32_NR_sigreturn 119
292 err |= __put_user(__IA32_NR_sigreturn & 0xffff, (short *)(frame->retcode+2));
293 err |= __put_user(__IA32_NR_sigreturn >> 16, (short *)(frame->retcode+4));
294 err |= __put_user(0x80cd, (short *)(frame->retcode+6));
295
296 if (err)
297 goto give_sigsegv;
298
299 /* Set up registers for signal handler */
300 regs->r12 = (unsigned long) frame;
301 regs->cr_iip = (unsigned long) ka->sa.sa_handler;
302
303 set_fs(USER_DS);
304 regs->r16 = (__USER_DS << 16) | (__USER_DS); /* ES == DS, GS, FS are zero */
305 regs->r17 = (__USER_DS << 16) | __USER_CS;
306
307 #if 0
308 regs->eflags &= ~TF_MASK;
309 #endif
310
311 #if 0
312 printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%x\n",
313 current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
314 #endif
315
316 return 1;
317
318 give_sigsegv:
319 if (sig == SIGSEGV)
320 ka->sa.sa_handler = SIG_DFL;
321 force_sig(SIGSEGV, current);
322 return 0;
323 }
324
325 static int
326 setup_rt_frame_ia32(int sig, struct k_sigaction *ka, siginfo_t *info,
327 sigset_t *set, struct pt_regs * regs)
328 {
329 struct rt_sigframe_ia32 *frame;
330 int err = 0;
331
332 frame = get_sigframe(ka, regs, sizeof(*frame));
333
334 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
335 goto give_sigsegv;
336
337 err |= __put_user((current->exec_domain
338 && current->exec_domain->signal_invmap
339 && sig < 32
340 ? current->exec_domain->signal_invmap[sig]
341 : sig),
342 &frame->sig);
343 err |= __put_user((long)&frame->info, &frame->pinfo);
344 err |= __put_user((long)&frame->uc, &frame->puc);
345 err |= copy_siginfo_to_user32(&frame->info, info);
346
347 /* Create the ucontext. */
348 err |= __put_user(0, &frame->uc.uc_flags);
349 err |= __put_user(0, &frame->uc.uc_link);
350 err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
351 err |= __put_user(sas_ss_flags(regs->r12),
352 &frame->uc.uc_stack.ss_flags);
353 err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
354 err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate,
355 regs, set->sig[0]);
356 err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
357
358 err |= __put_user((long)frame->retcode, &frame->pretcode);
359 /* This is movl $,%eax ; int $0x80 */
360 err |= __put_user(0xb8, (char *)(frame->retcode+0));
361 #define __IA32_NR_rt_sigreturn 173
362 err |= __put_user(__IA32_NR_rt_sigreturn, (int *)(frame->retcode+1));
363 err |= __put_user(0x80cd, (short *)(frame->retcode+5));
364
365 if (err)
366 goto give_sigsegv;
367
368 /* Set up registers for signal handler */
369 regs->r12 = (unsigned long) frame;
370 regs->cr_iip = (unsigned long) ka->sa.sa_handler;
371
372 set_fs(USER_DS);
373
374 regs->r16 = (__USER_DS << 16) | (__USER_DS); /* ES == DS, GS, FS are zero */
375 regs->r17 = (__USER_DS << 16) | __USER_CS;
376
377 #if 0
378 regs->eflags &= ~TF_MASK;
379 #endif
380
381 #if 0
382 printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%x\n",
383 current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
384 #endif
385
386 return 1;
387
388 give_sigsegv:
389 if (sig == SIGSEGV)
390 ka->sa.sa_handler = SIG_DFL;
391 force_sig(SIGSEGV, current);
392 return 0;
393 }
394
395 int
396 ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
397 sigset_t *set, struct pt_regs *regs)
398 {
399 /* Set up the stack frame */
400 if (ka->sa.sa_flags & SA_SIGINFO)
401 return(setup_rt_frame_ia32(sig, ka, info, set, regs));
402 else
403 return(setup_frame_ia32(sig, ka, set, regs));
404 }
405
406 asmlinkage int
407 sys32_sigreturn(
408 int arg0,
409 int arg1,
410 int arg2,
411 int arg3,
412 int arg4,
413 int arg5,
414 int arg6,
415 int arg7,
416 unsigned long stack)
417 {
418 struct pt_regs *regs = (struct pt_regs *) &stack;
419 struct sigframe_ia32 *frame = (struct sigframe_ia32 *)(regs->r12- 8);
420 sigset_t set;
421 int eax;
422
423 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
424 goto badframe;
425
426 if (__get_user(set.sig[0], &frame->sc.oldmask)
427 || (_IA32_NSIG_WORDS > 1
428 && __copy_from_user((((char *) &set.sig) + 4),
429 &frame->extramask,
430 sizeof(frame->extramask))))
431 goto badframe;
432
433 sigdelsetmask(&set, ~_BLOCKABLE);
434 spin_lock_irq(¤t->sigmask_lock);
435 current->blocked = (sigset_t) set;
436 recalc_sigpending(current);
437 spin_unlock_irq(¤t->sigmask_lock);
438
439 if (restore_sigcontext_ia32(regs, &frame->sc, &eax))
440 goto badframe;
441 return eax;
442
443 badframe:
444 force_sig(SIGSEGV, current);
445 return 0;
446 }
447
448 asmlinkage int
449 sys32_rt_sigreturn(
450 int arg0,
451 int arg1,
452 int arg2,
453 int arg3,
454 int arg4,
455 int arg5,
456 int arg6,
457 int arg7,
458 unsigned long stack)
459 {
460 struct pt_regs *regs = (struct pt_regs *) &stack;
461 struct rt_sigframe_ia32 *frame = (struct rt_sigframe_ia32 *)(regs->r12 - 4);
462 sigset_t set;
463 stack_t st;
464 int eax;
465
466 if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
467 goto badframe;
468 if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
469 goto badframe;
470
471 sigdelsetmask(&set, ~_BLOCKABLE);
472 spin_lock_irq(¤t->sigmask_lock);
473 current->blocked = set;
474 recalc_sigpending(current);
475 spin_unlock_irq(¤t->sigmask_lock);
476
477 if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
478 goto badframe;
479
480 if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
481 goto badframe;
482 /* It is more difficult to avoid calling this function than to
483 call it and ignore errors. */
484 do_sigaltstack(&st, NULL, regs->r12);
485
486 return eax;
487
488 badframe:
489 force_sig(SIGSEGV, current);
490 return 0;
491 }
492
493