These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / arch / arc / kernel / signal.c
index 2251fb4..004b7f0 100644 (file)
@@ -67,7 +67,33 @@ stash_usr_regs(struct rt_sigframe __user *sf, struct pt_regs *regs,
               sigset_t *set)
 {
        int err;
-       err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), regs,
+       struct user_regs_struct uregs;
+
+       uregs.scratch.bta       = regs->bta;
+       uregs.scratch.lp_start  = regs->lp_start;
+       uregs.scratch.lp_end    = regs->lp_end;
+       uregs.scratch.lp_count  = regs->lp_count;
+       uregs.scratch.status32  = regs->status32;
+       uregs.scratch.ret       = regs->ret;
+       uregs.scratch.blink     = regs->blink;
+       uregs.scratch.fp        = regs->fp;
+       uregs.scratch.gp        = regs->r26;
+       uregs.scratch.r12       = regs->r12;
+       uregs.scratch.r11       = regs->r11;
+       uregs.scratch.r10       = regs->r10;
+       uregs.scratch.r9        = regs->r9;
+       uregs.scratch.r8        = regs->r8;
+       uregs.scratch.r7        = regs->r7;
+       uregs.scratch.r6        = regs->r6;
+       uregs.scratch.r5        = regs->r5;
+       uregs.scratch.r4        = regs->r4;
+       uregs.scratch.r3        = regs->r3;
+       uregs.scratch.r2        = regs->r2;
+       uregs.scratch.r1        = regs->r1;
+       uregs.scratch.r0        = regs->r0;
+       uregs.scratch.sp        = regs->sp;
+
+       err = __copy_to_user(&(sf->uc.uc_mcontext.regs.scratch), &uregs.scratch,
                             sizeof(sf->uc.uc_mcontext.regs.scratch));
        err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(sigset_t));
 
@@ -78,14 +104,40 @@ static int restore_usr_regs(struct pt_regs *regs, struct rt_sigframe __user *sf)
 {
        sigset_t set;
        int err;
+       struct user_regs_struct uregs;
 
        err = __copy_from_user(&set, &sf->uc.uc_sigmask, sizeof(set));
        if (!err)
                set_current_blocked(&set);
 
-       err |= __copy_from_user(regs, &(sf->uc.uc_mcontext.regs.scratch),
+       err |= __copy_from_user(&uregs.scratch,
+                               &(sf->uc.uc_mcontext.regs.scratch),
                                sizeof(sf->uc.uc_mcontext.regs.scratch));
 
+       regs->bta       = uregs.scratch.bta;
+       regs->lp_start  = uregs.scratch.lp_start;
+       regs->lp_end    = uregs.scratch.lp_end;
+       regs->lp_count  = uregs.scratch.lp_count;
+       regs->status32  = uregs.scratch.status32;
+       regs->ret       = uregs.scratch.ret;
+       regs->blink     = uregs.scratch.blink;
+       regs->fp        = uregs.scratch.fp;
+       regs->r26       = uregs.scratch.gp;
+       regs->r12       = uregs.scratch.r12;
+       regs->r11       = uregs.scratch.r11;
+       regs->r10       = uregs.scratch.r10;
+       regs->r9        = uregs.scratch.r9;
+       regs->r8        = uregs.scratch.r8;
+       regs->r7        = uregs.scratch.r7;
+       regs->r6        = uregs.scratch.r6;
+       regs->r5        = uregs.scratch.r5;
+       regs->r4        = uregs.scratch.r4;
+       regs->r3        = uregs.scratch.r3;
+       regs->r2        = uregs.scratch.r2;
+       regs->r1        = uregs.scratch.r1;
+       regs->r0        = uregs.scratch.r0;
+       regs->sp        = uregs.scratch.sp;
+
        return err;
 }
 
@@ -284,7 +336,7 @@ static void arc_restart_syscall(struct k_sigaction *ka, struct pt_regs *regs)
                 * their orig user space value when we ret from kernel
                 */
                regs->r0 = regs->orig_r0;
-               regs->ret -= 4;
+               regs->ret -= is_isa_arcv2() ? 2 : 4;
                break;
        }
 }
@@ -325,10 +377,10 @@ void do_signal(struct pt_regs *regs)
                if (regs->r0 == -ERESTARTNOHAND ||
                    regs->r0 == -ERESTARTSYS || regs->r0 == -ERESTARTNOINTR) {
                        regs->r0 = regs->orig_r0;
-                       regs->ret -= 4;
+                       regs->ret -= is_isa_arcv2() ? 2 : 4;
                } else if (regs->r0 == -ERESTART_RESTARTBLOCK) {
                        regs->r8 = __NR_restart_syscall;
-                       regs->ret -= 4;
+                       regs->ret -= is_isa_arcv2() ? 2 : 4;
                }
                syscall_wont_restart(regs);     /* No more restarts */
        }