vserver 1.9.3
[linux-2.6.git] / arch / ppc64 / kernel / signal.c
index ce06678..ce61628 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/unistd.h>
 #include <linux/stddef.h>
 #include <linux/elf.h>
-#include <asm/ppc32.h>
 #include <asm/sigcontext.h>
 #include <asm/ucontext.h>
 #include <asm/uaccess.h>
@@ -127,12 +126,11 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
         * v_regs pointer or not
         */
 #ifdef CONFIG_ALTIVEC
-       elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve) & ~0xful);
+       elf_vrreg_t __user *v_regs = (elf_vrreg_t __user *)(((unsigned long)sc->vmx_reserve + 15) & ~0xful);
 #endif
        long err = 0;
 
-       if (regs->msr & MSR_FP)
-               giveup_fpu(current);
+       flush_fp_to_thread(current);
 
        /* Make sure signal doesn't get spurrious FP exceptions */
        current->thread.fpscr = 0;
@@ -141,9 +139,8 @@ static long setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
        err |= __put_user(v_regs, &sc->v_regs);
 
        /* save altivec registers */
-       if (current->thread.used_vr) {          
-               if (regs->msr & MSR_VEC)
-                       giveup_altivec(current);
+       if (current->thread.used_vr) {
+               flush_altivec_to_thread(current);
                /* Copy 33 vec registers (vr0..31 and vscr) to the stack */
                err |= __copy_to_user(v_regs, current->thread.vr, 33 * sizeof(vector128));
                /* set MSR_VEC in the MSR value in the frame to indicate that sc->v_reg)
@@ -180,7 +177,7 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
        elf_vrreg_t __user *v_regs;
 #endif
        unsigned long err = 0;
-       unsigned long save_r13;
+       unsigned long save_r13 = 0;
        elf_greg_t *gregs = (elf_greg_t *)regs;
        int i;
 
@@ -373,7 +370,8 @@ badframe:
        printk("badframe in sys_rt_sigreturn, regs=%p uc=%p &uc->uc_mcontext=%p\n",
               regs, uc, &uc->uc_mcontext);
 #endif
-       do_exit(SIGSEGV);
+       force_sig(SIGSEGV, current);
+       return 0;
 }
 
 static void setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
@@ -448,7 +446,7 @@ badframe:
        printk("badframe in setup_rt_frame, regs=%p frame=%p newsp=%lx\n",
               regs, frame, newsp);
 #endif
-       do_exit(SIGSEGV);
+       force_sigsegv(signr, current);
 }
 
 
@@ -461,17 +459,13 @@ static void handle_signal(unsigned long sig, struct k_sigaction *ka,
        /* Set up Signal Frame */
        setup_rt_frame(sig, ka, info, oldset, regs);
 
-       if (ka->sa.sa_flags & SA_ONESHOT)
-               ka->sa.sa_handler = SIG_DFL;
-
        if (!(ka->sa.sa_flags & SA_NODEFER)) {
                spin_lock_irq(&current->sighand->siglock);
-               sigorsets(&current->blocked,&current->blocked,&ka->sa.sa_mask);
+               sigorsets(&current->blocked, &current->blocked, &ka->sa.sa_mask);
                sigaddset(&current->blocked,sig);
                recalc_sigpending();
                spin_unlock_irq(&current->sighand->siglock);
        }
-       return;
 }
 
 static inline void syscall_restart(struct pt_regs *regs, struct k_sigaction *ka)
@@ -514,6 +508,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
 {
        siginfo_t info;
        int signr;
+       struct k_sigaction ka;
 
        /*
         * If the current thread is 32 bit - invoke the
@@ -525,18 +520,16 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
        if (!oldset)
                oldset = &current->blocked;
 
-       signr = get_signal_to_deliver(&info, regs, NULL);
+       signr = get_signal_to_deliver(&info, &ka, regs, NULL);
        if (signr > 0) {
-               struct k_sigaction *ka = &current->sighand->action[signr-1];
-
                /* Whee!  Actually deliver the signal.  */
-               if (regs->trap == 0x0C00)
-                       syscall_restart(regs, ka);
-               handle_signal(signr, ka, &info, oldset, regs);
+               if (TRAP(regs) == 0x0C00)
+                       syscall_restart(regs, &ka);
+               handle_signal(signr, &ka, &info, oldset, regs);
                return 1;
        }
 
-       if (regs->trap == 0x0C00) {     /* System Call! */
+       if (TRAP(regs) == 0x0C00) {     /* System Call! */
                if ((int)regs->result == -ERESTARTNOHAND ||
                    (int)regs->result == -ERESTARTSYS ||
                    (int)regs->result == -ERESTARTNOINTR) {