20 #include <linux/sched.h>
23 #include <linux/kernel.h>
24 #include <linux/signal.h>
25 #include <linux/errno.h>
26 #include <linux/elf.h>
27 #include <linux/ptrace.h>
33 #include <linux/wait.h>
35 #include <linux/stddef.h>
36 #include <linux/tty.h>
37 #include <linux/binfmts.h>
40 #include <asm/uaccess.h>
41 #include <asm/cacheflush.h>
42 #include <asm/syscalls.h>
43 #include <asm/sigcontext.h>
45 #include <asm/switch_to.h>
48 #include <asm/unistd.h>
50 #include <asm/ucontext.h>
51 #include <asm/pgtable.h>
59 #define sys_sigsuspend compat_sys_sigsuspend
60 #define sys_rt_sigsuspend compat_sys_rt_sigsuspend
61 #define sys_rt_sigreturn compat_sys_rt_sigreturn
62 #define sys_sigaction compat_sys_sigaction
63 #define sys_swapcontext compat_sys_swapcontext
64 #define sys_sigreturn compat_sys_sigreturn
66 #define old_sigaction old_sigaction32
67 #define sigcontext sigcontext32
68 #define mcontext mcontext32
69 #define ucontext ucontext32
75 #define UCONTEXTSIZEWITHOUTVSX \
76 (sizeof(struct ucontext) - sizeof(elf_vsrreghalf_t32))
85 #define GP_REGS_SIZE min(sizeof(elf_gregset_t32), sizeof(struct pt_regs32))
86 #undef __SIGNAL_FRAMESIZE
87 #define __SIGNAL_FRAMESIZE __SIGNAL_FRAMESIZE32
89 #define ELF_NVRREG ELF_NVRREG32
95 static inline int put_sigset_t(compat_sigset_t __user *uset,
sigset_t *
set)
100 case 4: cset.sig[6] =
set->sig[3] & 0xffffffffull;
101 cset.sig[7] =
set->sig[3] >> 32;
102 case 3: cset.sig[4] =
set->sig[2] & 0xffffffffull;
103 cset.sig[5] =
set->sig[2] >> 32;
104 case 2: cset.sig[2] =
set->sig[1] & 0xffffffffull;
105 cset.sig[3] =
set->sig[1] >> 32;
106 case 1: cset.sig[0] =
set->sig[0] & 0xffffffffull;
107 cset.sig[1] =
set->sig[0] >> 32;
112 static inline int get_sigset_t(
sigset_t *
set,
113 const compat_sigset_t __user *uset)
125 case 4:
set->sig[3] = s32.sig[6] | (((
long)s32.sig[7]) << 32);
126 case 3:
set->sig[2] = s32.sig[4] | (((
long)s32.sig[5]) << 32);
127 case 2:
set->sig[1] = s32.sig[2] | (((
long)s32.sig[3]) << 32);
128 case 1:
set->sig[0] = s32.sig[0] | (((
long)s32.sig[1]) << 32);
133 static inline int get_old_sigaction(
struct k_sigaction *new_ka,
139 if (
get_user(handler, &act->sa_handler) ||
144 new_ka->
sa.sa_handler = compat_ptr(handler);
145 new_ka->
sa.sa_restorer = compat_ptr(restorer);
146 siginitset(&new_ka->
sa.sa_mask, mask);
150 #define to_user_ptr(p) ptr_to_compat(p)
151 #define from_user_ptr(p) compat_ptr(p)
153 static inline int save_general_regs(
struct pt_regs *
regs,
164 if (
__put_user((
unsigned int)gregs[i], &frame->mc_gregs[i]))
170 static inline int restore_general_regs(
struct pt_regs *regs,
177 if ((i ==
PT_MSR) || (i == PT_SOFTE))
187 #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
199 static inline int get_old_sigaction(
struct k_sigaction *new_ka,
206 __get_user(new_ka->
sa.sa_restorer, &act->sa_restorer) ||
210 siginitset(&new_ka->
sa.sa_mask, mask);
214 #define to_user_ptr(p) ((unsigned long)(p))
215 #define from_user_ptr(p) ((void __user *)(p))
217 static inline int save_general_regs(
struct pt_regs *regs,
224 static inline int restore_general_regs(
struct pt_regs *regs,
246 siginitset(&blocked, mask);
262 if (get_old_sigaction(&new_ka, act))
270 &oact->sa_handler) ||
272 &oact->sa_restorer) ||
340 buf[i] = task->
thread.TS_FPR(i);
354 task->
thread.TS_FPR(i) = buf[
i];
360 unsigned long copy_vsx_to_user(
void __user *to,
363 double buf[ELF_NVSRHALFREG];
367 for (i = 0; i < ELF_NVSRHALFREG; i++)
368 buf[i] = task->
thread.fpr[i][TS_VSRLOWOFFSET];
372 unsigned long copy_vsx_from_user(
struct task_struct *task,
375 double buf[ELF_NVSRHALFREG];
380 for (i = 0; i < ELF_NVSRHALFREG ; i++)
381 task->
thread.fpr[i][TS_VSRLOWOFFSET] = buf[i];
406 int sigret,
int ctx_has_vsx_region)
408 unsigned long msr = regs->
msr;
414 if (save_general_regs(regs, frame))
417 #ifdef CONFIG_ALTIVEC
420 flush_altivec_to_thread(
current);
447 if (
current->thread.used_vsr && ctx_has_vsx_region) {
449 if (copy_vsx_to_user(&frame->mc_vsregs,
current))
456 if (
current->thread.used_spe) {
476 if (
__put_user(0x38000000UL + sigret, &frame->tramp[0])
477 ||
__put_user(0x44000002UL, &frame->tramp[1]))
480 (
unsigned long) &frame->tramp[2]);
494 unsigned int save_r2 = 0;
505 save_r2 = (
unsigned int)regs->
gpr[2];
506 err = restore_general_regs(regs, sr);
510 regs->
gpr[2] = (
unsigned long) save_r2;
516 regs->
msr = (regs->
msr & ~MSR_LE) | (msr & MSR_LE);
527 #ifdef CONFIG_ALTIVEC
532 regs->
msr &= ~MSR_VEC;
536 sizeof(sr->mc_vregs)))
538 }
else if (
current->thread.used_vr)
553 regs->
msr &= ~MSR_VSX;
559 if (copy_vsx_from_user(
current, &sr->mc_vsregs))
561 }
else if (
current->thread.used_vsr)
562 for (i = 0; i < 32 ; i++)
563 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
569 regs->
msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
574 regs->
msr &= ~MSR_SPE;
580 }
else if (
current->thread.used_spe)
593 struct sigaction32 __user *oact,
size_t sigsetsize)
599 if (sigsetsize !=
sizeof(compat_sigset_t))
605 ret =
get_user(handler, &act->sa_handler);
606 new_ka.
sa.sa_handler = compat_ptr(handler);
607 ret |= get_sigset_t(&new_ka.
sa.sa_mask, &act->sa_mask);
616 ret |= put_sigset_t(&oact->sa_mask, &old_ka.sa.sa_mask);
617 ret |=
__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
630 compat_sigset_t __user *oset,
size_t sigsetsize)
638 if (get_sigset_t(&s,
set))
651 if (put_sigset_t(oset, &s))
668 if (put_sigset_t(
set, &s))
696 else switch(s->
si_code >> 16) {
702 err |=
__put_user(s->si_status, &d->si_status);
705 err |=
__put_user((
unsigned int)(
unsigned long)s->si_addr,
714 err |=
__put_user(s->si_overrun, &d->si_overrun);
730 #define copy_siginfo_to_user copy_siginfo_to_user32
734 memset(to, 0,
sizeof *to);
777 stack_32_t __user * newstack = compat_ptr(__new);
778 stack_32_t __user * oldstack = compat_ptr(__old);
793 if (
get_user(ss_sp, &newstack->ss_sp) ||
797 uss.
ss_sp = compat_ptr(ss_sp);
805 oldstack ? (
stack_t __user *) &uoss : NULL,
809 if (!ret && oldstack &&
829 unsigned long newsp = 0;
844 &rt_sf->
uc.uc_stack.ss_flags)
848 || put_sigset_t(&rt_sf->
uc.uc_sigmask, oldset))
852 frame = &rt_sf->
uc.uc_mcontext;
861 regs->
link = (
unsigned long) frame->tramp;
868 addr = (
void __user *)regs->
gpr[1];
873 regs->
gpr[1] = newsp;
876 regs->
gpr[5] = (
unsigned long) &rt_sf->
uc;
877 regs->
gpr[6] = (
unsigned long) rt_sf;
878 regs->
nip = (
unsigned long) ka->
sa.sa_handler;
880 regs->
msr &= ~MSR_LE;
885 printk(
"badframe in handle_rt_signal, regs=%p frame=%p newsp=%lx\n",
890 "%s[%d]: bad frame in handle_rt_signal32: "
891 "%p nip %08lx lr %08lx\n",
899 static int do_setcontext(
struct ucontext __user *ucp,
struct pt_regs *regs,
int sig)
904 if (get_sigset_t(&
set, &ucp->uc_sigmask))
930 int ctx_size,
int r6,
int r7,
int r8,
struct pt_regs *regs)
933 int ctx_has_vsx_region = 0;
936 unsigned long new_msr = 0;
963 if ((ctx_size <
sizeof(
struct ucontext)) &&
967 if (ctx_size >=
sizeof(
struct ucontext))
968 ctx_has_vsx_region = 1;
973 if (ctx_size <
sizeof(
struct ucontext))
976 if (old_ctx != NULL) {
987 ((
unsigned long) &old_ctx->uc_mcontext & ~0xf
UL);
990 || put_sigset_t(&old_ctx->uc_sigmask, &
current->blocked)
998 ||
__get_user(tmp, (
u8 __user *) new_ctx + ctx_size - 1))
1012 if (do_setcontext(new_ctx, regs, 0))
1015 set_thread_flag(TIF_RESTOREALL);
1031 if (do_setcontext(&rt_sf->
uc, regs, 1))
1051 set_thread_flag(TIF_RESTOREALL);
1057 "%s[%d]: bad frame in sys_rt_sigreturn: "
1058 "%p nip %08lx lr %08lx\n",
1060 rt_sf, regs->
nip, regs->
link);
1067 int sys_debug_setcontext(
struct ucontext __user *
ctx,
1069 int r6,
int r7,
int r8,
1075 unsigned long new_msr = regs->
msr;
1076 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
1077 unsigned long new_dbcr0 =
current->thread.dbcr0;
1080 for (i=0; i<ndbg; i++) {
1083 switch (
op.dbg_type) {
1085 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
1088 new_dbcr0 |= (DBCR0_IDM | DBCR0_IC);
1090 new_dbcr0 &= ~DBCR0_IC;
1091 if (!DBCR_ACTIVE_EVENTS(new_dbcr0,
1094 new_dbcr0 &= ~DBCR0_IDM;
1105 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
1125 regs->
msr = new_msr;
1126 #ifdef CONFIG_PPC_ADV_DEBUG_REGS
1127 current->thread.dbcr0 = new_dbcr0;
1146 if (do_setcontext(ctx, regs, 1)) {
1149 "sys_debug_setcontext: %p nip %08lx "
1167 set_thread_flag(TIF_RESTOREALL);
1181 unsigned long newsp = 0;
1190 #
error "Please adjust handle_signal()"
1213 current->thread.fpscr.val = 0;
1220 regs->
gpr[1] = newsp;
1222 regs->
gpr[4] = (
unsigned long) sc;
1223 regs->
nip = (
unsigned long) ka->
sa.sa_handler;
1225 regs->
msr &= ~MSR_LE;
1231 printk(
"badframe in handle_signal, regs=%p frame=%p newsp=%lx\n",
1232 regs, frame, newsp);
1236 "%s[%d]: bad frame in handle_signal32: "
1237 "%p nip %08lx lr %08lx\n",
1239 frame, regs->
nip, regs->
link);
1273 set.sig[1] = sigctx.
_unused[3];
1283 set_thread_flag(TIF_RESTOREALL);
1289 "%s[%d]: bad frame in sys_sigreturn: "
1290 "%p nip %08lx lr %08lx\n",