[PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32

2016-10-21 Thread Yury Norov
After that, it will be possible to reuse it in ilp32.

Signed-off-by: Yury Norov 
Signed-off-by: Bamvor Zhang Jian 
---
 arch/arm64/include/asm/signal_common.h | 33 
 arch/arm64/kernel/signal.c | 93 +-
 2 files changed, 92 insertions(+), 34 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal_common.h

diff --git a/arch/arm64/include/asm/signal_common.h 
b/arch/arm64/include/asm/signal_common.h
new file mode 100644
index 000..756ed2c
--- /dev/null
+++ b/arch/arm64/include/asm/signal_common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2016 Cavium Networks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef __ASM_SIGNAL_COMMON_H
+#define __ASM_SIGNAL_COMMON_H
+
+#include 
+#include 
+#include 
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx);
+int restore_fpsimd_context(struct fpsimd_context __user *ctx);
+int setup_sigcontext(struct sigcontext __user *uc_mcontext, struct pt_regs 
*regs);
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sf);
+void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+   void __user *frame, off_t sigframe_off, int usig);
+
+#endif /* __ASM_SIGNAL_COMMON_H */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index f90cdf5..478d6c5 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -34,18 +34,26 @@
 #include 
 #include 
 #include 
+#include 
+
+#define RT_SIGFRAME_FP_POS (offsetof(struct rt_sigframe, sig)  \
+   + offsetof(struct sigframe, fp))
+
+struct sigframe {
+   struct ucontext uc;
+   u64 fp;
+   u64 lr;
+};
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
  */
 struct rt_sigframe {
struct siginfo info;
-   struct ucontext uc;
-   u64 fp;
-   u64 lr;
+   struct sigframe sig;
 };
 
-static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 {
struct fpsimd_state *fpsimd = >thread.fpsimd_state;
int err;
@@ -65,7 +73,7 @@ static int preserve_fpsimd_context(struct fpsimd_context 
__user *ctx)
return err ? -EFAULT : 0;
 }
 
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 {
struct fpsimd_state fpsimd;
__u32 magic, size;
@@ -93,22 +101,30 @@ static int restore_fpsimd_context(struct fpsimd_context 
__user *ctx)
 }
 
 static int restore_sigframe(struct pt_regs *regs,
-   struct rt_sigframe __user *sf)
+   struct sigframe __user *sf)
 {
sigset_t set;
-   int i, err;
-   void *aux = sf->uc.uc_mcontext.__reserved;
-
+   int err;
err = __copy_from_user(, >uc.uc_sigmask, sizeof(set));
if (err == 0)
set_current_blocked();
 
+   err |= restore_sigcontext(regs, >uc.uc_mcontext);
+   return err;
+}
+
+
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user 
*uc_mcontext)
+{
+   int i, err = 0;
+   void *aux = uc_mcontext->__reserved;
+
for (i = 0; i < 31; i++)
-   __get_user_error(regs->regs[i], >uc.uc_mcontext.regs[i],
+   __get_user_error(regs->regs[i], _mcontext->regs[i],
 err);
-   __get_user_error(regs->sp, >uc.uc_mcontext.sp, err);
-   __get_user_error(regs->pc, >uc.uc_mcontext.pc, err);
-   __get_user_error(regs->pstate, >uc.uc_mcontext.pstate, err);
+   __get_user_error(regs->sp, _mcontext->sp, err);
+   __get_user_error(regs->pc, _mcontext->pc, err);
+   __get_user_error(regs->pstate, _mcontext->pstate, err);
 
/*
 * Avoid sys_rt_sigreturn() restarting.
@@ -145,10 +161,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
goto badframe;
 
-   if (restore_sigframe(regs, frame))
+   if (restore_sigframe(regs, >sig))
goto badframe;
 
-   if (restore_altstack(>uc.uc_stack))
+   if (restore_altstack(>sig.uc.uc_stack))
goto badframe;
 
return regs->regs[0];
@@ -162,27 +178,36 @@ 

[PATCH 13/18] arm64: signal: share lp64 signal routines to ilp32

2016-08-17 Thread Yury Norov
After that, it will be possible to reuse it in ilp32.

Signed-off-by: Yury Norov 
---
 arch/arm64/include/asm/signal_common.h | 33 
 arch/arm64/kernel/signal.c | 93 +-
 2 files changed, 92 insertions(+), 34 deletions(-)
 create mode 100644 arch/arm64/include/asm/signal_common.h

diff --git a/arch/arm64/include/asm/signal_common.h 
b/arch/arm64/include/asm/signal_common.h
new file mode 100644
index 000..756ed2c
--- /dev/null
+++ b/arch/arm64/include/asm/signal_common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 1995-2009 Russell King
+ * Copyright (C) 2012 ARM Ltd.
+ * Copyright (C) 2016 Cavium Networks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see .
+ */
+
+#ifndef __ASM_SIGNAL_COMMON_H
+#define __ASM_SIGNAL_COMMON_H
+
+#include 
+#include 
+#include 
+
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx);
+int restore_fpsimd_context(struct fpsimd_context __user *ctx);
+int setup_sigcontext(struct sigcontext __user *uc_mcontext, struct pt_regs 
*regs);
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sf);
+void setup_return(struct pt_regs *regs, struct k_sigaction *ka,
+   void __user *frame, off_t sigframe_off, int usig);
+
+#endif /* __ASM_SIGNAL_COMMON_H */
diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
index be02f65..5c73864 100644
--- a/arch/arm64/kernel/signal.c
+++ b/arch/arm64/kernel/signal.c
@@ -34,18 +34,26 @@
 #include 
 #include 
 #include 
