15 #include <linux/sched.h>
18 #include <linux/kernel.h>
19 #include <linux/signal.h>
20 #include <linux/errno.h>
21 #include <linux/wait.h>
23 #include <linux/stddef.h>
24 #include <linux/elf.h>
25 #include <linux/ptrace.h>
28 #include <asm/sigcontext.h>
29 #include <asm/ucontext.h>
30 #include <asm/uaccess.h>
31 #include <asm/pgtable.h>
32 #include <asm/unistd.h>
33 #include <asm/cacheflush.h>
34 #include <asm/syscalls.h>
36 #include <asm/switch_to.h>
42 #define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
43 #define FP_REGS_SIZE sizeof(elf_fpregset_t)
45 #define TRAMP_TRACEBACK 3
69 "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n";
71 "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n";
78 int signr,
sigset_t *
set,
unsigned long handler,
79 int ctx_has_vsx_region)
92 unsigned long msr = regs->
msr;
102 flush_altivec_to_thread(
current);
126 if (
current->thread.used_vsr && ctx_has_vsx_region) {
129 err |= copy_vsx_to_user(v_regs,
current);
155 #ifdef CONFIG_ALTIVEC
158 unsigned long err = 0;
159 unsigned long save_r13 = 0;
167 save_r13 = regs->
gpr[13];
175 regs->
msr = (regs->
msr & ~MSR_LE) | (msr & MSR_LE);
188 regs->
gpr[13] = save_r13;
206 regs->
msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC | MSR_VSX);
208 #ifdef CONFIG_ALTIVEC
215 if (v_regs != 0 && (msr & MSR_VEC) != 0)
218 else if (
current->thread.used_vr)
235 if ((msr & MSR_VSX) != 0)
236 err |= copy_vsx_from_user(
current, v_regs);
238 for (i = 0; i < 32 ; i++)
239 current->thread.fpr[i][TS_VSRLOWOFFSET] = 0;
247 static long setup_trampoline(
unsigned int syscall,
unsigned int __user *
tramp)
255 err |=
__put_user(0x38000000UL | (syscall & 0xffff), &tramp[1]);
265 (
unsigned long) &tramp[TRAMP_SIZE]);
274 #define UCONTEXTSIZEWITHOUTVSX \
275 (sizeof(struct ucontext) - 32*sizeof(long))
282 long ctx_size,
long r6,
long r7,
long r8,
struct pt_regs *regs)
286 unsigned long new_msr = 0;
287 int ctx_has_vsx_region = 0;
302 if ((ctx_size <
sizeof(
struct ucontext)) &&
306 if (ctx_size >=
sizeof(
struct ucontext))
307 ctx_has_vsx_region = 1;
309 if (old_ctx !=
NULL) {
343 set_thread_flag(TIF_RESTOREALL);
353 unsigned long r6,
unsigned long r7,
unsigned long r8,
376 set_thread_flag(TIF_RESTOREALL);
381 printk(
"badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
387 (
long)uc, regs->
nip, regs->
link);
403 unsigned long newsp = 0;
421 &frame->
uc.uc_stack.ss_flags);
424 (
unsigned long)ka->
sa.sa_handler, 1);
433 if (vdso64_rt_sigtramp &&
current->mm->context.vdso_base) {
434 regs->
link =
current->mm->context.vdso_base + vdso64_rt_sigtramp;
445 err |=
put_user(regs->
gpr[1], (
unsigned long __user *)newsp);
448 err |=
get_user(regs->
nip, &funct_desc_ptr->entry);
450 regs->
msr &= ~MSR_LE;
451 regs->
gpr[1] = newsp;
452 err |=
get_user(regs->
gpr[2], &funct_desc_ptr->toc);
453 regs->
gpr[3] = signr;
457 err |=
get_user(regs->
gpr[5], (
unsigned long __user *)&frame->
puc);
458 regs->
gpr[6] = (
unsigned long) frame;
460 regs->
gpr[4] = (
unsigned long)&frame->
uc.uc_mcontext;
469 printk(
"badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
475 (
long)frame, regs->
nip, regs->
link);