#include <linux/uaccess.h>
 #include <asm/lowcore.h>
 #include <asm/switch_to.h>
+#include <asm/vdso.h>
 #include "compat_linux.h"
 #include "compat_ptrace.h"
 #include "entry.h"
        fpregs_load((_s390_fp_regs *) &user_sregs.fpregs, ¤t->thread.fpu);
 
        clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
-       clear_pt_regs_flag(regs, PIF_SYSCALL_RESTART);
        return 0;
 }
 
                restorer = (unsigned long __force)
                        ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
        } else {
-               /* Signal frames without vectors registers are short ! */
-               __u16 __user *svc = (void __user *) frame + frame_size - 2;
-               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
-                       return -EFAULT;
-               restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
+               restorer = VDSO32_SYMBOL(current, sigreturn);
         }
 
        /* Set up registers for signal handler */
                restorer = (unsigned long __force)
                        ksig->ka.sa.sa_restorer | PSW32_ADDR_AMODE;
        } else {
-               __u16 __user *svc = &frame->svc_insn;
-               if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
-                       return -EFAULT;
-               restorer = (unsigned long __force) svc | PSW32_ADDR_AMODE;
+               restorer = VDSO32_SYMBOL(current, rt_sigreturn);
        }
 
        /* Create siginfo on the signal stack */
 
 #include <linux/uaccess.h>
 #include <asm/lowcore.h>
 #include <asm/switch_to.h>
+#include <asm/vdso.h>
 #include "entry.h"
 
 /*
        fpregs_load(&user_sregs.fpregs, ¤t->thread.fpu);
 
        clear_pt_regs_flag(regs, PIF_SYSCALL); /* No longer in a system call */
-       clear_pt_regs_flag(regs, PIF_SYSCALL_RESTART);
        return 0;
 }
 
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ka->sa.sa_flags & SA_RESTORER) {
+       if (ka->sa.sa_flags & SA_RESTORER)
                restorer = (unsigned long) ka->sa.sa_restorer;
-       } else {
-               /* Signal frame without vector registers are short ! */
-               __u16 __user *svc = (void __user *) frame + frame_size - 2;
-               if (__put_user(S390_SYSCALL_OPCODE | __NR_sigreturn, svc))
-                       return -EFAULT;
-               restorer = (unsigned long) svc;
-       }
+       else
+               restorer = VDSO64_SYMBOL(current, sigreturn);
 
        /* Set up registers for signal handler */
        regs->gprs[14] = restorer;
 
        /* Set up to return from userspace.  If provided, use a stub
           already in userspace.  */
-       if (ksig->ka.sa.sa_flags & SA_RESTORER) {
+       if (ksig->ka.sa.sa_flags & SA_RESTORER)
                restorer = (unsigned long) ksig->ka.sa.sa_restorer;
-       } else {
-               __u16 __user *svc = &frame->svc_insn;
-               if (__put_user(S390_SYSCALL_OPCODE | __NR_rt_sigreturn, svc))
-                       return -EFAULT;
-               restorer = (unsigned long) svc;
-       }
+       else
+               restorer = VDSO64_SYMBOL(current, rt_sigreturn);
 
        /* Create siginfo on the signal stack */
        if (copy_siginfo_to_user(&frame->info, &ksig->info))
                }
                /* No longer in a system call */
                clear_pt_regs_flag(regs, PIF_SYSCALL);
-               clear_pt_regs_flag(regs, PIF_SYSCALL_RESTART);
+
                rseq_signal_deliver(&ksig, regs);
                if (is_compat_task())
                        handle_signal32(&ksig, oldset, regs);
                switch (regs->gprs[2]) {
                case -ERESTART_RESTARTBLOCK:
                        /* Restart with sys_restart_syscall */
-                       regs->int_code = __NR_restart_syscall;
-                       fallthrough;
+                       regs->gprs[2] = regs->orig_gpr2;
+                       current->restart_block.arch_data = regs->psw.addr;
+                       if (is_compat_task())
+                               regs->psw.addr = VDSO32_SYMBOL(current, restart_syscall);
+                       else
+                               regs->psw.addr = VDSO64_SYMBOL(current, restart_syscall);
+                       if (test_thread_flag(TIF_SINGLE_STEP))
+                               clear_thread_flag(TIF_PER_TRAP);
+                       break;
                case -ERESTARTNOHAND:
                case -ERESTARTSYS:
                case -ERESTARTNOINTR:
-                       /* Restart system call with magic TIF bit. */
                        regs->gprs[2] = regs->orig_gpr2;
-                       set_pt_regs_flag(regs, PIF_SYSCALL_RESTART);
+                       regs->psw.addr = __rewind_psw(regs->psw, regs->int_code >> 16);
                        if (test_thread_flag(TIF_SINGLE_STEP))
                                clear_thread_flag(TIF_PER_TRAP);
                        break;