vserver 1.9.3
[linux-2.6.git] / arch / ppc64 / kernel / signal.c
index 8323d73..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,7 +126,7 @@ 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;
 
@@ -178,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;
 
@@ -371,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,
@@ -446,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);
 }
 
 
@@ -459,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)
@@ -512,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
@@ -523,14 +520,12 @@ 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 (TRAP(regs) == 0x0C00)
-                       syscall_restart(regs, ka);
-               handle_signal(signr, ka, &info, oldset, regs);
+                       syscall_restart(regs, &ka);
+               handle_signal(signr, &ka, &info, oldset, regs);
                return 1;
        }