ia32_signal.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:20k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * IA32 Architecture-specific signal handling support.
  3.  *
  4.  * Copyright (C) 1999, 2001 Hewlett-Packard Co
  5.  * 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. #include <linux/errno.h>
  13. #include <linux/kernel.h>
  14. #include <linux/mm.h>
  15. #include <linux/personality.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. #include <asm/uaccess.h>
  25. #include <asm/rse.h>
  26. #include <asm/sigcontext.h>
  27. #include <asm/segment.h>
  28. #include <asm/ia32.h>
  29. #include "../kernel/sigframe.h"
  30. #define A(__x) ((unsigned long)(__x))
  31. #define DEBUG_SIG 0
  32. #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
  33. #define __IA32_NR_sigreturn            119
  34. #define __IA32_NR_rt_sigreturn         173
  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. struct rt_sigframe_ia32
  45. {
  46.        int pretcode;
  47.        int sig;
  48.        int pinfo;
  49.        int puc;
  50.        siginfo_t32 info;
  51.        struct ucontext_ia32 uc;
  52.        struct _fpstate_ia32 fpstate;
  53.        char retcode[8];
  54. };
  55. int
  56. copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from)
  57. {
  58. unsigned long tmp;
  59. int err;
  60. if (!access_ok(VERIFY_READ, from, sizeof(siginfo_t32)))
  61. return -EFAULT;
  62. err = __get_user(to->si_signo, &from->si_signo);
  63. err |= __get_user(to->si_errno, &from->si_errno);
  64. err |= __get_user(to->si_code, &from->si_code);
  65. if (from->si_code < 0)
  66. err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  67. else {
  68. switch (from->si_code >> 16) {
  69.       case __SI_CHLD >> 16:
  70. err |= __get_user(to->si_utime, &from->si_utime);
  71. err |= __get_user(to->si_stime, &from->si_stime);
  72. err |= __get_user(to->si_status, &from->si_status);
  73.       default:
  74. err |= __get_user(to->si_pid, &from->si_pid);
  75. err |= __get_user(to->si_uid, &from->si_uid);
  76. break;
  77.       case __SI_FAULT >> 16:
  78. err |= __get_user(tmp, &from->si_addr);
  79. to->si_addr = (void *) tmp;
  80. break;
  81.       case __SI_POLL >> 16:
  82. err |= __get_user(to->si_band, &from->si_band);
  83. err |= __get_user(to->si_fd, &from->si_fd);
  84. break;
  85. /* case __SI_RT: This is not generated by the kernel as of now.  */
  86. }
  87. }
  88. return err;
  89. }
  90. int
  91. copy_siginfo_to_user32 (siginfo_t32 *to, siginfo_t *from)
  92. {
  93. int err;
  94. if (!access_ok(VERIFY_WRITE, to, sizeof(siginfo_t32)))
  95. return -EFAULT;
  96. /* If you change siginfo_t structure, please be sure
  97.    this code is fixed accordingly.
  98.    It should never copy any pad contained in the structure
  99.    to avoid security leaks, but must copy the generic
  100.    3 ints plus the relevant union member.
  101.    This routine must convert siginfo from 64bit to 32bit as well
  102.    at the same time.  */
  103. err = __put_user(from->si_signo, &to->si_signo);
  104. err |= __put_user(from->si_errno, &to->si_errno);
  105. err |= __put_user((short)from->si_code, &to->si_code);
  106. if (from->si_code < 0)
  107. err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);
  108. else {
  109. switch (from->si_code >> 16) {
  110. case __SI_CHLD >> 16:
  111. err |= __put_user(from->si_utime, &to->si_utime);
  112. err |= __put_user(from->si_stime, &to->si_stime);
  113. err |= __put_user(from->si_status, &to->si_status);
  114. default:
  115. err |= __put_user(from->si_pid, &to->si_pid);
  116. err |= __put_user(from->si_uid, &to->si_uid);
  117. break;
  118. case __SI_FAULT >> 16:
  119. err |= __put_user((long)from->si_addr, &to->si_addr);
  120. break;
  121. case __SI_POLL >> 16:
  122. err |= __put_user(from->si_band, &to->si_band);
  123. err |= __put_user(from->si_fd, &to->si_fd);
  124. break;
  125. /* case __SI_RT: This is not generated by the kernel as of now.  */
  126. }
  127. }
  128. return err;
  129. }
  130. static inline void
  131. sigact_set_handler (struct k_sigaction *sa, unsigned int handler, unsigned int restorer)
  132. {
  133. if (handler + 1 <= 2)
  134. /* SIG_DFL, SIG_IGN, or SIG_ERR: must sign-extend to 64-bits */
  135. sa->sa.sa_handler = (__sighandler_t) A((int) handler);
  136. else
  137. sa->sa.sa_handler = (__sighandler_t) (((unsigned long) restorer << 32) | handler);
  138. }
  139. asmlinkage long
  140. ia32_rt_sigsuspend (sigset32_t *uset, unsigned int sigsetsize, struct sigscratch *scr)
  141. {
  142. extern long ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall);
  143. sigset_t oldset, set;
  144. scr->scratch_unat = 0; /* avoid leaking kernel bits to user level */
  145. memset(&set, 0, sizeof(&set));
  146. if (sigsetsize > sizeof(sigset_t))
  147. return -EINVAL;
  148. if (copy_from_user(&set.sig, &uset->sig, sigsetsize))
  149. return -EFAULT;
  150. sigdelsetmask(&set, ~_BLOCKABLE);
  151. spin_lock_irq(&current->sigmask_lock);
  152. {
  153. oldset = current->blocked;
  154. current->blocked = set;
  155. recalc_sigpending(current);
  156. }
  157. spin_unlock_irq(&current->sigmask_lock);
  158. /*
  159.  * The return below usually returns to the signal handler.  We need to pre-set the
  160.  * correct error code here to ensure that the right values get saved in sigcontext
  161.  * by ia64_do_signal.
  162.  */
  163. scr->pt.r8 = -EINTR;
  164. while (1) {
  165. current->state = TASK_INTERRUPTIBLE;
  166. schedule();
  167. if (ia64_do_signal(&oldset, scr, 1))
  168. return -EINTR;
  169. }
  170. }
  171. asmlinkage long
  172. ia32_sigsuspend (unsigned int mask, struct sigscratch *scr)
  173. {
  174. return ia32_rt_sigsuspend((sigset32_t *)&mask, sizeof(mask), scr);
  175. }
  176. asmlinkage long
  177. sys32_signal (int sig, unsigned int handler)
  178. {
  179. struct k_sigaction new_sa, old_sa;
  180. int ret;
  181. sigact_set_handler(&new_sa, handler, 0);
  182. new_sa.sa.sa_flags = SA_ONESHOT | SA_NOMASK;
  183. ret = do_sigaction(sig, &new_sa, &old_sa);
  184. return ret ? ret : IA32_SA_HANDLER(&old_sa);
  185. }
  186. asmlinkage long
  187. sys32_rt_sigaction (int sig, struct sigaction32 *act,
  188.     struct sigaction32 *oact, unsigned int sigsetsize)
  189. {
  190. struct k_sigaction new_ka, old_ka;
  191. unsigned int handler, restorer;
  192. int ret;
  193. /* XXX: Don't preclude handling different sized sigset_t's.  */
  194. if (sigsetsize != sizeof(sigset32_t))
  195. return -EINVAL;
  196. if (act) {
  197. ret = get_user(handler, &act->sa_handler);
  198. ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
  199. ret |= get_user(restorer, &act->sa_restorer);
  200. ret |= copy_from_user(&new_ka.sa.sa_mask, &act->sa_mask, sizeof(sigset32_t));
  201. if (ret)
  202. return -EFAULT;
  203. sigact_set_handler(&new_ka, handler, restorer);
  204. }
  205. ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  206. if (!ret && oact) {
  207. ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
  208. ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  209. ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
  210. ret |= copy_to_user(&oact->sa_mask, &old_ka.sa.sa_mask, sizeof(sigset32_t));
  211. }
  212. return ret;
  213. }
  214. extern asmlinkage long sys_rt_sigprocmask (int how, sigset_t *set, sigset_t *oset,
  215.    size_t sigsetsize);
  216. asmlinkage long
  217. sys32_rt_sigprocmask (int how, sigset32_t *set, sigset32_t *oset, unsigned int sigsetsize)
  218. {
  219. mm_segment_t old_fs = get_fs();
  220. sigset_t s;
  221. long ret;
  222. if (sigsetsize > sizeof(s))
  223. return -EINVAL;
  224. if (set) {
  225. memset(&s, 0, sizeof(s));
  226. if (copy_from_user(&s.sig, set, sigsetsize))
  227. return -EFAULT;
  228. }
  229. set_fs(KERNEL_DS);
  230. ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, sizeof(s));
  231. set_fs(old_fs);
  232. if (ret)
  233. return ret;
  234. if (oset) {
  235. if (copy_to_user(oset, &s.sig, sigsetsize))
  236. return -EFAULT;
  237. }
  238. return 0;
  239. }
  240. asmlinkage long
  241. sys32_sigprocmask (int how, unsigned int *set, unsigned int *oset)
  242. {
  243. return sys32_rt_sigprocmask(how, (sigset32_t *) set, (sigset32_t *) oset, sizeof(*set));
  244. }
  245. asmlinkage long
  246. sys32_rt_sigtimedwait (sigset32_t *uthese, siginfo_t32 *uinfo, struct timespec32 *uts,
  247.        unsigned int sigsetsize)
  248. {
  249. extern asmlinkage long sys_rt_sigtimedwait (const sigset_t *, siginfo_t *,
  250.     const struct timespec *, size_t);
  251. extern int copy_siginfo_to_user32 (siginfo_t32 *, siginfo_t *);
  252. mm_segment_t old_fs = get_fs();
  253. struct timespec t;
  254. siginfo_t info;
  255. sigset_t s;
  256. int ret;
  257. if (copy_from_user(&s.sig, uthese, sizeof(sigset32_t)))
  258. return -EFAULT;
  259. if (uts) {
  260. ret = get_user(t.tv_sec, &uts->tv_sec);
  261. ret |= get_user(t.tv_nsec, &uts->tv_nsec);
  262. if (ret)
  263. return -EFAULT;
  264. }
  265. set_fs(KERNEL_DS);
  266. ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);
  267. set_fs(old_fs);
  268. if (ret >= 0 && uinfo) {
  269. if (copy_siginfo_to_user32(uinfo, &info))
  270. return -EFAULT;
  271. }
  272. return ret;
  273. }
  274. asmlinkage long
  275. sys32_rt_sigqueueinfo (int pid, int sig, siginfo_t32 *uinfo)
  276. {
  277. extern asmlinkage long sys_rt_sigqueueinfo (int, int, siginfo_t *);
  278. extern int copy_siginfo_from_user32 (siginfo_t *to, siginfo_t32 *from);
  279. mm_segment_t old_fs = get_fs();
  280. siginfo_t info;
  281. int ret;
  282. if (copy_siginfo_from_user32(&info, uinfo))
  283. return -EFAULT;
  284. set_fs(KERNEL_DS);
  285. ret = sys_rt_sigqueueinfo(pid, sig, &info);
  286. set_fs(old_fs);
  287. return ret;
  288. }
  289. asmlinkage long
  290. sys32_sigaction (int sig, struct old_sigaction32 *act, struct old_sigaction32 *oact)
  291. {
  292. struct k_sigaction new_ka, old_ka;
  293. unsigned int handler, restorer;
  294. int ret;
  295. if (act) {
  296. old_sigset32_t mask;
  297. ret = get_user(handler, &act->sa_handler);
  298. ret |= get_user(new_ka.sa.sa_flags, &act->sa_flags);
  299. ret |= get_user(restorer, &act->sa_restorer);
  300. ret |= get_user(mask, &act->sa_mask);
  301. if (ret)
  302. return ret;
  303. sigact_set_handler(&new_ka, handler, restorer);
  304. siginitset(&new_ka.sa.sa_mask, mask);
  305. }
  306. ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
  307. if (!ret && oact) {
  308. ret = put_user(IA32_SA_HANDLER(&old_ka), &oact->sa_handler);
  309. ret |= put_user(old_ka.sa.sa_flags, &oact->sa_flags);
  310. ret |= put_user(IA32_SA_RESTORER(&old_ka), &oact->sa_restorer);
  311. ret |= put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
  312. }
  313. return ret;
  314. }
  315. static int
  316. setup_sigcontext_ia32 (struct sigcontext_ia32 *sc, struct _fpstate_ia32 *fpstate,
  317.        struct pt_regs *regs, unsigned long mask)
  318. {
  319. int  err = 0;
  320. unsigned long flag;
  321. err |= __put_user((regs->r16 >> 32) & 0xffff, (unsigned int *)&sc->fs);
  322. err |= __put_user((regs->r16 >> 48) & 0xffff, (unsigned int *)&sc->gs);
  323. err |= __put_user((regs->r16 >> 16) & 0xffff, (unsigned int *)&sc->es);
  324. err |= __put_user(regs->r16 & 0xffff, (unsigned int *)&sc->ds);
  325. err |= __put_user(regs->r15, &sc->edi);
  326. err |= __put_user(regs->r14, &sc->esi);
  327. err |= __put_user(regs->r13, &sc->ebp);
  328. err |= __put_user(regs->r12, &sc->esp);
  329. err |= __put_user(regs->r11, &sc->ebx);
  330. err |= __put_user(regs->r10, &sc->edx);
  331. err |= __put_user(regs->r9, &sc->ecx);
  332. err |= __put_user(regs->r8, &sc->eax);
  333. #if 0
  334. err |= __put_user(current->tss.trap_no, &sc->trapno);
  335. err |= __put_user(current->tss.error_code, &sc->err);
  336. #endif
  337. err |= __put_user(regs->cr_iip, &sc->eip);
  338. err |= __put_user(regs->r17 & 0xffff, (unsigned int *)&sc->cs);
  339. /*
  340.  *  `eflags' is in an ar register for this context
  341.  */
  342. asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
  343. err |= __put_user((unsigned int)flag, &sc->eflags);
  344. err |= __put_user(regs->r12, &sc->esp_at_signal);
  345. err |= __put_user((regs->r17 >> 16) & 0xffff, (unsigned int *)&sc->ss);
  346. #if 0
  347. tmp = save_i387(fpstate);
  348. if (tmp < 0)
  349. err = 1;
  350. else
  351. err |= __put_user(tmp ? fpstate : NULL, &sc->fpstate);
  352. /* non-iBCS2 extensions.. */
  353. #endif
  354. err |= __put_user(mask, &sc->oldmask);
  355. #if 0
  356. err |= __put_user(current->tss.cr2, &sc->cr2);
  357. #endif
  358. return err;
  359. }
  360. static int
  361. restore_sigcontext_ia32 (struct pt_regs *regs, struct sigcontext_ia32 *sc, int *peax)
  362. {
  363. unsigned int err = 0;
  364. #define COPY(ia64x, ia32x) err |= __get_user(regs->ia64x, &sc->ia32x)
  365. #define copyseg_gs(tmp) (regs->r16 |= (unsigned long) tmp << 48)
  366. #define copyseg_fs(tmp) (regs->r16 |= (unsigned long) tmp << 32)
  367. #define copyseg_cs(tmp) (regs->r17 |= tmp)
  368. #define copyseg_ss(tmp) (regs->r17 |= (unsigned long) tmp << 16)
  369. #define copyseg_es(tmp) (regs->r16 |= (unsigned long) tmp << 16)
  370. #define copyseg_ds(tmp) (regs->r16 |= tmp)
  371. #define COPY_SEG(seg)
  372. {
  373. unsigned short tmp;
  374. err |= __get_user(tmp, &sc->seg);
  375. copyseg_##seg(tmp);
  376. }
  377. #define COPY_SEG_STRICT(seg)
  378. {
  379. unsigned short tmp;
  380. err |= __get_user(tmp, &sc->seg);
  381. copyseg_##seg(tmp|3);
  382. }
  383. /* To make COPY_SEGs easier, we zero r16, r17 */
  384. regs->r16 = 0;
  385. regs->r17 = 0;
  386. COPY_SEG(gs);
  387. COPY_SEG(fs);
  388. COPY_SEG(es);
  389. COPY_SEG(ds);
  390. COPY(r15, edi);
  391. COPY(r14, esi);
  392. COPY(r13, ebp);
  393. COPY(r12, esp);
  394. COPY(r11, ebx);
  395. COPY(r10, edx);
  396. COPY(r9, ecx);
  397. COPY(cr_iip, eip);
  398. COPY_SEG_STRICT(cs);
  399. COPY_SEG_STRICT(ss);
  400. ia32_load_segment_descriptors(current);
  401. {
  402. unsigned int tmpflags;
  403. unsigned long flag;
  404. /*
  405.  *  IA32 `eflags' is not part of `pt_regs', it's in an ar register which
  406.  *  is part of the thread context.  Fortunately, we are executing in the
  407.  *  IA32 process's context.
  408.  */
  409. err |= __get_user(tmpflags, &sc->eflags);
  410. asm volatile ("mov %0=ar.eflag ;;" : "=r"(flag));
  411. flag &= ~0x40DD5;
  412. flag |= (tmpflags & 0x40DD5);
  413. asm volatile ("mov ar.eflag=%0 ;;" :: "r"(flag));
  414. regs->r1 = -1; /* disable syscall checks, r1 is orig_eax */
  415. }
  416. #if 0
  417. {
  418. struct _fpstate * buf;
  419. err |= __get_user(buf, &sc->fpstate);
  420. if (buf) {
  421. if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
  422. goto badframe;
  423. err |= restore_i387(buf);
  424. }
  425. }
  426. #endif
  427. err |= __get_user(*peax, &sc->eax);
  428. return err;
  429. #if 0
  430.   badframe:
  431. return 1;
  432. #endif
  433. }
  434. /*
  435.  * Determine which stack to use..
  436.  */
  437. static inline void *
  438. get_sigframe (struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size)
  439. {
  440. unsigned long esp;
  441. /* Default to using normal stack (truncate off sign-extension of bit 31: */
  442. esp = (unsigned int) regs->r12;
  443. /* This is the X/Open sanctioned signal stack switching.  */
  444. if (ka->sa.sa_flags & SA_ONSTACK) {
  445. if (!on_sig_stack(esp))
  446. esp = current->sas_ss_sp + current->sas_ss_size;
  447. }
  448. /* Legacy stack switching not supported */
  449. return (void *)((esp - frame_size) & -8ul);
  450. }
  451. static int
  452. setup_frame_ia32 (int sig, struct k_sigaction *ka, sigset_t *set, struct pt_regs * regs)
  453. {
  454. struct sigframe_ia32 *frame;
  455. int err = 0;
  456. frame = get_sigframe(ka, regs, sizeof(*frame));
  457. if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  458. goto give_sigsegv;
  459. err |= __put_user((current->exec_domain
  460.    && current->exec_domain->signal_invmap
  461.    && sig < 32
  462.    ? (int)(current->exec_domain->signal_invmap[sig])
  463.    : sig),
  464.   &frame->sig);
  465. err |= setup_sigcontext_ia32(&frame->sc, &frame->fpstate, regs, set->sig[0]);
  466. if (_IA32_NSIG_WORDS > 1)
  467. err |= __copy_to_user(frame->extramask, (char *) &set->sig + 4,
  468.       sizeof(frame->extramask));
  469. /* Set up to return from userspace.  If provided, use a stub
  470.    already in userspace.  */
  471. if (ka->sa.sa_flags & SA_RESTORER) {
  472. unsigned int restorer = IA32_SA_RESTORER(ka);
  473. err |= __put_user(restorer, &frame->pretcode);
  474. } else {
  475. err |= __put_user((long)frame->retcode, &frame->pretcode);
  476. /* This is popl %eax ; movl $,%eax ; int $0x80 */
  477. err |= __put_user(0xb858, (short *)(frame->retcode+0));
  478. err |= __put_user(__IA32_NR_sigreturn & 0xffff, (short *)(frame->retcode+2));
  479. err |= __put_user(__IA32_NR_sigreturn >> 16, (short *)(frame->retcode+4));
  480. err |= __put_user(0x80cd, (short *)(frame->retcode+6));
  481. }
  482. if (err)
  483. goto give_sigsegv;
  484. /* Set up registers for signal handler */
  485. regs->r12 = (unsigned long) frame;
  486. regs->cr_iip = IA32_SA_HANDLER(ka);
  487. set_fs(USER_DS);
  488. regs->r16 = (__USER_DS << 16) |  (__USER_DS); /* ES == DS, GS, FS are zero */
  489. regs->r17 = (__USER_DS << 16) | __USER_CS;
  490. #if 0
  491. regs->eflags &= ~TF_MASK;
  492. #endif
  493. #if 0
  494. printk("SIG deliver (%s:%d): sig=%d sp=%p pc=%lx ra=%xn",
  495.                current->comm, current->pid, sig, (void *) frame, regs->cr_iip, frame->pretcode);
  496. #endif
  497. return 1;
  498.   give_sigsegv:
  499. if (sig == SIGSEGV)
  500. ka->sa.sa_handler = SIG_DFL;
  501. force_sig(SIGSEGV, current);
  502. return 0;
  503. }
  504. static int
  505. setup_rt_frame_ia32 (int sig, struct k_sigaction *ka, siginfo_t *info,
  506.      sigset_t *set, struct pt_regs * regs)
  507. {
  508. struct rt_sigframe_ia32 *frame;
  509. int err = 0;
  510. frame = get_sigframe(ka, regs, sizeof(*frame));
  511. if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
  512. goto give_sigsegv;
  513. err |= __put_user((current->exec_domain
  514.    && current->exec_domain->signal_invmap
  515.    && sig < 32
  516.    ? current->exec_domain->signal_invmap[sig]
  517.    : sig),
  518.   &frame->sig);
  519. err |= __put_user((long)&frame->info, &frame->pinfo);
  520. err |= __put_user((long)&frame->uc, &frame->puc);
  521. err |= copy_siginfo_to_user32(&frame->info, info);
  522. /* Create the ucontext.  */
  523. err |= __put_user(0, &frame->uc.uc_flags);
  524. err |= __put_user(0, &frame->uc.uc_link);
  525. err |= __put_user(current->sas_ss_sp, &frame->uc.uc_stack.ss_sp);
  526. err |= __put_user(sas_ss_flags(regs->r12), &frame->uc.uc_stack.ss_flags);
  527. err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
  528. err |= setup_sigcontext_ia32(&frame->uc.uc_mcontext, &frame->fpstate, regs, set->sig[0]);
  529. err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
  530. if (err)
  531. goto give_sigsegv;
  532. /* Set up to return from userspace.  If provided, use a stub
  533.    already in userspace.  */
  534. if (ka->sa.sa_flags & SA_RESTORER) {
  535. unsigned int restorer = IA32_SA_RESTORER(ka);
  536. err |= __put_user(restorer, &frame->pretcode);
  537. } else {
  538. err |= __put_user((long)frame->retcode, &frame->pretcode);
  539. /* This is movl $,%eax ; int $0x80 */
  540. err |= __put_user(0xb8, (char *)(frame->retcode+0));
  541. err |= __put_user(__IA32_NR_rt_sigreturn, (int *)(frame->retcode+1));
  542. err |= __put_user(0x80cd, (short *)(frame->retcode+5));
  543. }
  544. if (err)
  545. goto give_sigsegv;
  546. /* Set up registers for signal handler */
  547. regs->r12 = (unsigned long) frame;
  548. regs->cr_iip = IA32_SA_HANDLER(ka);
  549. set_fs(USER_DS);
  550. regs->r16 = (__USER_DS << 16) |  (__USER_DS); /* ES == DS, GS, FS are zero */
  551. regs->r17 = (__USER_DS << 16) | __USER_CS;
  552. #if 0
  553. regs->eflags &= ~TF_MASK;
  554. #endif
  555. #if 0
  556. printk("SIG deliver (%s:%d): sp=%p pc=%lx ra=%xn",
  557.                current->comm, current->pid, (void *) frame, regs->cr_iip, frame->pretcode);
  558. #endif
  559. return 1;
  560. give_sigsegv:
  561. if (sig == SIGSEGV)
  562. ka->sa.sa_handler = SIG_DFL;
  563. force_sig(SIGSEGV, current);
  564. return 0;
  565. }
  566. int
  567. ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
  568.    sigset_t *set, struct pt_regs *regs)
  569. {
  570.        /* Set up the stack frame */
  571.        if (ka->sa.sa_flags & SA_SIGINFO)
  572.                return setup_rt_frame_ia32(sig, ka, info, set, regs);
  573.        else
  574.                return setup_frame_ia32(sig, ka, set, regs);
  575. }
  576. asmlinkage long
  577. sys32_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
  578.  unsigned long stack)
  579. {
  580. struct pt_regs *regs = (struct pt_regs *) &stack;
  581. unsigned long esp = (unsigned int) regs->r12;
  582. struct sigframe_ia32 *frame = (struct sigframe_ia32 *)(esp - 8);
  583. sigset_t set;
  584. int eax;
  585. if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
  586. goto badframe;
  587. if (__get_user(set.sig[0], &frame->sc.oldmask)
  588.     || (_IA32_NSIG_WORDS > 1 && __copy_from_user((char *) &set.sig + 4, &frame->extramask,
  589.  sizeof(frame->extramask))))
  590. goto badframe;
  591. sigdelsetmask(&set, ~_BLOCKABLE);
  592. spin_lock_irq(&current->sigmask_lock);
  593. current->blocked = (sigset_t) set;
  594. recalc_sigpending(current);
  595. spin_unlock_irq(&current->sigmask_lock);
  596. if (restore_sigcontext_ia32(regs, &frame->sc, &eax))
  597. goto badframe;
  598. return eax;
  599.   badframe:
  600. force_sig(SIGSEGV, current);
  601. return 0;
  602. }
  603. asmlinkage long
  604. sys32_rt_sigreturn (int arg0, int arg1, int arg2, int arg3, int arg4, int arg5, int arg6, int arg7,
  605.     unsigned long stack)
  606. {
  607. struct pt_regs *regs = (struct pt_regs *) &stack;
  608. unsigned long esp = (unsigned int) regs->r12;
  609. struct rt_sigframe_ia32 *frame = (struct rt_sigframe_ia32 *)(esp - 4);
  610. sigset_t set;
  611. stack_t st;
  612. int eax;
  613. if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
  614. goto badframe;
  615. if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
  616. goto badframe;
  617. sigdelsetmask(&set, ~_BLOCKABLE);
  618. spin_lock_irq(&current->sigmask_lock);
  619. current->blocked =  set;
  620. recalc_sigpending(current);
  621. spin_unlock_irq(&current->sigmask_lock);
  622. if (restore_sigcontext_ia32(regs, &frame->uc.uc_mcontext, &eax))
  623. goto badframe;
  624. if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
  625. goto badframe;
  626. /* It is more difficult to avoid calling this function than to
  627.    call it and ignore errors.  */
  628. do_sigaltstack(&st, NULL, esp);
  629. return eax;
  630.   badframe:
  631. force_sig(SIGSEGV, current);
  632. return 0;
  633. }