+#include 
+
+#define RT_SIGFRAME_FP_POS (offsetof(struct rt_sigframe, sig)  \
+   + offsetof(struct sigframe, fp))
+
+struct sigframe {
+   struct ucontext uc;
+   u64 fp;
+   u64 lr;
+};
 
 /*
  * Do a signal return; undo the signal stack. These are aligned to 128-bit.
  */
 struct rt_sigframe {
struct siginfo info;
-   struct ucontext uc;
-   u64 fp;
-   u64 lr;
+   struct sigframe sig;
 };
 
-static int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
+int preserve_fpsimd_context(struct fpsimd_context __user *ctx)
 {
struct fpsimd_state *fpsimd = >thread.fpsimd_state;
int err;
@@ -65,7 +73,7 @@ static int preserve_fpsimd_context(struct fpsimd_context 
__user *ctx)
return err ? -EFAULT : 0;
 }
 
-static int restore_fpsimd_context(struct fpsimd_context __user *ctx)
+int restore_fpsimd_context(struct fpsimd_context __user *ctx)
 {
struct fpsimd_state fpsimd;
__u32 magic, size;
@@ -93,22 +101,30 @@ static int restore_fpsimd_context(struct fpsimd_context 
__user *ctx)
 }
 
 static int restore_sigframe(struct pt_regs *regs,
-   struct rt_sigframe __user *sf)
+   struct sigframe __user *sf)
 {
sigset_t set;
-   int i, err;
-   void *aux = sf->uc.uc_mcontext.__reserved;
-
+   int err;
err = __copy_from_user(, >uc.uc_sigmask, sizeof(set));
if (err == 0)
set_current_blocked();
 
+   err |= restore_sigcontext(regs, >uc.uc_mcontext);
+   return err;
+}
+
+
+int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user 
*uc_mcontext)
+{
+   int i, err = 0;
+   void *aux = uc_mcontext->__reserved;
+
for (i = 0; i < 31; i++)
-   __get_user_error(regs->regs[i], >uc.uc_mcontext.regs[i],
+   __get_user_error(regs->regs[i], _mcontext->regs[i],
 err);
-   __get_user_error(regs->sp, >uc.uc_mcontext.sp, err);
-   __get_user_error(regs->pc, >uc.uc_mcontext.pc, err);
-   __get_user_error(regs->pstate, >uc.uc_mcontext.pstate, err);
+   __get_user_error(regs->sp, _mcontext->sp, err);
+   __get_user_error(regs->pc, _mcontext->pc, err);
+   __get_user_error(regs->pstate, _mcontext->pstate, err);
 
/*
 * Avoid sys_rt_sigreturn() restarting.
@@ -145,10 +161,10 @@ asmlinkage long sys_rt_sigreturn(struct pt_regs *regs)
if (!access_ok(VERIFY_READ, frame, sizeof (*frame)))
goto badframe;
 
-   if (restore_sigframe(regs, frame))
+   if (restore_sigframe(regs, >sig))
goto badframe;
 
-   if (restore_altstack(>uc.uc_stack))
+   if (restore_altstack(>sig.uc.uc_stack))
goto badframe;
 
return regs->regs[0];
@@ -162,27 +178,36 @@ badframe:
return 0;
 }
 
-static int