[PATCH 1/4] signal: add a helper to restore a process state from sigcontex
From: Andrei Vagin
Date: Wed Apr 14 2021 - 01:55:08 EST
It will be used to implement process_vm_exec.
Signed-off-by: Andrei Vagin <avagin@xxxxxxxxx>
---
arch/x86/kernel/signal.c | 78 ++++++++++++++++++++++------------------
1 file changed, 43 insertions(+), 35 deletions(-)
diff --git a/arch/x86/kernel/signal.c b/arch/x86/kernel/signal.c
index be0d7d4152ec..cc269a20dd5f 100644
--- a/arch/x86/kernel/signal.c
+++ b/arch/x86/kernel/signal.c
@@ -79,51 +79,43 @@ static void force_valid_ss(struct pt_regs *regs)
# define CONTEXT_COPY_SIZE sizeof(struct sigcontext)
#endif
-static int restore_sigcontext(struct pt_regs *regs,
- struct sigcontext __user *usc,
+static int __restore_sigcontext(struct pt_regs *regs,
+ struct sigcontext __user *sc,
unsigned long uc_flags)
{
- struct sigcontext sc;
-
- /* Always make any pending restarted system calls return -EINTR */
- current->restart_block.fn = do_no_restart_syscall;
-
- if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE))
- return -EFAULT;
-
#ifdef CONFIG_X86_32
- set_user_gs(regs, sc.gs);
- regs->fs = sc.fs;
- regs->es = sc.es;
- regs->ds = sc.ds;
+ set_user_gs(regs, sc->gs);
+ regs->fs = sc->fs;
+ regs->es = sc->es;
+ regs->ds = sc->ds;
#endif /* CONFIG_X86_32 */
- regs->bx = sc.bx;
- regs->cx = sc.cx;
- regs->dx = sc.dx;
- regs->si = sc.si;
- regs->di = sc.di;
- regs->bp = sc.bp;
- regs->ax = sc.ax;
- regs->sp = sc.sp;
- regs->ip = sc.ip;
+ regs->bx = sc->bx;
+ regs->cx = sc->cx;
+ regs->dx = sc->dx;
+ regs->si = sc->si;
+ regs->di = sc->di;
+ regs->bp = sc->bp;
+ regs->ax = sc->ax;
+ regs->sp = sc->sp;
+ regs->ip = sc->ip;
#ifdef CONFIG_X86_64
- regs->r8 = sc.r8;
- regs->r9 = sc.r9;
- regs->r10 = sc.r10;
- regs->r11 = sc.r11;
- regs->r12 = sc.r12;
- regs->r13 = sc.r13;
- regs->r14 = sc.r14;
- regs->r15 = sc.r15;
+ regs->r8 = sc->r8;
+ regs->r9 = sc->r9;
+ regs->r10 = sc->r10;
+ regs->r11 = sc->r11;
+ regs->r12 = sc->r12;
+ regs->r13 = sc->r13;
+ regs->r14 = sc->r14;
+ regs->r15 = sc->r15;
#endif /* CONFIG_X86_64 */
/* Get CS/SS and force CPL3 */
- regs->cs = sc.cs | 0x03;
- regs->ss = sc.ss | 0x03;
+ regs->cs = sc->cs | 0x03;
+ regs->ss = sc->ss | 0x03;
- regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc.flags & FIX_EFLAGS);
+ regs->flags = (regs->flags & ~FIX_EFLAGS) | (sc->flags & FIX_EFLAGS);
/* disable syscall checks */
regs->orig_ax = -1;
@@ -136,10 +128,26 @@ static int restore_sigcontext(struct pt_regs *regs,
force_valid_ss(regs);
#endif
- return fpu__restore_sig((void __user *)sc.fpstate,
+ return fpu__restore_sig((void __user *)sc->fpstate,
IS_ENABLED(CONFIG_X86_32));
}
+static int restore_sigcontext(struct pt_regs *regs,
+ struct sigcontext __user *usc,
+ unsigned long uc_flags)
+{
+ struct sigcontext sc;
+
+ /* Always make any pending restarted system calls return -EINTR */
+ current->restart_block.fn = do_no_restart_syscall;
+
+ if (copy_from_user(&sc, usc, CONTEXT_COPY_SIZE))
+ return -EFAULT;
+
+ return __restore_sigcontext(regs, &sc, uc_flags);
+}
+
+
static __always_inline int
__unsafe_setup_sigcontext(struct sigcontext __user *sc, void __user *fpstate,
struct pt_regs *regs, unsigned long mask)
--
2.29.2