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