* [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
This series replaces copies to users by unsafe_put_user() and friends
with user_write_access_begin() dance in signal32.
The advantages are:
- No KUAP unlock/lock at every copy
- More readable code.
- Better generated code.
Copying Al Viro who did it on x86 and may have suggestions,
and Dmitry V. Levin who introduced put_compat_sigset()
Christophe Leroy (19):
powerpc/signal: Move inline functions in signal.h
powerpc/ptrace: Move declaration of ptrace_get_reg() and
ptrace_set_reg()
powerpc/ptrace: Consolidate reg index calculation
powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr()
powerpc/signal: Don't manage floating point regs when no FPU
powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x
powerpc/signal: Move access_ok() out of get_sigframe()
powerpc/signal: Remove get_clean_sp()
powerpc/signal: Call get_tm_stackpointer() from get_sigframe()
powerpc/signal: Refactor bad frame logging
powerpc/signal32: Simplify logging in handle_rt_signal32()
powerpc/signal32: Regroup copies in save_user_regs() and
save_tm_user_regs()
powerpc/signal32: Create 'unsafe' versions of
copy_[ck][fpr/vsx]_to_user()
powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to
user_access_begin() logic
powerpc/signal32: Switch handle_signal32() to user_access_begin()
logic
powerpc/signal32: Switch handle_rt_signal32() to user_access_begin()
logic
signal: Add unsafe_put_compat_sigset()
powerpc/signal32: Add and use unsafe_put_sigset_t()
powerpc/signal32: Switch swap_context() to user_access_begin() logic
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/processor.h | 16 +-
arch/powerpc/include/asm/ptrace.h | 6 -
arch/powerpc/kernel/asm-offsets.c | 2 +
arch/powerpc/kernel/process.c | 4 +
arch/powerpc/kernel/ptrace/Makefile | 3 +-
arch/powerpc/kernel/ptrace/ptrace-decl.h | 21 ++
arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 +++
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +
arch/powerpc/kernel/ptrace/ptrace.c | 54 +---
arch/powerpc/kernel/signal.c | 59 ++--
arch/powerpc/kernel/signal.h | 109 ++++++-
arch/powerpc/kernel/signal_32.c | 386 ++++++++++++-----------
arch/powerpc/kernel/signal_64.c | 19 +-
arch/powerpc/kernel/traps.c | 2 +
arch/powerpc/platforms/Kconfig.cputype | 15 +-
include/linux/compat.h | 32 ++
17 files changed, 462 insertions(+), 309 deletions(-)
create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c
--
2.25.0
^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
This series replaces copies to users by unsafe_put_user() and friends
with user_write_access_begin() dance in signal32.
The advantages are:
- No KUAP unlock/lock at every copy
- More readable code.
- Better generated code.
Copying Al Viro who did it on x86 and may have suggestions,
and Dmitry V. Levin who introduced put_compat_sigset()
Christophe Leroy (19):
powerpc/signal: Move inline functions in signal.h
powerpc/ptrace: Move declaration of ptrace_get_reg() and
ptrace_set_reg()
powerpc/ptrace: Consolidate reg index calculation
powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr()
powerpc/signal: Don't manage floating point regs when no FPU
powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x
powerpc/signal: Move access_ok() out of get_sigframe()
powerpc/signal: Remove get_clean_sp()
powerpc/signal: Call get_tm_stackpointer() from get_sigframe()
powerpc/signal: Refactor bad frame logging
powerpc/signal32: Simplify logging in handle_rt_signal32()
powerpc/signal32: Regroup copies in save_user_regs() and
save_tm_user_regs()
powerpc/signal32: Create 'unsafe' versions of
copy_[ck][fpr/vsx]_to_user()
powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to
user_access_begin() logic
powerpc/signal32: Switch handle_signal32() to user_access_begin()
logic
powerpc/signal32: Switch handle_rt_signal32() to user_access_begin()
logic
signal: Add unsafe_put_compat_sigset()
powerpc/signal32: Add and use unsafe_put_sigset_t()
powerpc/signal32: Switch swap_context() to user_access_begin() logic
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/processor.h | 16 +-
arch/powerpc/include/asm/ptrace.h | 6 -
arch/powerpc/kernel/asm-offsets.c | 2 +
arch/powerpc/kernel/process.c | 4 +
arch/powerpc/kernel/ptrace/Makefile | 3 +-
arch/powerpc/kernel/ptrace/ptrace-decl.h | 21 ++
arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 +++
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 +
arch/powerpc/kernel/ptrace/ptrace.c | 54 +---
arch/powerpc/kernel/signal.c | 59 ++--
arch/powerpc/kernel/signal.h | 109 ++++++-
arch/powerpc/kernel/signal_32.c | 386 ++++++++++++-----------
arch/powerpc/kernel/signal_64.c | 19 +-
arch/powerpc/kernel/traps.c | 2 +
arch/powerpc/platforms/Kconfig.cputype | 15 +-
include/linux/compat.h | 32 ++
17 files changed, 462 insertions(+), 309 deletions(-)
create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c
--
2.25.0
^ permalink raw reply [flat|nested] 42+ messages in thread
* [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
To really be inlined, the functions needs to be defined in the
same C file as the caller, or in an included header.
Move functions from signal .c defined inline in signal.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Fixes: 3dd4eb83a9c0 ("powerpc: move common register copy functions from signal_32.c to signal.c")
---
arch/powerpc/kernel/signal.c | 30 --------------------------
arch/powerpc/kernel/signal.h | 41 +++++++++++++++++++++++++++++-------
2 files changed, 33 insertions(+), 38 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index d15a98c758b8..3b56db02b762 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -133,36 +133,6 @@ unsigned long copy_ckvsx_from_user(struct task_struct *task,
return 0;
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
-#else
-inline unsigned long copy_fpr_to_user(void __user *to,
- struct task_struct *task)
-{
- return __copy_to_user(to, task->thread.fp_state.fpr,
- ELF_NFPREG * sizeof(double));
-}
-
-inline unsigned long copy_fpr_from_user(struct task_struct *task,
- void __user *from)
-{
- return __copy_from_user(task->thread.fp_state.fpr, from,
- ELF_NFPREG * sizeof(double));
-}
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-inline unsigned long copy_ckfpr_to_user(void __user *to,
- struct task_struct *task)
-{
- return __copy_to_user(to, task->thread.ckfp_state.fpr,
- ELF_NFPREG * sizeof(double));
-}
-
-inline unsigned long copy_ckfpr_from_user(struct task_struct *task,
- void __user *from)
-{
- return __copy_from_user(task->thread.ckfp_state.fpr, from,
- ELF_NFPREG * sizeof(double));
-}
-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#endif
/* Log an error when sending an unhandled signal to a process. Controlled
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index d396efca4068..4626d39cc0f0 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -19,14 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
-extern unsigned long copy_fpr_to_user(void __user *to,
- struct task_struct *task);
-extern unsigned long copy_ckfpr_to_user(void __user *to,
- struct task_struct *task);
-extern unsigned long copy_fpr_from_user(struct task_struct *task,
- void __user *from);
-extern unsigned long copy_ckfpr_from_user(struct task_struct *task,
- void __user *from);
extern unsigned long get_tm_stackpointer(struct task_struct *tsk);
#ifdef CONFIG_VSX
@@ -38,6 +30,39 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task,
void __user *from);
extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
void __user *from);
+unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
+unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
+unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
+unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
+#else
+static inline unsigned long
+copy_fpr_to_user(void __user *to, struct task_struct *task)
+{
+ return __copy_to_user(to, task->thread.fp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+static inline unsigned long
+copy_fpr_from_user(struct task_struct *task, void __user *from)
+{
+ return __copy_from_user(task->thread.fp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
+{
+ return __copy_to_user(to, task->thread.ckfp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+static inline unsigned long
+copy_ckfpr_from_user(struct task_struct *task, void __user *from)
+{
+ return __copy_from_user(task->thread.ckfp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#endif
#ifdef CONFIG_PPC64
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
To really be inlined, the functions needs to be defined in the
same C file as the caller, or in an included header.
Move functions from signal .c defined inline in signal.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Fixes: 3dd4eb83a9c0 ("powerpc: move common register copy functions from signal_32.c to signal.c")
---
arch/powerpc/kernel/signal.c | 30 --------------------------
arch/powerpc/kernel/signal.h | 41 +++++++++++++++++++++++++++++-------
2 files changed, 33 insertions(+), 38 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index d15a98c758b8..3b56db02b762 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -133,36 +133,6 @@ unsigned long copy_ckvsx_from_user(struct task_struct *task,
return 0;
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
-#else
-inline unsigned long copy_fpr_to_user(void __user *to,
- struct task_struct *task)
-{
- return __copy_to_user(to, task->thread.fp_state.fpr,
- ELF_NFPREG * sizeof(double));
-}
-
-inline unsigned long copy_fpr_from_user(struct task_struct *task,
- void __user *from)
-{
- return __copy_from_user(task->thread.fp_state.fpr, from,
- ELF_NFPREG * sizeof(double));
-}
-
-#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
-inline unsigned long copy_ckfpr_to_user(void __user *to,
- struct task_struct *task)
-{
- return __copy_to_user(to, task->thread.ckfp_state.fpr,
- ELF_NFPREG * sizeof(double));
-}
-
-inline unsigned long copy_ckfpr_from_user(struct task_struct *task,
- void __user *from)
-{
- return __copy_from_user(task->thread.ckfp_state.fpr, from,
- ELF_NFPREG * sizeof(double));
-}
-#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#endif
/* Log an error when sending an unhandled signal to a process. Controlled
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index d396efca4068..4626d39cc0f0 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -19,14 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
-extern unsigned long copy_fpr_to_user(void __user *to,
- struct task_struct *task);
-extern unsigned long copy_ckfpr_to_user(void __user *to,
- struct task_struct *task);
-extern unsigned long copy_fpr_from_user(struct task_struct *task,
- void __user *from);
-extern unsigned long copy_ckfpr_from_user(struct task_struct *task,
- void __user *from);
extern unsigned long get_tm_stackpointer(struct task_struct *tsk);
#ifdef CONFIG_VSX
@@ -38,6 +30,39 @@ extern unsigned long copy_vsx_from_user(struct task_struct *task,
void __user *from);
extern unsigned long copy_ckvsx_from_user(struct task_struct *task,
void __user *from);
+unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
+unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
+unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
+unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
+#else
+static inline unsigned long
+copy_fpr_to_user(void __user *to, struct task_struct *task)
+{
+ return __copy_to_user(to, task->thread.fp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+static inline unsigned long
+copy_fpr_from_user(struct task_struct *task, void __user *from)
+{
+ return __copy_from_user(task->thread.fp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
+{
+ return __copy_to_user(to, task->thread.ckfp_state.fpr,
+ ELF_NFPREG * sizeof(double));
+}
+
+static inline unsigned long
+copy_ckfpr_from_user(struct task_struct *task, void __user *from)
+{
+ return __copy_from_user(task->thread.ckfp_state.fpr, from,
+ ELF_NFPREG * sizeof(double));
+}
+#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#endif
#ifdef CONFIG_PPC64
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
ptrace_get_reg() and ptrace_set_reg() are only used internally by
ptrace.
Move them in arch/powerpc/kernel/ptrace/ptrace-decl.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/ptrace.h | 6 ------
arch/powerpc/kernel/ptrace/ptrace-decl.h | 3 +++
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 155a197c0aa1..3c3cf537c3bf 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -171,12 +171,6 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
set_thread_flag(TIF_NOERROR); \
} while(0)
-struct task_struct;
-extern int ptrace_get_reg(struct task_struct *task, int regno,
- unsigned long *data);
-extern int ptrace_put_reg(struct task_struct *task, int regno,
- unsigned long data);
-
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index 67447a6197eb..2ddc68412fa8 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -159,6 +159,9 @@ int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
/* ptrace-view */
+int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data);
+int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
+
extern const struct user_regset_view user_ppc_native_view;
/* ptrace-(no)adv */
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg()
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
ptrace_get_reg() and ptrace_set_reg() are only used internally by
ptrace.
Move them in arch/powerpc/kernel/ptrace/ptrace-decl.h
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/ptrace.h | 6 ------
arch/powerpc/kernel/ptrace/ptrace-decl.h | 3 +++
2 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/include/asm/ptrace.h b/arch/powerpc/include/asm/ptrace.h
index 155a197c0aa1..3c3cf537c3bf 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -171,12 +171,6 @@ static inline void regs_set_return_value(struct pt_regs *regs, unsigned long rc)
set_thread_flag(TIF_NOERROR); \
} while(0)
-struct task_struct;
-extern int ptrace_get_reg(struct task_struct *task, int regno,
- unsigned long *data);
-extern int ptrace_put_reg(struct task_struct *task, int regno,
- unsigned long data);
-
#define current_pt_regs() \
((struct pt_regs *)((unsigned long)task_stack_page(current) + THREAD_SIZE) - 1)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index 67447a6197eb..2ddc68412fa8 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -159,6 +159,9 @@ int tm_cgpr32_set(struct task_struct *target, const struct user_regset *regset,
/* ptrace-view */
+int ptrace_get_reg(struct task_struct *task, int regno, unsigned long *data);
+int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
+
extern const struct user_regset_view user_ppc_native_view;
/* ptrace-(no)adv */
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Today we have:
#ifdef CONFIG_PPC32
index = addr >> 2;
if ((addr & 3) || child->thread.regs == NULL)
#else
index = addr >> 3;
if ((addr & 7))
#endif
sizeof(long) has value 4 for PPC32 and value 8 for PPC64.
Dividing by 4 is equivalent to >> 2 and dividing by 8 is equivalent
to >> 3.
And 3 and 7 are respectively (sizeof(long) - 1).
Use sizeof(long) to get rid of the #ifdef CONFIG_PPC32 and consolidate
the calculation and checking.
thread.regs have to be not NULL on both PPC32 and PPC64 so adding
that test on PPC64 is harmless.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/ptrace/ptrace.c | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index f6e51be47c6e..0b4645a7a1b4 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -55,14 +55,8 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
-#ifdef CONFIG_PPC32
- index = addr >> 2;
- if ((addr & 3) || (index > PT_FPSCR)
- || (child->thread.regs == NULL))
-#else
- index = addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
-#endif
+ index = addr / sizeof(long);
+ if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
@@ -90,14 +84,8 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
-#ifdef CONFIG_PPC32
- index = addr >> 2;
- if ((addr & 3) || (index > PT_FPSCR)
- || (child->thread.regs == NULL))
-#else
- index = addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
-#endif
+ index = addr / sizeof(long);
+ if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Today we have:
#ifdef CONFIG_PPC32
index = addr >> 2;
if ((addr & 3) || child->thread.regs == NULL)
#else
index = addr >> 3;
if ((addr & 7))
#endif
sizeof(long) has value 4 for PPC32 and value 8 for PPC64.
Dividing by 4 is equivalent to >> 2 and dividing by 8 is equivalent
to >> 3.
And 3 and 7 are respectively (sizeof(long) - 1).
Use sizeof(long) to get rid of the #ifdef CONFIG_PPC32 and consolidate
the calculation and checking.
thread.regs have to be not NULL on both PPC32 and PPC64 so adding
that test on PPC64 is harmless.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/ptrace/ptrace.c | 20 ++++----------------
1 file changed, 4 insertions(+), 16 deletions(-)
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index f6e51be47c6e..0b4645a7a1b4 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -55,14 +55,8 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
-#ifdef CONFIG_PPC32
- index = addr >> 2;
- if ((addr & 3) || (index > PT_FPSCR)
- || (child->thread.regs == NULL))
-#else
- index = addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
-#endif
+ index = addr / sizeof(long);
+ if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
@@ -90,14 +84,8 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
-#ifdef CONFIG_PPC32
- index = addr >> 2;
- if ((addr & 3) || (index > PT_FPSCR)
- || (child->thread.regs == NULL))
-#else
- index = addr >> 3;
- if ((addr & 7) || (index > PT_FPSCR))
-#endif
+ index = addr / sizeof(long);
+ if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
On the same model as ptrace_get_reg() and ptrace_put_reg(),
create ptrace_get_fpr() and ptrace_put_fpr() to get/set
the floating points registers.
We move the boundary checkings in them.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/ptrace/Makefile | 1 +
arch/powerpc/kernel/ptrace/ptrace-decl.h | 4 +++
arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 ++++++++++++++++++++++++
arch/powerpc/kernel/ptrace/ptrace.c | 38 +++++++---------------
4 files changed, 56 insertions(+), 27 deletions(-)
create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c
diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile
index c2f2402ebc8c..77abd1a5a508 100644
--- a/arch/powerpc/kernel/ptrace/Makefile
+++ b/arch/powerpc/kernel/ptrace/Makefile
@@ -6,6 +6,7 @@
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
obj-y += ptrace.o ptrace-view.o
+obj-y += ptrace-fpu.o
obj-$(CONFIG_COMPAT) += ptrace32.o
obj-$(CONFIG_VSX) += ptrace-vsx.o
ifneq ($(CONFIG_VSX),y)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index 2ddc68412fa8..eafe5f0f6289 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
extern const struct user_regset_view user_ppc_native_view;
+/* ptrace-fpu */
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
+
/* ptrace-(no)adv */
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
new file mode 100644
index 000000000000..8301cb52dd99
--- /dev/null
+++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/regset.h>
+
+#include <asm/switch_to.h>
+
+#include "ptrace-decl.h"
+
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
+{
+ unsigned int fpidx = index - PT_FPR0;
+
+ if (index > PT_FPSCR)
+ return -EIO;
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
+ else
+ *data = child->thread.fp_state.fpscr;
+
+ return 0;
+}
+
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
+{
+ unsigned int fpidx = index - PT_FPR0;
+
+ if (index > PT_FPSCR)
+ return -EIO;
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
+ else
+ child->thread.fp_state.fpscr = data;
+
+ return 0;
+}
+
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 0b4645a7a1b4..3d44b73adb83 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -56,24 +56,17 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
index = addr / sizeof(long);
- if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
+ if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
- if (index < PT_FPR0) {
+ if (index < PT_FPR0)
ret = ptrace_get_reg(child, (int) index, &tmp);
- if (ret)
- break;
- } else {
- unsigned int fpidx = index - PT_FPR0;
-
- flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&tmp, &child->thread.TS_FPR(fpidx),
- sizeof(long));
- else
- tmp = child->thread.fp_state.fpscr;
- }
+ else
+ ret = ptrace_get_fpr(child, index, &tmp);
+
+ if (ret)
+ break;
ret = put_user(tmp, datalp);
break;
}
@@ -85,23 +78,14 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
index = addr / sizeof(long);
- if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
+ if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
- if (index < PT_FPR0) {
+ if (index < PT_FPR0)
ret = ptrace_put_reg(child, index, data);
- } else {
- unsigned int fpidx = index - PT_FPR0;
-
- flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&child->thread.TS_FPR(fpidx), &data,
- sizeof(long));
- else
- child->thread.fp_state.fpscr = data;
- ret = 0;
- }
+ else
+ ret = ptrace_put_fpr(child, index, data);
break;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr()
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
On the same model as ptrace_get_reg() and ptrace_put_reg(),
create ptrace_get_fpr() and ptrace_put_fpr() to get/set
the floating points registers.
We move the boundary checkings in them.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/ptrace/Makefile | 1 +
arch/powerpc/kernel/ptrace/ptrace-decl.h | 4 +++
arch/powerpc/kernel/ptrace/ptrace-fpu.c | 40 ++++++++++++++++++++++++
arch/powerpc/kernel/ptrace/ptrace.c | 38 +++++++---------------
4 files changed, 56 insertions(+), 27 deletions(-)
create mode 100644 arch/powerpc/kernel/ptrace/ptrace-fpu.c
diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile
index c2f2402ebc8c..77abd1a5a508 100644
--- a/arch/powerpc/kernel/ptrace/Makefile
+++ b/arch/powerpc/kernel/ptrace/Makefile
@@ -6,6 +6,7 @@
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
obj-y += ptrace.o ptrace-view.o
+obj-y += ptrace-fpu.o
obj-$(CONFIG_COMPAT) += ptrace32.o
obj-$(CONFIG_VSX) += ptrace-vsx.o
ifneq ($(CONFIG_VSX),y)
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index 2ddc68412fa8..eafe5f0f6289 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -164,6 +164,10 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
extern const struct user_regset_view user_ppc_native_view;
+/* ptrace-fpu */
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
+
/* ptrace-(no)adv */
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
int ptrace_get_debugreg(struct task_struct *child, unsigned long addr,
diff --git a/arch/powerpc/kernel/ptrace/ptrace-fpu.c b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
new file mode 100644
index 000000000000..8301cb52dd99
--- /dev/null
+++ b/arch/powerpc/kernel/ptrace/ptrace-fpu.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include <linux/regset.h>
+
+#include <asm/switch_to.h>
+
+#include "ptrace-decl.h"
+
+int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
+{
+ unsigned int fpidx = index - PT_FPR0;
+
+ if (index > PT_FPSCR)
+ return -EIO;
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ memcpy(data, &child->thread.TS_FPR(fpidx), sizeof(long));
+ else
+ *data = child->thread.fp_state.fpscr;
+
+ return 0;
+}
+
+int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
+{
+ unsigned int fpidx = index - PT_FPR0;
+
+ if (index > PT_FPSCR)
+ return -EIO;
+
+ flush_fp_to_thread(child);
+ if (fpidx < (PT_FPSCR - PT_FPR0))
+ memcpy(&child->thread.TS_FPR(fpidx), &data, sizeof(long));
+ else
+ child->thread.fp_state.fpscr = data;
+
+ return 0;
+}
+
diff --git a/arch/powerpc/kernel/ptrace/ptrace.c b/arch/powerpc/kernel/ptrace/ptrace.c
index 0b4645a7a1b4..3d44b73adb83 100644
--- a/arch/powerpc/kernel/ptrace/ptrace.c
+++ b/arch/powerpc/kernel/ptrace/ptrace.c
@@ -56,24 +56,17 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
index = addr / sizeof(long);
- if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
+ if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
- if (index < PT_FPR0) {
+ if (index < PT_FPR0)
ret = ptrace_get_reg(child, (int) index, &tmp);
- if (ret)
- break;
- } else {
- unsigned int fpidx = index - PT_FPR0;
-
- flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&tmp, &child->thread.TS_FPR(fpidx),
- sizeof(long));
- else
- tmp = child->thread.fp_state.fpscr;
- }
+ else
+ ret = ptrace_get_fpr(child, index, &tmp);
+
+ if (ret)
+ break;
ret = put_user(tmp, datalp);
break;
}
@@ -85,23 +78,14 @@ long arch_ptrace(struct task_struct *child, long request,
ret = -EIO;
/* convert to index and check */
index = addr / sizeof(long);
- if ((addr & (sizeof(long) - 1)) || (index > PT_FPSCR) || !child->thread.regs)
+ if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
break;
CHECK_FULL_REGS(child->thread.regs);
- if (index < PT_FPR0) {
+ if (index < PT_FPR0)
ret = ptrace_put_reg(child, index, data);
- } else {
- unsigned int fpidx = index - PT_FPR0;
-
- flush_fp_to_thread(child);
- if (fpidx < (PT_FPSCR - PT_FPR0))
- memcpy(&child->thread.TS_FPR(fpidx), &data,
- sizeof(long));
- else
- child->thread.fp_state.fpscr = data;
- ret = 0;
- }
+ else
+ ret = ptrace_put_fpr(child, index, data);
break;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
There is no point in copying floating point regs when there
is no FPU and MATH_EMULATION is not selected.
Create a new CONFIG_PPC_FPU_REGS bool that is selected by
CONFIG_MATH_EMULATION and CONFIG_PPC_FPU, and use it to
opt out everything related to fp_state in thread_struct.
The asm const used only by fpu.S are opted out with CONFIG_PPC_FPU
as fpu.S build is conditionnal to CONFIG_PPC_FPU.
The following app spends approx 8.1 seconds system time on
an 8xx without the patch, and 7.0 seconds with the patch.
void sigusr1(int sig) { }
int main(int argc, char **argv)
{
int i = 100000;
signal(SIGUSR1, sigusr1);
for (;i--;)
raise(SIGUSR1);
exit(0);
}
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/processor.h | 2 ++
arch/powerpc/kernel/asm-offsets.c | 2 ++
arch/powerpc/kernel/process.c | 4 ++++
arch/powerpc/kernel/ptrace/Makefile | 4 ++--
arch/powerpc/kernel/ptrace/ptrace-decl.h | 14 ++++++++++++++
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 ++
arch/powerpc/kernel/signal.h | 14 +++++++++++++-
arch/powerpc/kernel/signal_32.c | 4 ++++
arch/powerpc/kernel/traps.c | 2 ++
arch/powerpc/platforms/Kconfig.cputype | 4 ++++
11 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1f48bbfb3ce9..a2611880b904 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -416,6 +416,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE
config MATH_EMULATION
bool "Math emulation"
depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE
+ select PPC_FPU_REGS
help
Some PowerPC chips designed for embedded applications do not have
a floating-point unit and therefore do not implement the
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index ed0d633ab5aa..e20b0c5abe62 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -175,8 +175,10 @@ struct thread_struct {
#endif
/* Debug Registers */
struct debug_reg debug;
+#ifdef CONFIG_PPC_FPU_REGS
struct thread_fp_state fp_state;
struct thread_fp_state *fp_save_area;
+#endif
int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_HAVE_HW_BREAKPOINT
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 8711c2164b45..6cb36c341c70 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -110,9 +110,11 @@ int main(void)
#ifdef CONFIG_BOOKE
OFFSET(THREAD_NORMSAVES, thread_struct, normsave[0]);
#endif
+#ifdef CONFIG_PPC_FPU
OFFSET(THREAD_FPEXC_MODE, thread_struct, fpexc_mode);
OFFSET(THREAD_FPSTATE, thread_struct, fp_state.fpr);
OFFSET(THREAD_FPSAVEAREA, thread_struct, fp_save_area);
+#endif
OFFSET(FPSTATE_FPSCR, thread_fp_state, fpscr);
OFFSET(THREAD_LOAD_FP, thread_struct, load_fp);
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 016bd831908e..7e0082ac0a39 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1694,7 +1694,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.ptrace_bps[i] = NULL;
#endif
+#ifdef CONFIG_PPC_FPU_REGS
p->thread.fp_save_area = NULL;
+#endif
#ifdef CONFIG_ALTIVEC
p->thread.vr_save_area = NULL;
#endif
@@ -1821,8 +1823,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
#endif
current->thread.load_slb = 0;
current->thread.load_fp = 0;
+#ifdef CONFIG_PPC_FPU_REGS
memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state));
current->thread.fp_save_area = NULL;
+#endif
#ifdef CONFIG_ALTIVEC
memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state));
current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */
diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile
index 77abd1a5a508..8ebc11d1168d 100644
--- a/arch/powerpc/kernel/ptrace/Makefile
+++ b/arch/powerpc/kernel/ptrace/Makefile
@@ -6,11 +6,11 @@
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
obj-y += ptrace.o ptrace-view.o
-obj-y += ptrace-fpu.o
+obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o
obj-$(CONFIG_COMPAT) += ptrace32.o
obj-$(CONFIG_VSX) += ptrace-vsx.o
ifneq ($(CONFIG_VSX),y)
-obj-y += ptrace-novsx.o
+obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o
endif
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
obj-$(CONFIG_SPE) += ptrace-spe.o
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index eafe5f0f6289..3487f2c9735c 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -165,8 +165,22 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
extern const struct user_regset_view user_ppc_native_view;
/* ptrace-fpu */
+#ifdef CONFIG_PPC_FPU_REGS
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
+#else
+static inline int
+ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
+{
+ return -EIO;
+}
+
+static inline int
+ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
+{
+ return -EIO;
+}
+#endif
/* ptrace-(no)adv */
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 7e6478e7ed07..f1df8c62baf1 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -520,11 +520,13 @@ static const struct user_regset native_regsets[] = {
.size = sizeof(long), .align = sizeof(long),
.regset_get = gpr_get, .set = gpr_set
},
+#ifdef CONFIG_PPC_FPU_REGS
[REGSET_FPR] = {
.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
.size = sizeof(double), .align = sizeof(double),
.regset_get = fpr_get, .set = fpr_set
},
+#endif
#ifdef CONFIG_ALTIVEC
[REGSET_VMX] = {
.core_note_type = NT_PPC_VMX, .n = 34,
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 4626d39cc0f0..6c2a33ab042c 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -34,7 +34,7 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
-#else
+#elif defined(CONFIG_PPC_FPU_REGS)
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
@@ -63,6 +63,18 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from)
ELF_NFPREG * sizeof(double));
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#else
+static inline unsigned long
+copy_fpr_to_user(void __user *to, struct task_struct *task)
+{
+ return 0;
+}
+
+static inline unsigned long
+copy_fpr_from_user(struct task_struct *task, void __user *from)
+{
+ return 0;
+}
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 96950f189b5a..7b291707eb31 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -814,7 +814,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
}
regs->link = tramp;
+#ifdef CONFIG_PPC_FPU_REGS
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
+#endif
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1271,7 +1273,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->link = tramp;
+#ifdef CONFIG_PPC_FPU_REGS
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
+#endif
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d1ebe152f210..5c68f0de905c 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1194,7 +1194,9 @@ static void parse_fpe(struct pt_regs *regs)
flush_fp_to_thread(current);
+#ifdef CONFIG_PPC_FPU_REGS
code = __parse_fpscr(current->thread.fp_state.fpscr);
+#endif
_exception(SIGFPE, regs, code, regs->nip);
}
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 87737ec86d39..40ffcdba42b8 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -225,9 +225,13 @@ config PPC_E500MC
such as e5500/e6500), and must be disabled for running on
e500v1 or e500v2.
+config PPC_FPU_REGS
+ bool
+
config PPC_FPU
bool
default y if PPC64
+ select PPC_FPU_REGS
config FSL_EMB_PERFMON
bool "Freescale Embedded Perfmon"
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
There is no point in copying floating point regs when there
is no FPU and MATH_EMULATION is not selected.
Create a new CONFIG_PPC_FPU_REGS bool that is selected by
CONFIG_MATH_EMULATION and CONFIG_PPC_FPU, and use it to
opt out everything related to fp_state in thread_struct.
The asm const used only by fpu.S are opted out with CONFIG_PPC_FPU
as fpu.S build is conditionnal to CONFIG_PPC_FPU.
The following app spends approx 8.1 seconds system time on
an 8xx without the patch, and 7.0 seconds with the patch.
void sigusr1(int sig) { }
int main(int argc, char **argv)
{
int i = 100000;
signal(SIGUSR1, sigusr1);
for (;i--;)
raise(SIGUSR1);
exit(0);
}
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/processor.h | 2 ++
arch/powerpc/kernel/asm-offsets.c | 2 ++
arch/powerpc/kernel/process.c | 4 ++++
arch/powerpc/kernel/ptrace/Makefile | 4 ++--
arch/powerpc/kernel/ptrace/ptrace-decl.h | 14 ++++++++++++++
arch/powerpc/kernel/ptrace/ptrace-view.c | 2 ++
arch/powerpc/kernel/signal.h | 14 +++++++++++++-
arch/powerpc/kernel/signal_32.c | 4 ++++
arch/powerpc/kernel/traps.c | 2 ++
arch/powerpc/platforms/Kconfig.cputype | 4 ++++
11 files changed, 50 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 1f48bbfb3ce9..a2611880b904 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -416,6 +416,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE
config MATH_EMULATION
bool "Math emulation"
depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE
+ select PPC_FPU_REGS
help
Some PowerPC chips designed for embedded applications do not have
a floating-point unit and therefore do not implement the
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index ed0d633ab5aa..e20b0c5abe62 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -175,8 +175,10 @@ struct thread_struct {
#endif
/* Debug Registers */
struct debug_reg debug;
+#ifdef CONFIG_PPC_FPU_REGS
struct thread_fp_state fp_state;
struct thread_fp_state *fp_save_area;
+#endif
int fpexc_mode; /* floating-point exception mode */
unsigned int align_ctl; /* alignment handling control */
#ifdef CONFIG_HAVE_HW_BREAKPOINT
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 8711c2164b45..6cb36c341c70 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -110,9 +110,11 @@ int main(void)
#ifdef CONFIG_BOOKE
OFFSET(THREAD_NORMSAVES, thread_struct, normsave[0]);
#endif
+#ifdef CONFIG_PPC_FPU
OFFSET(THREAD_FPEXC_MODE, thread_struct, fpexc_mode);
OFFSET(THREAD_FPSTATE, thread_struct, fp_state.fpr);
OFFSET(THREAD_FPSAVEAREA, thread_struct, fp_save_area);
+#endif
OFFSET(FPSTATE_FPSCR, thread_fp_state, fpscr);
OFFSET(THREAD_LOAD_FP, thread_struct, load_fp);
#ifdef CONFIG_ALTIVEC
diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c
index 016bd831908e..7e0082ac0a39 100644
--- a/arch/powerpc/kernel/process.c
+++ b/arch/powerpc/kernel/process.c
@@ -1694,7 +1694,9 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
p->thread.ptrace_bps[i] = NULL;
#endif
+#ifdef CONFIG_PPC_FPU_REGS
p->thread.fp_save_area = NULL;
+#endif
#ifdef CONFIG_ALTIVEC
p->thread.vr_save_area = NULL;
#endif
@@ -1821,8 +1823,10 @@ void start_thread(struct pt_regs *regs, unsigned long start, unsigned long sp)
#endif
current->thread.load_slb = 0;
current->thread.load_fp = 0;
+#ifdef CONFIG_PPC_FPU_REGS
memset(¤t->thread.fp_state, 0, sizeof(current->thread.fp_state));
current->thread.fp_save_area = NULL;
+#endif
#ifdef CONFIG_ALTIVEC
memset(¤t->thread.vr_state, 0, sizeof(current->thread.vr_state));
current->thread.vr_state.vscr.u[3] = 0x00010000; /* Java mode disabled */
diff --git a/arch/powerpc/kernel/ptrace/Makefile b/arch/powerpc/kernel/ptrace/Makefile
index 77abd1a5a508..8ebc11d1168d 100644
--- a/arch/powerpc/kernel/ptrace/Makefile
+++ b/arch/powerpc/kernel/ptrace/Makefile
@@ -6,11 +6,11 @@
CFLAGS_ptrace-view.o += -DUTS_MACHINE='"$(UTS_MACHINE)"'
obj-y += ptrace.o ptrace-view.o
-obj-y += ptrace-fpu.o
+obj-$(CONFIG_PPC_FPU_REGS) += ptrace-fpu.o
obj-$(CONFIG_COMPAT) += ptrace32.o
obj-$(CONFIG_VSX) += ptrace-vsx.o
ifneq ($(CONFIG_VSX),y)
-obj-y += ptrace-novsx.o
+obj-$(CONFIG_PPC_FPU_REGS) += ptrace-novsx.o
endif
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
obj-$(CONFIG_SPE) += ptrace-spe.o
diff --git a/arch/powerpc/kernel/ptrace/ptrace-decl.h b/arch/powerpc/kernel/ptrace/ptrace-decl.h
index eafe5f0f6289..3487f2c9735c 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-decl.h
+++ b/arch/powerpc/kernel/ptrace/ptrace-decl.h
@@ -165,8 +165,22 @@ int ptrace_put_reg(struct task_struct *task, int regno, unsigned long data);
extern const struct user_regset_view user_ppc_native_view;
/* ptrace-fpu */
+#ifdef CONFIG_PPC_FPU_REGS
int ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data);
int ptrace_put_fpr(struct task_struct *child, int index, unsigned long data);
+#else
+static inline int
+ptrace_get_fpr(struct task_struct *child, int index, unsigned long *data)
+{
+ return -EIO;
+}
+
+static inline int
+ptrace_put_fpr(struct task_struct *child, int index, unsigned long data)
+{
+ return -EIO;
+}
+#endif
/* ptrace-(no)adv */
void ppc_gethwdinfo(struct ppc_debug_info *dbginfo);
diff --git a/arch/powerpc/kernel/ptrace/ptrace-view.c b/arch/powerpc/kernel/ptrace/ptrace-view.c
index 7e6478e7ed07..f1df8c62baf1 100644
--- a/arch/powerpc/kernel/ptrace/ptrace-view.c
+++ b/arch/powerpc/kernel/ptrace/ptrace-view.c
@@ -520,11 +520,13 @@ static const struct user_regset native_regsets[] = {
.size = sizeof(long), .align = sizeof(long),
.regset_get = gpr_get, .set = gpr_set
},
+#ifdef CONFIG_PPC_FPU_REGS
[REGSET_FPR] = {
.core_note_type = NT_PRFPREG, .n = ELF_NFPREG,
.size = sizeof(double), .align = sizeof(double),
.regset_get = fpr_get, .set = fpr_set
},
+#endif
#ifdef CONFIG_ALTIVEC
[REGSET_VMX] = {
.core_note_type = NT_PPC_VMX, .n = 34,
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 4626d39cc0f0..6c2a33ab042c 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -34,7 +34,7 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
-#else
+#elif defined(CONFIG_PPC_FPU_REGS)
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
@@ -63,6 +63,18 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from)
ELF_NFPREG * sizeof(double));
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
+#else
+static inline unsigned long
+copy_fpr_to_user(void __user *to, struct task_struct *task)
+{
+ return 0;
+}
+
+static inline unsigned long
+copy_fpr_from_user(struct task_struct *task, void __user *from)
+{
+ return 0;
+}
#endif
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 96950f189b5a..7b291707eb31 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -814,7 +814,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
}
regs->link = tramp;
+#ifdef CONFIG_PPC_FPU_REGS
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
+#endif
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
@@ -1271,7 +1273,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->link = tramp;
+#ifdef CONFIG_PPC_FPU_REGS
tsk->thread.fp_state.fpscr = 0; /* turn off all fp exceptions */
+#endif
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)frame) - __SIGNAL_FRAMESIZE;
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index d1ebe152f210..5c68f0de905c 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1194,7 +1194,9 @@ static void parse_fpe(struct pt_regs *regs)
flush_fp_to_thread(current);
+#ifdef CONFIG_PPC_FPU_REGS
code = __parse_fpscr(current->thread.fp_state.fpscr);
+#endif
_exception(SIGFPE, regs, code, regs->nip);
}
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 87737ec86d39..40ffcdba42b8 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -225,9 +225,13 @@ config PPC_E500MC
such as e5500/e6500), and must be disabled for running on
e500v1 or e500v2.
+config PPC_FPU_REGS
+ bool
+
config PPC_FPU
bool
default y if PPC64
+ select PPC_FPU_REGS
config FSL_EMB_PERFMON
bool "Freescale Embedded Perfmon"
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
The e300c2 core which is embedded in mpc832x CPU doesn't have
an FPU.
Make it possible to not select CONFIG_PPC_FPU when building a
kernel dedicated to that target.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/Kconfig.cputype | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 40ffcdba42b8..d4fd109f177e 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -32,7 +32,7 @@ choice
config PPC_BOOK3S_6xx
bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601"
select PPC_BOOK3S_32
- select PPC_FPU
+ imply PPC_FPU
select PPC_HAVE_PMU_SUPPORT
select PPC_HAVE_KUEP
select PPC_HAVE_KUAP
@@ -229,9 +229,16 @@ config PPC_FPU_REGS
bool
config PPC_FPU
- bool
+ bool "Support for Floating Point Unit (FPU)" if PPC_MPC832x
default y if PPC64
select PPC_FPU_REGS
+ help
+ This must be enabled to support the Floating Point Unit
+ Most 6xx have an FPU but e300c2 core (mpc832x) don't have
+ an FPU, so when building an embedded kernel for that target
+ you can disable FPU support.
+
+ If unsure say Y.
config FSL_EMB_PERFMON
bool "Freescale Embedded Perfmon"
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
The e300c2 core which is embedded in mpc832x CPU doesn't have
an FPU.
Make it possible to not select CONFIG_PPC_FPU when building a
kernel dedicated to that target.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/platforms/Kconfig.cputype | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype
index 40ffcdba42b8..d4fd109f177e 100644
--- a/arch/powerpc/platforms/Kconfig.cputype
+++ b/arch/powerpc/platforms/Kconfig.cputype
@@ -32,7 +32,7 @@ choice
config PPC_BOOK3S_6xx
bool "512x/52xx/6xx/7xx/74xx/82xx/83xx/86xx except 601"
select PPC_BOOK3S_32
- select PPC_FPU
+ imply PPC_FPU
select PPC_HAVE_PMU_SUPPORT
select PPC_HAVE_KUEP
select PPC_HAVE_KUAP
@@ -229,9 +229,16 @@ config PPC_FPU_REGS
bool
config PPC_FPU
- bool
+ bool "Support for Floating Point Unit (FPU)" if PPC_MPC832x
default y if PPC64
select PPC_FPU_REGS
+ help
+ This must be enabled to support the Floating Point Unit
+ Most 6xx have an FPU but e300c2 core (mpc832x) don't have
+ an FPU, so when building an embedded kernel for that target
+ you can disable FPU support.
+
+ If unsure say Y.
config FSL_EMB_PERFMON
bool "Freescale Embedded Perfmon"
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
This access_ok() will soon be performed by user_access_begin().
So move it out of get_sigframe()
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 4 ----
arch/powerpc/kernel/signal_32.c | 4 ++--
arch/powerpc/kernel/signal_64.c | 2 +-
3 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 3b56db02b762..1be5fd01f866 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -154,10 +154,6 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
- /* Check access */
- if (!access_ok((void __user *)newsp, oldsp - newsp))
- return NULL;
-
return (void __user *)newsp;
}
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 7b291707eb31..5a838188a181 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -770,7 +770,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1);
addr = rt_sf;
- if (unlikely(rt_sf == NULL))
+ if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
@@ -1231,7 +1231,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1);
- if (unlikely(frame == NULL))
+ if (!access_ok(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index bfc939360bad..ec259a0efe24 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -825,7 +825,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
BUG_ON(tsk != current);
frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0);
- if (unlikely(frame == NULL))
+ if (!access_ok(frame, sizeof(*frame)))
goto badframe;
err |= __put_user(&frame->info, &frame->pinfo);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe()
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
This access_ok() will soon be performed by user_access_begin().
So move it out of get_sigframe()
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 4 ----
arch/powerpc/kernel/signal_32.c | 4 ++--
arch/powerpc/kernel/signal_64.c | 2 +-
3 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 3b56db02b762..1be5fd01f866 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -154,10 +154,6 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
- /* Check access */
- if (!access_ok((void __user *)newsp, oldsp - newsp))
- return NULL;
-
return (void __user *)newsp;
}
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 7b291707eb31..5a838188a181 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -770,7 +770,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1);
addr = rt_sf;
- if (unlikely(rt_sf == NULL))
+ if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
@@ -1231,7 +1231,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1);
- if (unlikely(frame == NULL))
+ if (!access_ok(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index bfc939360bad..ec259a0efe24 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -825,7 +825,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
BUG_ON(tsk != current);
frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0);
- if (unlikely(frame == NULL))
+ if (!access_ok(frame, sizeof(*frame)))
goto badframe;
err |= __put_user(&frame->info, &frame->pinfo);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:05 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
get_clean_sp() is only used once in kernel/signal.c .
And GCC is smart enough to see that x & 0xffffffff is a nop
calculation on PPC32, no need of a special PPC32 trivial version.
Include the logic from the PPC64 version of get_clean_sp() directly
in get_sigframe()
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/processor.h | 14 --------------
arch/powerpc/kernel/signal.c | 5 ++++-
2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index e20b0c5abe62..8320aedbdca3 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -406,20 +406,6 @@ static inline void prefetchw(const void *x)
#define HAVE_ARCH_PICK_MMAP_LAYOUT
-#ifdef CONFIG_PPC64
-static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
-{
- if (is_32)
- return sp & 0x0ffffffffUL;
- return sp;
-}
-#else
-static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
-{
- return sp;
-}
-#endif
-
/* asm stubs */
extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val);
extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val);
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 1be5fd01f866..a295d482adec 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -150,7 +150,10 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
unsigned long oldsp, newsp;
/* Default to using normal stack */
- oldsp = get_clean_sp(sp, is_32);
+ if (is_32)
+ oldsp = sp & 0x0ffffffffUL;
+ else
+ oldsp = sp;
oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp()
@ 2020-08-12 12:05 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:05 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
get_clean_sp() is only used once in kernel/signal.c .
And GCC is smart enough to see that x & 0xffffffff is a nop
calculation on PPC32, no need of a special PPC32 trivial version.
Include the logic from the PPC64 version of get_clean_sp() directly
in get_sigframe()
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/include/asm/processor.h | 14 --------------
arch/powerpc/kernel/signal.c | 5 ++++-
2 files changed, 4 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h
index e20b0c5abe62..8320aedbdca3 100644
--- a/arch/powerpc/include/asm/processor.h
+++ b/arch/powerpc/include/asm/processor.h
@@ -406,20 +406,6 @@ static inline void prefetchw(const void *x)
#define HAVE_ARCH_PICK_MMAP_LAYOUT
-#ifdef CONFIG_PPC64
-static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
-{
- if (is_32)
- return sp & 0x0ffffffffUL;
- return sp;
-}
-#else
-static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
-{
- return sp;
-}
-#endif
-
/* asm stubs */
extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val);
extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val);
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 1be5fd01f866..a295d482adec 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -150,7 +150,10 @@ void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
unsigned long oldsp, newsp;
/* Default to using normal stack */
- oldsp = get_clean_sp(sp, is_32);
+ if (is_32)
+ oldsp = sp & 0x0ffffffffUL;
+ else
+ oldsp = sp;
oldsp = sigsp(oldsp, ksig);
newsp = (oldsp - frame_size) & ~0xFUL;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Instead of calling get_tm_stackpointer() from the caller, call it
directly from get_sigframe(). This avoids a double call and
allows get_tm_stackpointer() to become static and be inlined
into get_sigframe() by GCC.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 9 ++++++---
arch/powerpc/kernel/signal.h | 6 ++----
arch/powerpc/kernel/signal_32.c | 4 ++--
arch/powerpc/kernel/signal_64.c | 2 +-
4 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a295d482adec..5edded5c5d20 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -144,10 +144,13 @@ int show_unhandled_signals = 1;
/*
* Allocate space for the signal frame
*/
-void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
- size_t frame_size, int is_32)
+static unsigned long get_tm_stackpointer(struct task_struct *tsk);
+
+void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
+ size_t frame_size, int is_32)
{
unsigned long oldsp, newsp;
+ unsigned long sp = get_tm_stackpointer(tsk);
/* Default to using normal stack */
if (is_32)
@@ -304,7 +307,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
user_enter();
}
-unsigned long get_tm_stackpointer(struct task_struct *tsk)
+static unsigned long get_tm_stackpointer(struct task_struct *tsk)
{
/* When in an active transaction that takes a signal, we need to be
* careful with the stack. It's possible that the stack has moved back
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 6c2a33ab042c..fb98731348c3 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -10,8 +10,8 @@
#ifndef _POWERPC_ARCH_SIGNAL_H
#define _POWERPC_ARCH_SIGNAL_H
-extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
- size_t frame_size, int is_32);
+void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
+ size_t frame_size, int is_32);
extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
@@ -19,8 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
-extern unsigned long get_tm_stackpointer(struct task_struct *tsk);
-
#ifdef CONFIG_VSX
extern unsigned long copy_vsx_to_user(void __user *to,
struct task_struct *task);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5a838188a181..3356f6aba4ae 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -768,7 +768,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
- rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1);
+ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
addr = rt_sf;
if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
@@ -1230,7 +1230,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
BUG_ON(tsk != current);
/* Set up Signal Frame */
- frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1);
+ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index ec259a0efe24..92d152c1155c 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -824,7 +824,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
BUG_ON(tsk != current);
- frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0);
+ frame = get_sigframe(ksig, tsk, sizeof(*frame), 0);
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Instead of calling get_tm_stackpointer() from the caller, call it
directly from get_sigframe(). This avoids a double call and
allows get_tm_stackpointer() to become static and be inlined
into get_sigframe() by GCC.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 9 ++++++---
arch/powerpc/kernel/signal.h | 6 ++----
arch/powerpc/kernel/signal_32.c | 4 ++--
arch/powerpc/kernel/signal_64.c | 2 +-
4 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index a295d482adec..5edded5c5d20 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -144,10 +144,13 @@ int show_unhandled_signals = 1;
/*
* Allocate space for the signal frame
*/
-void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
- size_t frame_size, int is_32)
+static unsigned long get_tm_stackpointer(struct task_struct *tsk);
+
+void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
+ size_t frame_size, int is_32)
{
unsigned long oldsp, newsp;
+ unsigned long sp = get_tm_stackpointer(tsk);
/* Default to using normal stack */
if (is_32)
@@ -304,7 +307,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
user_enter();
}
-unsigned long get_tm_stackpointer(struct task_struct *tsk)
+static unsigned long get_tm_stackpointer(struct task_struct *tsk)
{
/* When in an active transaction that takes a signal, we need to be
* careful with the stack. It's possible that the stack has moved back
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index 6c2a33ab042c..fb98731348c3 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -10,8 +10,8 @@
#ifndef _POWERPC_ARCH_SIGNAL_H
#define _POWERPC_ARCH_SIGNAL_H
-extern void __user *get_sigframe(struct ksignal *ksig, unsigned long sp,
- size_t frame_size, int is_32);
+void __user *get_sigframe(struct ksignal *ksig, struct task_struct *tsk,
+ size_t frame_size, int is_32);
extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
@@ -19,8 +19,6 @@ extern int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
extern int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct task_struct *tsk);
-extern unsigned long get_tm_stackpointer(struct task_struct *tsk);
-
#ifdef CONFIG_VSX
extern unsigned long copy_vsx_to_user(void __user *to,
struct task_struct *task);
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 5a838188a181..3356f6aba4ae 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -768,7 +768,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
- rt_sf = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*rt_sf), 1);
+ rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
addr = rt_sf;
if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
@@ -1230,7 +1230,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
BUG_ON(tsk != current);
/* Set up Signal Frame */
- frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 1);
+ frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index ec259a0efe24..92d152c1155c 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -824,7 +824,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
BUG_ON(tsk != current);
- frame = get_sigframe(ksig, get_tm_stackpointer(tsk), sizeof(*frame), 0);
+ frame = get_sigframe(ksig, tsk, sizeof(*frame), 0);
if (!access_ok(frame, sizeof(*frame)))
goto badframe;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
The logging of bad frame appears half a dozen of times
and is pretty similar.
Create signal_fault() fonction to perform that logging.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 11 +++++++++++
arch/powerpc/kernel/signal.h | 3 +++
arch/powerpc/kernel/signal_32.c | 35 +++++----------------------------
arch/powerpc/kernel/signal_64.c | 15 ++------------
4 files changed, 21 insertions(+), 43 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 5edded5c5d20..53b4987a45b5 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -355,3 +355,14 @@ static unsigned long get_tm_stackpointer(struct task_struct *tsk)
#endif
return ret;
}
+
+static const char fmt32[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %08lx lr %08lx\n";
+static const char fmt64[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %016lx lr %016lx\n";
+
+void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
+ const char *where, void __user *ptr)
+{
+ if (show_unhandled_signals)
+ printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, tsk->comm,
+ task_pid_nr(tsk), where, ptr, regs->nip, regs->link);
+}
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index fb98731348c3..f610cfafa478 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -93,4 +93,7 @@ static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
#endif /* !defined(CONFIG_PPC64) */
+void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
+ const char *where, void __user *ptr);
+
#endif /* _POWERPC_ARCH_SIGNAL_H */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 3356f6aba4ae..d1087dd87174 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -837,12 +837,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in handle_rt_signal32: "
- "%p nip %08lx lr %08lx\n",
- tsk->comm, tsk->pid,
- addr, regs->nip, regs->link);
+ signal_fault(tsk, regs, "handle_rt_signal32", addr);
return 1;
}
@@ -1094,12 +1089,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
return 0;
bad:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in sys_rt_sigreturn: "
- "%p nip %08lx lr %08lx\n",
- current->comm, current->pid,
- rt_sf, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_rt_sigreturn", rt_sf);
force_sig(SIGSEGV);
return 0;
@@ -1183,12 +1173,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx,
* We kill the task with a SIGSEGV in this situation.
*/
if (do_setcontext(ctx, regs, 1)) {
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO "%s[%d]: bad frame in "
- "sys_debug_setcontext: %p nip %08lx "
- "lr %08lx\n",
- current->comm, current->pid,
- ctx, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_debug_setcontext", ctx);
force_sig(SIGSEGV);
goto out;
@@ -1291,12 +1276,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in handle_signal32: "
- "%p nip %08lx lr %08lx\n",
- tsk->comm, tsk->pid,
- frame, regs->nip, regs->link);
+ signal_fault(tsk, regs, "handle_signal32", frame);
return 1;
}
@@ -1367,12 +1347,7 @@ SYSCALL_DEFINE0(sigreturn)
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in sys_sigreturn: "
- "%p nip %08lx lr %08lx\n",
- current->comm, current->pid,
- addr, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_sigreturn", addr);
force_sig(SIGSEGV);
return 0;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 92d152c1155c..a10b0bb14131 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -66,11 +66,6 @@ struct rt_sigframe {
char abigap[USER_REDZONE_SIZE];
} __attribute__ ((aligned (16)));
-static const char fmt32[] = KERN_INFO \
- "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n";
-static const char fmt64[] = KERN_INFO \
- "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n";
-
/*
* This computes a quad word aligned pointer inside the vmx_reserve array
* element. For historical reasons sigcontext might not be quad word aligned,
@@ -801,10 +796,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
- current->comm, current->pid, "rt_sigreturn",
- (long)uc, regs->nip, regs->link);
+ signal_fault(current, regs, "rt_sigreturn", uc);
force_sig(SIGSEGV);
return 0;
@@ -913,10 +905,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
- tsk->comm, tsk->pid, "setup_rt_frame",
- (long)frame, regs->nip, regs->link);
+ signal_fault(current, regs, "handle_rt_signal64", frame);
return 1;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
The logging of bad frame appears half a dozen of times
and is pretty similar.
Create signal_fault() fonction to perform that logging.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.c | 11 +++++++++++
arch/powerpc/kernel/signal.h | 3 +++
arch/powerpc/kernel/signal_32.c | 35 +++++----------------------------
arch/powerpc/kernel/signal_64.c | 15 ++------------
4 files changed, 21 insertions(+), 43 deletions(-)
diff --git a/arch/powerpc/kernel/signal.c b/arch/powerpc/kernel/signal.c
index 5edded5c5d20..53b4987a45b5 100644
--- a/arch/powerpc/kernel/signal.c
+++ b/arch/powerpc/kernel/signal.c
@@ -355,3 +355,14 @@ static unsigned long get_tm_stackpointer(struct task_struct *tsk)
#endif
return ret;
}
+
+static const char fmt32[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %08lx lr %08lx\n";
+static const char fmt64[] = KERN_INFO "%s[%d]: bad frame in %s: %p nip %016lx lr %016lx\n";
+
+void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
+ const char *where, void __user *ptr)
+{
+ if (show_unhandled_signals)
+ printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32, tsk->comm,
+ task_pid_nr(tsk), where, ptr, regs->nip, regs->link);
+}
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index fb98731348c3..f610cfafa478 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -93,4 +93,7 @@ static inline int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
#endif /* !defined(CONFIG_PPC64) */
+void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
+ const char *where, void __user *ptr);
+
#endif /* _POWERPC_ARCH_SIGNAL_H */
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 3356f6aba4ae..d1087dd87174 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -837,12 +837,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in handle_rt_signal32: "
- "%p nip %08lx lr %08lx\n",
- tsk->comm, tsk->pid,
- addr, regs->nip, regs->link);
+ signal_fault(tsk, regs, "handle_rt_signal32", addr);
return 1;
}
@@ -1094,12 +1089,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
return 0;
bad:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in sys_rt_sigreturn: "
- "%p nip %08lx lr %08lx\n",
- current->comm, current->pid,
- rt_sf, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_rt_sigreturn", rt_sf);
force_sig(SIGSEGV);
return 0;
@@ -1183,12 +1173,7 @@ SYSCALL_DEFINE3(debug_setcontext, struct ucontext __user *, ctx,
* We kill the task with a SIGSEGV in this situation.
*/
if (do_setcontext(ctx, regs, 1)) {
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO "%s[%d]: bad frame in "
- "sys_debug_setcontext: %p nip %08lx "
- "lr %08lx\n",
- current->comm, current->pid,
- ctx, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_debug_setcontext", ctx);
force_sig(SIGSEGV);
goto out;
@@ -1291,12 +1276,7 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in handle_signal32: "
- "%p nip %08lx lr %08lx\n",
- tsk->comm, tsk->pid,
- frame, regs->nip, regs->link);
+ signal_fault(tsk, regs, "handle_signal32", frame);
return 1;
}
@@ -1367,12 +1347,7 @@ SYSCALL_DEFINE0(sigreturn)
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(KERN_INFO
- "%s[%d]: bad frame in sys_sigreturn: "
- "%p nip %08lx lr %08lx\n",
- current->comm, current->pid,
- addr, regs->nip, regs->link);
+ signal_fault(current, regs, "sys_sigreturn", addr);
force_sig(SIGSEGV);
return 0;
diff --git a/arch/powerpc/kernel/signal_64.c b/arch/powerpc/kernel/signal_64.c
index 92d152c1155c..a10b0bb14131 100644
--- a/arch/powerpc/kernel/signal_64.c
+++ b/arch/powerpc/kernel/signal_64.c
@@ -66,11 +66,6 @@ struct rt_sigframe {
char abigap[USER_REDZONE_SIZE];
} __attribute__ ((aligned (16)));
-static const char fmt32[] = KERN_INFO \
- "%s[%d]: bad frame in %s: %08lx nip %08lx lr %08lx\n";
-static const char fmt64[] = KERN_INFO \
- "%s[%d]: bad frame in %s: %016lx nip %016lx lr %016lx\n";
-
/*
* This computes a quad word aligned pointer inside the vmx_reserve array
* element. For historical reasons sigcontext might not be quad word aligned,
@@ -801,10 +796,7 @@ SYSCALL_DEFINE0(rt_sigreturn)
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
- current->comm, current->pid, "rt_sigreturn",
- (long)uc, regs->nip, regs->link);
+ signal_fault(current, regs, "rt_sigreturn", uc);
force_sig(SIGSEGV);
return 0;
@@ -913,10 +905,7 @@ int handle_rt_signal64(struct ksignal *ksig, sigset_t *set,
return 0;
badframe:
- if (show_unhandled_signals)
- printk_ratelimited(regs->msr & MSR_64BIT ? fmt64 : fmt32,
- tsk->comm, tsk->pid, "setup_rt_frame",
- (long)frame, regs->nip, regs->link);
+ signal_fault(current, regs, "handle_rt_signal64", frame);
return 1;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
If something is bad in the frame, there is no point in
knowing which part of the frame exactly is wrong as it
got allocated as a single block.
Always print the root address of the frame in case on
failed user access, just like handle_signal32().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d1087dd87174..495bee1b713d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -754,7 +754,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct rt_sigframe __user *rt_sf;
struct mcontext __user *frame;
struct mcontext __user *tm_frame = NULL;
- void __user *addr;
unsigned long newsp = 0;
int sigret;
unsigned long tramp;
@@ -769,7 +768,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
- addr = rt_sf;
if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
@@ -784,7 +782,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- addr = frame;
if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) {
sigret = 0;
tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp;
@@ -820,7 +817,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
- addr = (void __user *)regs->gpr[1];
if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
@@ -837,7 +833,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- signal_fault(tsk, regs, "handle_rt_signal32", addr);
+ signal_fault(tsk, regs, "handle_rt_signal32", rt_sf);
return 1;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
If something is bad in the frame, there is no point in
knowing which part of the frame exactly is wrong as it
got allocated as a single block.
Always print the root address of the frame in case on
failed user access, just like handle_signal32().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d1087dd87174..495bee1b713d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -754,7 +754,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
struct rt_sigframe __user *rt_sf;
struct mcontext __user *frame;
struct mcontext __user *tm_frame = NULL;
- void __user *addr;
unsigned long newsp = 0;
int sigret;
unsigned long tramp;
@@ -769,7 +768,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
- addr = rt_sf;
if (!access_ok(rt_sf, sizeof(*rt_sf)))
goto badframe;
@@ -784,7 +782,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Save user registers on the stack */
frame = &rt_sf->uc.uc_mcontext;
- addr = frame;
if (vdso32_rt_sigtramp && tsk->mm->context.vdso_base) {
sigret = 0;
tramp = tsk->mm->context.vdso_base + vdso32_rt_sigtramp;
@@ -820,7 +817,6 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* create a stack frame for the caller of the handler */
newsp = ((unsigned long)rt_sf) - (__SIGNAL_FRAMESIZE + 16);
- addr = (void __user *)regs->gpr[1];
if (put_user(regs->gpr[1], (u32 __user *)newsp))
goto badframe;
@@ -837,7 +833,7 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
return 0;
badframe:
- signal_fault(tsk, regs, "handle_rt_signal32", addr);
+ signal_fault(tsk, regs, "handle_rt_signal32", rt_sf);
return 1;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Reorder actions in save_user_regs() and save_tm_user_regs() to
regroup copies together in order to switch to user_access_begin()
logic in a later patch.
In save_tm_user_regs(), first perform copies to frame, then
perform copies to tm_frame.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 153 +++++++++++++++++++-------------
1 file changed, 91 insertions(+), 62 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 495bee1b713d..2c3d5d4400ec 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -243,6 +243,20 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
/* Make sure floating point registers are stored in regs */
flush_fp_to_thread(current);
+#ifdef CONFIG_ALTIVEC
+ if (current->thread.used_vr)
+ flush_altivec_to_thread(current);
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ current->thread.vrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_VSX
+ if (current->thread.used_vsr && ctx_has_vsx_region)
+ flush_vsx_to_thread(current);
+#endif
+#ifdef CONFIG_SPE
+ if (current->thread.used_spe)
+ flush_spe_to_thread(current);
+#endif
/* save general registers */
if (save_general_regs(regs, frame))
@@ -251,7 +265,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
ELF_NVRREG * sizeof(vector128)))
return 1;
@@ -267,8 +280,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* most significant bits of that same vector. --BenH
* Note that the current VRSAVE value is in the SPR at this point.
*/
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- current->thread.vrsave = mfspr(SPRN_VRSAVE);
if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
@@ -288,7 +299,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* contains valid data
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- flush_vsx_to_thread(current);
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
msr |= MSR_VSX;
@@ -297,7 +307,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
#ifdef CONFIG_SPE
/* save spe registers */
if (current->thread.used_spe) {
- flush_spe_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
ELF_NEVRREG * sizeof(u32)))
return 1;
@@ -314,20 +323,22 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
return 1;
- /* We need to write 0 the MSR top 32 bits in the tm frame so that we
- * can check it on the restore to see if TM is active
- */
- if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
- return 1;
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
return 1;
+ }
+ if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
- }
+
+ /* We need to write 0 the MSR top 32 bits in the tm frame so that we
+ * can check it on the restore to see if TM is active
+ */
+ if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
+ return 1;
return 0;
}
@@ -349,18 +360,16 @@ static int save_tm_user_regs(struct pt_regs *regs,
{
WARN_ON(tm_suspend_disabled);
- /* Save both sets of general registers */
- if (save_general_regs(¤t->thread.ckpt_regs, frame)
- || save_general_regs(regs, tm_frame))
- return 1;
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_SPE
+ if (current->thread.used_spe)
+ flush_spe_to_thread(current);
+#endif
- /* Stash the top half of the 64bit MSR into the 32bit MSR word
- * of the transactional mcontext. This way we have a backward-compatible
- * MSR in the 'normal' (checkpointed) mcontext and additionally one can
- * also look at what type of transaction (T or S) was active at the
- * time of the signal.
- */
- if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
+ if (save_general_regs(¤t->thread.ckpt_regs, frame))
return 1;
#ifdef CONFIG_ALTIVEC
@@ -369,17 +378,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
ELF_NVRREG * sizeof(vector128)))
return 1;
- if (msr & MSR_VEC) {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- } else {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- }
/* set MSR_VEC in the saved MSR value to indicate that
* frame->mc_vregs contains valid data
@@ -392,32 +390,13 @@ static int save_tm_user_regs(struct pt_regs *regs,
* significant bits of a vector, we "cheat" and stuff VRSAVE in the
* most significant bits of that same vector. --BenH
*/
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
if (__put_user(current->thread.ckvrsave,
(u32 __user *)&frame->mc_vregs[32]))
return 1;
- if (msr & MSR_VEC) {
- if (__put_user(current->thread.vrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- } else {
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- }
#endif /* CONFIG_ALTIVEC */
if (copy_ckfpr_to_user(&frame->mc_fregs, current))
return 1;
- if (msr & MSR_FP) {
- if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- } else {
- if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- }
-
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
@@ -428,15 +407,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (current->thread.used_vsr) {
if (copy_ckvsx_to_user(&frame->mc_vsregs, current))
return 1;
- if (msr & MSR_VSX) {
- if (copy_vsx_to_user(&tm_frame->mc_vsregs,
- current))
- return 1;
- } else {
- if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
- return 1;
- }
-
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
@@ -445,7 +415,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
* simply the same as in save_user_regs().
*/
if (current->thread.used_spe) {
- flush_spe_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
ELF_NEVRREG * sizeof(u32)))
return 1;
@@ -466,9 +435,69 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
return 1;
+ }
+ if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
+
+ if (save_general_regs(regs, tm_frame))
+ return 1;
+
+ /* Stash the top half of the 64bit MSR into the 32bit MSR word
+ * of the transactional mcontext. This way we have a backward-compatible
+ * MSR in the 'normal' (checkpointed) mcontext and additionally one can
+ * also look at what type of transaction (T or S) was active at the
+ * time of the signal.
+ */
+ if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
+ return 1;
+
+#ifdef CONFIG_ALTIVEC
+ if (current->thread.used_vr) {
+ if (msr & MSR_VEC) {
+ if (__copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128)))
+ return 1;
+ } else {
+ if (__copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128)))
+ return 1;
+ }
+ }
+
+ if (msr & MSR_VEC) {
+ if (__put_user(current->thread.vrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32]))
+ return 1;
+ } else {
+ if (__put_user(current->thread.ckvrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32]))
+ return 1;
}
+#endif /* CONFIG_ALTIVEC */
+
+ if (msr & MSR_FP) {
+ if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
+ return 1;
+ } else {
+ if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
+ return 1;
+ }
+
+#ifdef CONFIG_VSX
+ if (current->thread.used_vsr) {
+ if (msr & MSR_VSX) {
+ if (copy_vsx_to_user(&tm_frame->mc_vsregs,
+ current))
+ return 1;
+ } else {
+ if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
+ return 1;
+ }
+ }
+#endif /* CONFIG_VSX */
return 0;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Reorder actions in save_user_regs() and save_tm_user_regs() to
regroup copies together in order to switch to user_access_begin()
logic in a later patch.
In save_tm_user_regs(), first perform copies to frame, then
perform copies to tm_frame.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 153 +++++++++++++++++++-------------
1 file changed, 91 insertions(+), 62 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 495bee1b713d..2c3d5d4400ec 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -243,6 +243,20 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
/* Make sure floating point registers are stored in regs */
flush_fp_to_thread(current);
+#ifdef CONFIG_ALTIVEC
+ if (current->thread.used_vr)
+ flush_altivec_to_thread(current);
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ current->thread.vrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_VSX
+ if (current->thread.used_vsr && ctx_has_vsx_region)
+ flush_vsx_to_thread(current);
+#endif
+#ifdef CONFIG_SPE
+ if (current->thread.used_spe)
+ flush_spe_to_thread(current);
+#endif
/* save general registers */
if (save_general_regs(regs, frame))
@@ -251,7 +265,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- flush_altivec_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
ELF_NVRREG * sizeof(vector128)))
return 1;
@@ -267,8 +280,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* most significant bits of that same vector. --BenH
* Note that the current VRSAVE value is in the SPR at this point.
*/
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- current->thread.vrsave = mfspr(SPRN_VRSAVE);
if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
return 1;
#endif /* CONFIG_ALTIVEC */
@@ -288,7 +299,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* contains valid data
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- flush_vsx_to_thread(current);
if (copy_vsx_to_user(&frame->mc_vsregs, current))
return 1;
msr |= MSR_VSX;
@@ -297,7 +307,6 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
#ifdef CONFIG_SPE
/* save spe registers */
if (current->thread.used_spe) {
- flush_spe_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
ELF_NEVRREG * sizeof(u32)))
return 1;
@@ -314,20 +323,22 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
return 1;
- /* We need to write 0 the MSR top 32 bits in the tm frame so that we
- * can check it on the restore to see if TM is active
- */
- if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
- return 1;
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
return 1;
+ }
+ if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
- }
+
+ /* We need to write 0 the MSR top 32 bits in the tm frame so that we
+ * can check it on the restore to see if TM is active
+ */
+ if (tm_frame && __put_user(0, &tm_frame->mc_gregs[PT_MSR]))
+ return 1;
return 0;
}
@@ -349,18 +360,16 @@ static int save_tm_user_regs(struct pt_regs *regs,
{
WARN_ON(tm_suspend_disabled);
- /* Save both sets of general registers */
- if (save_general_regs(¤t->thread.ckpt_regs, frame)
- || save_general_regs(regs, tm_frame))
- return 1;
+#ifdef CONFIG_ALTIVEC
+ if (cpu_has_feature(CPU_FTR_ALTIVEC))
+ current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
+#endif
+#ifdef CONFIG_SPE
+ if (current->thread.used_spe)
+ flush_spe_to_thread(current);
+#endif
- /* Stash the top half of the 64bit MSR into the 32bit MSR word
- * of the transactional mcontext. This way we have a backward-compatible
- * MSR in the 'normal' (checkpointed) mcontext and additionally one can
- * also look at what type of transaction (T or S) was active at the
- * time of the signal.
- */
- if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
+ if (save_general_regs(¤t->thread.ckpt_regs, frame))
return 1;
#ifdef CONFIG_ALTIVEC
@@ -369,17 +378,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
ELF_NVRREG * sizeof(vector128)))
return 1;
- if (msr & MSR_VEC) {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- } else {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- }
/* set MSR_VEC in the saved MSR value to indicate that
* frame->mc_vregs contains valid data
@@ -392,32 +390,13 @@ static int save_tm_user_regs(struct pt_regs *regs,
* significant bits of a vector, we "cheat" and stuff VRSAVE in the
* most significant bits of that same vector. --BenH
*/
- if (cpu_has_feature(CPU_FTR_ALTIVEC))
- current->thread.ckvrsave = mfspr(SPRN_VRSAVE);
if (__put_user(current->thread.ckvrsave,
(u32 __user *)&frame->mc_vregs[32]))
return 1;
- if (msr & MSR_VEC) {
- if (__put_user(current->thread.vrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- } else {
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- }
#endif /* CONFIG_ALTIVEC */
if (copy_ckfpr_to_user(&frame->mc_fregs, current))
return 1;
- if (msr & MSR_FP) {
- if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- } else {
- if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- }
-
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
@@ -428,15 +407,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (current->thread.used_vsr) {
if (copy_ckvsx_to_user(&frame->mc_vsregs, current))
return 1;
- if (msr & MSR_VSX) {
- if (copy_vsx_to_user(&tm_frame->mc_vsregs,
- current))
- return 1;
- } else {
- if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
- return 1;
- }
-
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
@@ -445,7 +415,6 @@ static int save_tm_user_regs(struct pt_regs *regs,
* simply the same as in save_user_regs().
*/
if (current->thread.used_spe) {
- flush_spe_to_thread(current);
if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
ELF_NEVRREG * sizeof(u32)))
return 1;
@@ -466,9 +435,69 @@ static int save_tm_user_regs(struct pt_regs *regs,
if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
|| __put_user(PPC_INST_SC, &frame->tramp[1]))
return 1;
+ }
+ if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
+
+ if (save_general_regs(regs, tm_frame))
+ return 1;
+
+ /* Stash the top half of the 64bit MSR into the 32bit MSR word
+ * of the transactional mcontext. This way we have a backward-compatible
+ * MSR in the 'normal' (checkpointed) mcontext and additionally one can
+ * also look at what type of transaction (T or S) was active at the
+ * time of the signal.
+ */
+ if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
+ return 1;
+
+#ifdef CONFIG_ALTIVEC
+ if (current->thread.used_vr) {
+ if (msr & MSR_VEC) {
+ if (__copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128)))
+ return 1;
+ } else {
+ if (__copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128)))
+ return 1;
+ }
+ }
+
+ if (msr & MSR_VEC) {
+ if (__put_user(current->thread.vrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32]))
+ return 1;
+ } else {
+ if (__put_user(current->thread.ckvrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32]))
+ return 1;
}
+#endif /* CONFIG_ALTIVEC */
+
+ if (msr & MSR_FP) {
+ if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
+ return 1;
+ } else {
+ if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
+ return 1;
+ }
+
+#ifdef CONFIG_VSX
+ if (current->thread.used_vsr) {
+ if (msr & MSR_VSX) {
+ if (copy_vsx_to_user(&tm_frame->mc_vsregs,
+ current))
+ return 1;
+ } else {
+ if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
+ return 1;
+ }
+ }
+#endif /* CONFIG_VSX */
return 0;
}
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
For the non VSX version, that's trivial. Just use unsafe_copy_to_user()
instead of __copy_to_user().
For the VSX version, remove the intermediate step through a buffer and
use unsafe_put_user() directly. This generates a far smaller code which
is acceptable to inline, see below:
Standard VSX version:
0000000000000000 <.copy_fpr_to_user>:
0: 7c 08 02 a6 mflr r0
4: fb e1 ff f8 std r31,-8(r1)
8: 39 00 00 20 li r8,32
c: 39 24 0b 80 addi r9,r4,2944
10: 7d 09 03 a6 mtctr r8
14: f8 01 00 10 std r0,16(r1)
18: f8 21 fe 71 stdu r1,-400(r1)
1c: 39 41 00 68 addi r10,r1,104
20: e9 09 00 00 ld r8,0(r9)
24: 39 4a 00 08 addi r10,r10,8
28: 39 29 00 10 addi r9,r9,16
2c: f9 0a 00 00 std r8,0(r10)
30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20>
34: e9 24 0d 80 ld r9,3456(r4)
38: 3d 42 00 00 addis r10,r2,0
3a: R_PPC64_TOC16_HA .toc
3c: eb ea 00 00 ld r31,0(r10)
3e: R_PPC64_TOC16_LO_DS .toc
40: f9 21 01 70 std r9,368(r1)
44: e9 3f 00 00 ld r9,0(r31)
48: 81 29 00 20 lwz r9,32(r9)
4c: 2f 89 00 00 cmpwi cr7,r9,0
50: 40 9c 00 18 bge cr7,68 <.copy_fpr_to_user+0x68>
54: 4c 00 01 2c isync
58: 3d 20 40 00 lis r9,16384
5c: 79 29 07 c6 rldicr r9,r9,32,31
60: 7d 3d 03 a6 mtspr 29,r9
64: 4c 00 01 2c isync
68: 38 a0 01 08 li r5,264
6c: 38 81 00 70 addi r4,r1,112
70: 48 00 00 01 bl 70 <.copy_fpr_to_user+0x70>
70: R_PPC64_REL24 .__copy_tofrom_user
74: 60 00 00 00 nop
78: e9 3f 00 00 ld r9,0(r31)
7c: 81 29 00 20 lwz r9,32(r9)
80: 2f 89 00 00 cmpwi cr7,r9,0
84: 40 9c 00 18 bge cr7,9c <.copy_fpr_to_user+0x9c>
88: 4c 00 01 2c isync
8c: 39 20 ff ff li r9,-1
90: 79 29 00 44 rldicr r9,r9,0,1
94: 7d 3d 03 a6 mtspr 29,r9
98: 4c 00 01 2c isync
9c: 38 21 01 90 addi r1,r1,400
a0: e8 01 00 10 ld r0,16(r1)
a4: eb e1 ff f8 ld r31,-8(r1)
a8: 7c 08 03 a6 mtlr r0
ac: 4e 80 00 20 blr
'unsafe' simulated VSX version (The ... are only nops) using
unsafe_copy_fpr_to_user() macro:
unsigned long copy_fpr_to_user(void __user *to,
struct task_struct *task)
{
unsafe_copy_fpr_to_user(to, task, failed);
return 0;
failed:
return 1;
}
0000000000000000 <.copy_fpr_to_user>:
0: 39 00 00 20 li r8,32
4: 39 44 0b 80 addi r10,r4,2944
8: 7d 09 03 a6 mtctr r8
c: 7c 69 1b 78 mr r9,r3
...
20: e9 0a 00 00 ld r8,0(r10)
24: f9 09 00 00 std r8,0(r9)
28: 39 4a 00 10 addi r10,r10,16
2c: 39 29 00 08 addi r9,r9,8
30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20>
34: e9 24 0d 80 ld r9,3456(r4)
38: f9 23 01 00 std r9,256(r3)
3c: 38 60 00 00 li r3,0
40: 4e 80 00 20 blr
...
50: 38 60 00 01 li r3,1
54: 4e 80 00 20 blr
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.h | 47 ++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index f610cfafa478..abe570f06c12 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -32,7 +32,49 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
+
+#define unsafe_copy_fpr_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NFPREG - 1 ; i++) \
+ unsafe_put_user(task->thread.TS_FPR(i), &buf[i], label);\
+ unsafe_put_user(task->thread.fp_state.fpscr, &buf[i], label); \
+} while (0)
+
+#define unsafe_copy_vsx_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NVSRHALFREG ; i++) \
+ unsafe_put_user(task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
+ &buf[i], label);\
+} while (0)
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+#define unsafe_copy_ckfpr_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NFPREG - 1 ; i++) \
+ unsafe_put_user(task->thread.TS_CKFPR(i), &buf[i], label);\
+ unsafe_put_user(task->thread.ckfp_state.fpscr, &buf[i], label); \
+} while (0)
+
+#define unsafe_copy_ckvsx_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NVSRHALFREG ; i++) \
+ unsafe_put_user(task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
+ &buf[i], label);\
+} while (0)
+#endif
#elif defined(CONFIG_PPC_FPU_REGS)
+
+#define unsafe_copy_fpr_to_user(to, task, label) \
+ unsafe_copy_to_user(to, task->thread.fp_state.fpr, ELF_NFPREG * sizeof(double), label)
+
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
@@ -48,6 +90,9 @@ copy_fpr_from_user(struct task_struct *task, void __user *from)
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+#define unsafe_copy_ckfpr_to_user(to, task, label) \
+ unsafe_copy_to_user(to, task->thread.ckfp_state.fpr, ELF_NFPREG * sizeof(double), label)
+
inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
{
return __copy_to_user(to, task->thread.ckfp_state.fpr,
@@ -62,6 +107,8 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from)
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#else
+#define unsafe_copy_fpr_to_user(to, task, label) do { } while (0)
+
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
For the non VSX version, that's trivial. Just use unsafe_copy_to_user()
instead of __copy_to_user().
For the VSX version, remove the intermediate step through a buffer and
use unsafe_put_user() directly. This generates a far smaller code which
is acceptable to inline, see below:
Standard VSX version:
0000000000000000 <.copy_fpr_to_user>:
0: 7c 08 02 a6 mflr r0
4: fb e1 ff f8 std r31,-8(r1)
8: 39 00 00 20 li r8,32
c: 39 24 0b 80 addi r9,r4,2944
10: 7d 09 03 a6 mtctr r8
14: f8 01 00 10 std r0,16(r1)
18: f8 21 fe 71 stdu r1,-400(r1)
1c: 39 41 00 68 addi r10,r1,104
20: e9 09 00 00 ld r8,0(r9)
24: 39 4a 00 08 addi r10,r10,8
28: 39 29 00 10 addi r9,r9,16
2c: f9 0a 00 00 std r8,0(r10)
30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20>
34: e9 24 0d 80 ld r9,3456(r4)
38: 3d 42 00 00 addis r10,r2,0
3a: R_PPC64_TOC16_HA .toc
3c: eb ea 00 00 ld r31,0(r10)
3e: R_PPC64_TOC16_LO_DS .toc
40: f9 21 01 70 std r9,368(r1)
44: e9 3f 00 00 ld r9,0(r31)
48: 81 29 00 20 lwz r9,32(r9)
4c: 2f 89 00 00 cmpwi cr7,r9,0
50: 40 9c 00 18 bge cr7,68 <.copy_fpr_to_user+0x68>
54: 4c 00 01 2c isync
58: 3d 20 40 00 lis r9,16384
5c: 79 29 07 c6 rldicr r9,r9,32,31
60: 7d 3d 03 a6 mtspr 29,r9
64: 4c 00 01 2c isync
68: 38 a0 01 08 li r5,264
6c: 38 81 00 70 addi r4,r1,112
70: 48 00 00 01 bl 70 <.copy_fpr_to_user+0x70>
70: R_PPC64_REL24 .__copy_tofrom_user
74: 60 00 00 00 nop
78: e9 3f 00 00 ld r9,0(r31)
7c: 81 29 00 20 lwz r9,32(r9)
80: 2f 89 00 00 cmpwi cr7,r9,0
84: 40 9c 00 18 bge cr7,9c <.copy_fpr_to_user+0x9c>
88: 4c 00 01 2c isync
8c: 39 20 ff ff li r9,-1
90: 79 29 00 44 rldicr r9,r9,0,1
94: 7d 3d 03 a6 mtspr 29,r9
98: 4c 00 01 2c isync
9c: 38 21 01 90 addi r1,r1,400
a0: e8 01 00 10 ld r0,16(r1)
a4: eb e1 ff f8 ld r31,-8(r1)
a8: 7c 08 03 a6 mtlr r0
ac: 4e 80 00 20 blr
'unsafe' simulated VSX version (The ... are only nops) using
unsafe_copy_fpr_to_user() macro:
unsigned long copy_fpr_to_user(void __user *to,
struct task_struct *task)
{
unsafe_copy_fpr_to_user(to, task, failed);
return 0;
failed:
return 1;
}
0000000000000000 <.copy_fpr_to_user>:
0: 39 00 00 20 li r8,32
4: 39 44 0b 80 addi r10,r4,2944
8: 7d 09 03 a6 mtctr r8
c: 7c 69 1b 78 mr r9,r3
...
20: e9 0a 00 00 ld r8,0(r10)
24: f9 09 00 00 std r8,0(r9)
28: 39 4a 00 10 addi r10,r10,16
2c: 39 29 00 08 addi r9,r9,8
30: 42 00 ff f0 bdnz 20 <.copy_fpr_to_user+0x20>
34: e9 24 0d 80 ld r9,3456(r4)
38: f9 23 01 00 std r9,256(r3)
3c: 38 60 00 00 li r3,0
40: 4e 80 00 20 blr
...
50: 38 60 00 01 li r3,1
54: 4e 80 00 20 blr
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal.h | 47 ++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/arch/powerpc/kernel/signal.h b/arch/powerpc/kernel/signal.h
index f610cfafa478..abe570f06c12 100644
--- a/arch/powerpc/kernel/signal.h
+++ b/arch/powerpc/kernel/signal.h
@@ -32,7 +32,49 @@ unsigned long copy_fpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task);
unsigned long copy_fpr_from_user(struct task_struct *task, void __user *from);
unsigned long copy_ckfpr_from_user(struct task_struct *task, void __user *from);
+
+#define unsafe_copy_fpr_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NFPREG - 1 ; i++) \
+ unsafe_put_user(task->thread.TS_FPR(i), &buf[i], label);\
+ unsafe_put_user(task->thread.fp_state.fpscr, &buf[i], label); \
+} while (0)
+
+#define unsafe_copy_vsx_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NVSRHALFREG ; i++) \
+ unsafe_put_user(task->thread.fp_state.fpr[i][TS_VSRLOWOFFSET], \
+ &buf[i], label);\
+} while (0)
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+#define unsafe_copy_ckfpr_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NFPREG - 1 ; i++) \
+ unsafe_put_user(task->thread.TS_CKFPR(i), &buf[i], label);\
+ unsafe_put_user(task->thread.ckfp_state.fpscr, &buf[i], label); \
+} while (0)
+
+#define unsafe_copy_ckvsx_to_user(to, task, label) do { \
+ u64 __user *buf = (u64 __user *)to; \
+ int i; \
+ \
+ for (i = 0; i < ELF_NVSRHALFREG ; i++) \
+ unsafe_put_user(task->thread.ckfp_state.fpr[i][TS_VSRLOWOFFSET], \
+ &buf[i], label);\
+} while (0)
+#endif
#elif defined(CONFIG_PPC_FPU_REGS)
+
+#define unsafe_copy_fpr_to_user(to, task, label) \
+ unsafe_copy_to_user(to, task->thread.fp_state.fpr, ELF_NFPREG * sizeof(double), label)
+
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
@@ -48,6 +90,9 @@ copy_fpr_from_user(struct task_struct *task, void __user *from)
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+#define unsafe_copy_ckfpr_to_user(to, task, label) \
+ unsafe_copy_to_user(to, task->thread.ckfp_state.fpr, ELF_NFPREG * sizeof(double), label)
+
inline unsigned long copy_ckfpr_to_user(void __user *to, struct task_struct *task)
{
return __copy_to_user(to, task->thread.ckfp_state.fpr,
@@ -62,6 +107,8 @@ copy_ckfpr_from_user(struct task_struct *task, void __user *from)
}
#endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
#else
+#define unsafe_copy_fpr_to_user(to, task, label) do { } while (0)
+
static inline unsigned long
copy_fpr_to_user(void __user *to, struct task_struct *task)
{
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 168 ++++++++++++++++----------------
1 file changed, 84 insertions(+), 84 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 2c3d5d4400ec..0d076c2a9f6c 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -98,7 +98,7 @@ static inline int get_sigset_t(sigset_t *set,
#define to_user_ptr(p) ptr_to_compat(p)
#define from_user_ptr(p) compat_ptr(p)
-static inline int save_general_regs(struct pt_regs *regs,
+static __always_inline int save_general_regs(struct pt_regs *regs,
struct mcontext __user *frame)
{
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
@@ -113,10 +113,12 @@ static inline int save_general_regs(struct pt_regs *regs,
else
val = gregs[i];
- if (__put_user(val, &frame->mc_gregs[i]))
- return -EFAULT;
+ unsafe_put_user(val, &frame->mc_gregs[i], failed);
}
return 0;
+
+failed:
+ return 1;
}
static inline int restore_general_regs(struct pt_regs *regs,
@@ -151,11 +153,15 @@ static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
#define to_user_ptr(p) ((unsigned long)(p))
#define from_user_ptr(p) ((void __user *)(p))
-static inline int save_general_regs(struct pt_regs *regs,
+static __always_inline int save_general_regs(struct pt_regs *regs,
struct mcontext __user *frame)
{
WARN_ON(!FULL_REGS(regs));
- return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
+ unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed);
+ return 0;
+
+failed:
+ return 1;
}
static inline int restore_general_regs(struct pt_regs *regs,
@@ -258,16 +264,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
flush_spe_to_thread(current);
#endif
+ if (!user_write_access_begin(frame, sizeof(*frame)))
+ return 1;
+
/* save general registers */
if (save_general_regs(regs, frame))
- return 1;
+ goto failed;
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
/* set MSR_VEC in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
msr |= MSR_VEC;
@@ -280,11 +288,9 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* most significant bits of that same vector. --BenH
* Note that the current VRSAVE value is in the SPR at this point.
*/
- if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
- return 1;
+ unsafe_put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (copy_fpr_to_user(&frame->mc_fregs, current))
- return 1;
+ unsafe_copy_fpr_to_user(&frame->mc_fregs, current, failed);
/*
* Clear the MSR VSX bit to indicate there is no valid state attached
@@ -299,17 +305,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* contains valid data
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- if (copy_vsx_to_user(&frame->mc_vsregs, current))
- return 1;
+ unsafe_copy_vsx_to_user(&frame->mc_vsregs, current, failed);
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
/* save spe registers */
if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32)), failed);
/* set MSR_SPE in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
msr |= MSR_SPE;
@@ -317,19 +321,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
/* else assert((regs->msr & MSR_SPE) == 0) */
/* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
+ unsafe_put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed);
#endif /* CONFIG_SPE */
- if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed);
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
- if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
- || __put_user(PPC_INST_SC, &frame->tramp[1]))
- return 1;
+ unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed);
+ unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed);
}
+ user_write_access_end();
+
if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
@@ -341,6 +344,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
return 1;
return 0;
+
+failed:
+ user_write_access_end();
+ return 1;
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@ -369,15 +376,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
flush_spe_to_thread(current);
#endif
- if (save_general_regs(¤t->thread.ckpt_regs, frame))
+ if (!user_write_access_begin(frame, sizeof(*frame)))
return 1;
+ if (save_general_regs(¤t->thread.ckpt_regs, frame))
+ goto failed;
+
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
/* set MSR_VEC in the saved MSR value to indicate that
* frame->mc_vregs contains valid data
@@ -390,13 +399,11 @@ static int save_tm_user_regs(struct pt_regs *regs,
* significant bits of a vector, we "cheat" and stuff VRSAVE in the
* most significant bits of that same vector. --BenH
*/
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&frame->mc_vregs[32]))
- return 1;
+ unsafe_put_user(current->thread.ckvrsave,
+ (u32 __user *)&frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (copy_ckfpr_to_user(&frame->mc_fregs, current))
- return 1;
+ unsafe_copy_ckfpr_to_user(&frame->mc_fregs, current, failed);
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
@@ -405,8 +412,7 @@ static int save_tm_user_regs(struct pt_regs *regs,
* contains valid data
*/
if (current->thread.used_vsr) {
- if (copy_ckvsx_to_user(&frame->mc_vsregs, current))
- return 1;
+ unsafe_copy_ckvsx_to_user(&frame->mc_vsregs, current, failed);
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
@@ -415,91 +421,85 @@ static int save_tm_user_regs(struct pt_regs *regs,
* simply the same as in save_user_regs().
*/
if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32), failed);
/* set MSR_SPE in the saved MSR value to indicate that
* frame->mc_vregs contains valid data */
msr |= MSR_SPE;
}
/* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
+ unsafe_put_user(current->thread.spefscr,
+ (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed);
#endif /* CONFIG_SPE */
- if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed);
+
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
- if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
- || __put_user(PPC_INST_SC, &frame->tramp[1]))
- return 1;
+ unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed);
+ unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed);
}
+ user_write_access_end();
+
if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
- if (save_general_regs(regs, tm_frame))
+ if (!user_write_access_begin(tm_frame, sizeof(*tm_frame)))
return 1;
+ if (save_general_regs(regs, tm_frame))
+ goto failed;
+
/* Stash the top half of the 64bit MSR into the 32bit MSR word
* of the transactional mcontext. This way we have a backward-compatible
* MSR in the 'normal' (checkpointed) mcontext and additionally one can
* also look at what type of transaction (T or S) was active at the
* time of the signal.
*/
- if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR], failed);
#ifdef CONFIG_ALTIVEC
if (current->thread.used_vr) {
- if (msr & MSR_VEC) {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- } else {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- }
+ if (msr & MSR_VEC)
+ unsafe_copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
+ else
+ unsafe_copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
}
- if (msr & MSR_VEC) {
- if (__put_user(current->thread.vrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- } else {
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- }
+ if (msr & MSR_VEC)
+ unsafe_put_user(current->thread.vrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32], failed);
+ else
+ unsafe_put_user(current->thread.ckvrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (msr & MSR_FP) {
- if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- } else {
- if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- }
+ if (msr & MSR_FP)
+ unsafe_copy_fpr_to_user(&tm_frame->mc_fregs, current, failed);
+ else
+ unsafe_copy_ckfpr_to_user(&tm_frame->mc_fregs, current, failed);
#ifdef CONFIG_VSX
if (current->thread.used_vsr) {
- if (msr & MSR_VSX) {
- if (copy_vsx_to_user(&tm_frame->mc_vsregs,
- current))
- return 1;
- } else {
- if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
- return 1;
- }
+ if (msr & MSR_VSX)
+ unsafe_copy_vsx_to_user(&tm_frame->mc_vsregs, current, failed);
+ else
+ unsafe_copy_ckvsx_to_user(&tm_frame->mc_vsregs, current, failed);
}
#endif /* CONFIG_VSX */
+ user_write_access_end();
return 0;
+
+failed:
+ user_write_access_end();
+ return 1;
}
#endif
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 168 ++++++++++++++++----------------
1 file changed, 84 insertions(+), 84 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 2c3d5d4400ec..0d076c2a9f6c 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -98,7 +98,7 @@ static inline int get_sigset_t(sigset_t *set,
#define to_user_ptr(p) ptr_to_compat(p)
#define from_user_ptr(p) compat_ptr(p)
-static inline int save_general_regs(struct pt_regs *regs,
+static __always_inline int save_general_regs(struct pt_regs *regs,
struct mcontext __user *frame)
{
elf_greg_t64 *gregs = (elf_greg_t64 *)regs;
@@ -113,10 +113,12 @@ static inline int save_general_regs(struct pt_regs *regs,
else
val = gregs[i];
- if (__put_user(val, &frame->mc_gregs[i]))
- return -EFAULT;
+ unsafe_put_user(val, &frame->mc_gregs[i], failed);
}
return 0;
+
+failed:
+ return 1;
}
static inline int restore_general_regs(struct pt_regs *regs,
@@ -151,11 +153,15 @@ static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
#define to_user_ptr(p) ((unsigned long)(p))
#define from_user_ptr(p) ((void __user *)(p))
-static inline int save_general_regs(struct pt_regs *regs,
+static __always_inline int save_general_regs(struct pt_regs *regs,
struct mcontext __user *frame)
{
WARN_ON(!FULL_REGS(regs));
- return __copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE);
+ unsafe_copy_to_user(&frame->mc_gregs, regs, GP_REGS_SIZE, failed);
+ return 0;
+
+failed:
+ return 1;
}
static inline int restore_general_regs(struct pt_regs *regs,
@@ -258,16 +264,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
flush_spe_to_thread(current);
#endif
+ if (!user_write_access_begin(frame, sizeof(*frame)))
+ return 1;
+
/* save general registers */
if (save_general_regs(regs, frame))
- return 1;
+ goto failed;
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
/* set MSR_VEC in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
msr |= MSR_VEC;
@@ -280,11 +288,9 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* most significant bits of that same vector. --BenH
* Note that the current VRSAVE value is in the SPR at this point.
*/
- if (__put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32]))
- return 1;
+ unsafe_put_user(current->thread.vrsave, (u32 __user *)&frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (copy_fpr_to_user(&frame->mc_fregs, current))
- return 1;
+ unsafe_copy_fpr_to_user(&frame->mc_fregs, current, failed);
/*
* Clear the MSR VSX bit to indicate there is no valid state attached
@@ -299,17 +305,15 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
* contains valid data
*/
if (current->thread.used_vsr && ctx_has_vsx_region) {
- if (copy_vsx_to_user(&frame->mc_vsregs, current))
- return 1;
+ unsafe_copy_vsx_to_user(&frame->mc_vsregs, current, failed);
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
#ifdef CONFIG_SPE
/* save spe registers */
if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32)), failed);
/* set MSR_SPE in the saved MSR value to indicate that
frame->mc_vregs contains valid data */
msr |= MSR_SPE;
@@ -317,19 +321,18 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
/* else assert((regs->msr & MSR_SPE) == 0) */
/* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
+ unsafe_put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed);
#endif /* CONFIG_SPE */
- if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed);
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
- if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
- || __put_user(PPC_INST_SC, &frame->tramp[1]))
- return 1;
+ unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed);
+ unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed);
}
+ user_write_access_end();
+
if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
@@ -341,6 +344,10 @@ static int save_user_regs(struct pt_regs *regs, struct mcontext __user *frame,
return 1;
return 0;
+
+failed:
+ user_write_access_end();
+ return 1;
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
@@ -369,15 +376,17 @@ static int save_tm_user_regs(struct pt_regs *regs,
flush_spe_to_thread(current);
#endif
- if (save_general_regs(¤t->thread.ckpt_regs, frame))
+ if (!user_write_access_begin(frame, sizeof(*frame)))
return 1;
+ if (save_general_regs(¤t->thread.ckpt_regs, frame))
+ goto failed;
+
#ifdef CONFIG_ALTIVEC
/* save altivec registers */
if (current->thread.used_vr) {
- if (__copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
/* set MSR_VEC in the saved MSR value to indicate that
* frame->mc_vregs contains valid data
@@ -390,13 +399,11 @@ static int save_tm_user_regs(struct pt_regs *regs,
* significant bits of a vector, we "cheat" and stuff VRSAVE in the
* most significant bits of that same vector. --BenH
*/
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&frame->mc_vregs[32]))
- return 1;
+ unsafe_put_user(current->thread.ckvrsave,
+ (u32 __user *)&frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (copy_ckfpr_to_user(&frame->mc_fregs, current))
- return 1;
+ unsafe_copy_ckfpr_to_user(&frame->mc_fregs, current, failed);
#ifdef CONFIG_VSX
/*
* Copy VSR 0-31 upper half from thread_struct to local
@@ -405,8 +412,7 @@ static int save_tm_user_regs(struct pt_regs *regs,
* contains valid data
*/
if (current->thread.used_vsr) {
- if (copy_ckvsx_to_user(&frame->mc_vsregs, current))
- return 1;
+ unsafe_copy_ckvsx_to_user(&frame->mc_vsregs, current, failed);
msr |= MSR_VSX;
}
#endif /* CONFIG_VSX */
@@ -415,91 +421,85 @@ static int save_tm_user_regs(struct pt_regs *regs,
* simply the same as in save_user_regs().
*/
if (current->thread.used_spe) {
- if (__copy_to_user(&frame->mc_vregs, current->thread.evr,
- ELF_NEVRREG * sizeof(u32)))
- return 1;
+ unsafe_copy_to_user(&frame->mc_vregs, current->thread.evr,
+ ELF_NEVRREG * sizeof(u32), failed);
/* set MSR_SPE in the saved MSR value to indicate that
* frame->mc_vregs contains valid data */
msr |= MSR_SPE;
}
/* We always copy to/from spefscr */
- if (__put_user(current->thread.spefscr, (u32 __user *)&frame->mc_vregs + ELF_NEVRREG))
- return 1;
+ unsafe_put_user(current->thread.spefscr,
+ (u32 __user *)&frame->mc_vregs + ELF_NEVRREG, failed);
#endif /* CONFIG_SPE */
- if (__put_user(msr, &frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user(msr, &frame->mc_gregs[PT_MSR], failed);
+
if (sigret) {
/* Set up the sigreturn trampoline: li 0,sigret; sc */
- if (__put_user(PPC_INST_ADDI + sigret, &frame->tramp[0])
- || __put_user(PPC_INST_SC, &frame->tramp[1]))
- return 1;
+ unsafe_put_user(PPC_INST_ADDI + sigret, &frame->tramp[0], failed);
+ unsafe_put_user(PPC_INST_SC, &frame->tramp[1], failed);
}
+ user_write_access_end();
+
if (sigret)
flush_icache_range((unsigned long) &frame->tramp[0],
(unsigned long) &frame->tramp[2]);
- if (save_general_regs(regs, tm_frame))
+ if (!user_write_access_begin(tm_frame, sizeof(*tm_frame)))
return 1;
+ if (save_general_regs(regs, tm_frame))
+ goto failed;
+
/* Stash the top half of the 64bit MSR into the 32bit MSR word
* of the transactional mcontext. This way we have a backward-compatible
* MSR in the 'normal' (checkpointed) mcontext and additionally one can
* also look at what type of transaction (T or S) was active at the
* time of the signal.
*/
- if (__put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR]))
- return 1;
+ unsafe_put_user((msr >> 32), &tm_frame->mc_gregs[PT_MSR], failed);
#ifdef CONFIG_ALTIVEC
if (current->thread.used_vr) {
- if (msr & MSR_VEC) {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.vr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- } else {
- if (__copy_to_user(&tm_frame->mc_vregs,
- ¤t->thread.ckvr_state,
- ELF_NVRREG * sizeof(vector128)))
- return 1;
- }
+ if (msr & MSR_VEC)
+ unsafe_copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.vr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
+ else
+ unsafe_copy_to_user(&tm_frame->mc_vregs,
+ ¤t->thread.ckvr_state,
+ ELF_NVRREG * sizeof(vector128), failed);
}
- if (msr & MSR_VEC) {
- if (__put_user(current->thread.vrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- } else {
- if (__put_user(current->thread.ckvrsave,
- (u32 __user *)&tm_frame->mc_vregs[32]))
- return 1;
- }
+ if (msr & MSR_VEC)
+ unsafe_put_user(current->thread.vrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32], failed);
+ else
+ unsafe_put_user(current->thread.ckvrsave,
+ (u32 __user *)&tm_frame->mc_vregs[32], failed);
#endif /* CONFIG_ALTIVEC */
- if (msr & MSR_FP) {
- if (copy_fpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- } else {
- if (copy_ckfpr_to_user(&tm_frame->mc_fregs, current))
- return 1;
- }
+ if (msr & MSR_FP)
+ unsafe_copy_fpr_to_user(&tm_frame->mc_fregs, current, failed);
+ else
+ unsafe_copy_ckfpr_to_user(&tm_frame->mc_fregs, current, failed);
#ifdef CONFIG_VSX
if (current->thread.used_vsr) {
- if (msr & MSR_VSX) {
- if (copy_vsx_to_user(&tm_frame->mc_vsregs,
- current))
- return 1;
- } else {
- if (copy_ckvsx_to_user(&tm_frame->mc_vsregs, current))
- return 1;
- }
+ if (msr & MSR_VSX)
+ unsafe_copy_vsx_to_user(&tm_frame->mc_vsregs, current, failed);
+ else
+ unsafe_copy_ckvsx_to_user(&tm_frame->mc_vsregs, current, failed);
}
#endif /* CONFIG_VSX */
+ user_write_access_end();
return 0;
+
+failed:
+ user_write_access_end();
+ return 1;
}
#endif
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() to user_access_begin() logic
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 0d076c2a9f6c..4ea83578ba9d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1241,23 +1241,23 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
- if (!access_ok(frame, sizeof(*frame)))
+ if (!user_write_access_begin(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
#if _NSIG != 64
#error "Please adjust handle_signal()"
#endif
- if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
+ unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed);
+ unsafe_put_user(oldset->sig[0], &sc->oldmask, failed);
#ifdef CONFIG_PPC64
- || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
+ unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed);
#else
- || __put_user(oldset->sig[1], &sc->_unused[3])
+ unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed);
#endif
- || __put_user(to_user_ptr(&frame->mctx), &sc->regs)
- || __put_user(ksig->sig, &sc->signal))
- goto badframe;
+ unsafe_put_user(to_user_ptr(&frame->mctx), &sc->regs, failed);
+ unsafe_put_user(ksig->sig, &sc->signal, failed);
+ user_write_access_end();
if (vdso32_sigtramp && tsk->mm->context.vdso_base) {
sigret = 0;
@@ -1300,6 +1300,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->msr &= ~MSR_LE;
return 0;
+failed:
+ user_write_access_end();
+
badframe:
signal_fault(tsk, regs, "handle_signal32", frame);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() to user_access_begin() logic
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 0d076c2a9f6c..4ea83578ba9d 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -1241,23 +1241,23 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
frame = get_sigframe(ksig, tsk, sizeof(*frame), 1);
- if (!access_ok(frame, sizeof(*frame)))
+ if (!user_write_access_begin(frame, sizeof(*frame)))
goto badframe;
sc = (struct sigcontext __user *) &frame->sctx;
#if _NSIG != 64
#error "Please adjust handle_signal()"
#endif
- if (__put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler)
- || __put_user(oldset->sig[0], &sc->oldmask)
+ unsafe_put_user(to_user_ptr(ksig->ka.sa.sa_handler), &sc->handler, failed);
+ unsafe_put_user(oldset->sig[0], &sc->oldmask, failed);
#ifdef CONFIG_PPC64
- || __put_user((oldset->sig[0] >> 32), &sc->_unused[3])
+ unsafe_put_user((oldset->sig[0] >> 32), &sc->_unused[3], failed);
#else
- || __put_user(oldset->sig[1], &sc->_unused[3])
+ unsafe_put_user(oldset->sig[1], &sc->_unused[3], failed);
#endif
- || __put_user(to_user_ptr(&frame->mctx), &sc->regs)
- || __put_user(ksig->sig, &sc->signal))
- goto badframe;
+ unsafe_put_user(to_user_ptr(&frame->mctx), &sc->regs, failed);
+ unsafe_put_user(ksig->sig, &sc->signal, failed);
+ user_write_access_end();
if (vdso32_sigtramp && tsk->mm->context.vdso_base) {
sigret = 0;
@@ -1300,6 +1300,9 @@ int handle_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->msr &= ~MSR_LE;
return 0;
+failed:
+ user_write_access_end();
+
badframe:
signal_fault(tsk, regs, "handle_signal32", frame);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 47 +++++++++++++++++++++------------
1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 4ea83578ba9d..d03ba3d8eb68 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -58,8 +58,6 @@
#define mcontext mcontext32
#define ucontext ucontext32
-#define __save_altstack __compat_save_altstack
-
/*
* Userspace code may pass a ucontext which doesn't include VSX added
* at the end. We need to check for this case.
@@ -797,16 +795,36 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
- if (!access_ok(rt_sf, sizeof(*rt_sf)))
+ if (!user_write_access_begin(rt_sf, sizeof(*rt_sf)))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)
- || __put_user(0, &rt_sf->uc.uc_flags)
- || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
- || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
- &rt_sf->uc.uc_regs)
- || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
+ unsafe_put_user(0, &rt_sf->uc.uc_flags, failed);
+#ifdef CONFIG_PPC64
+ unsafe_compat_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed);
+#else
+ unsafe_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed);
+#endif
+ unsafe_put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), &rt_sf->uc.uc_regs, failed);
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ tm_frame = &rt_sf->uc_transact.uc_mcontext;
+ if (MSR_TM_ACTIVE(msr)) {
+ unsafe_put_user((unsigned long)&rt_sf->uc_transact,
+ &rt_sf->uc.uc_link, failed);
+ unsafe_put_user((unsigned long)tm_frame,
+ &rt_sf->uc_transact.uc_regs, failed);
+ }
+ else
+#endif
+ {
+ unsafe_put_user(0, &rt_sf->uc.uc_link, failed);
+ }
+ user_write_access_end();
+
+ if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
+ goto badframe;
+ if (copy_siginfo_to_user(&rt_sf->info, &ksig->info))
goto badframe;
/* Save user registers on the stack */
@@ -820,21 +838,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
- tm_frame = &rt_sf->uc_transact.uc_mcontext;
if (MSR_TM_ACTIVE(msr)) {
- if (__put_user((unsigned long)&rt_sf->uc_transact,
- &rt_sf->uc.uc_link) ||
- __put_user((unsigned long)tm_frame,
- &rt_sf->uc_transact.uc_regs))
- goto badframe;
if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr))
goto badframe;
}
else
#endif
{
- if (__put_user(0, &rt_sf->uc.uc_link))
- goto badframe;
if (save_user_regs(regs, frame, tm_frame, sigret, 1))
goto badframe;
}
@@ -861,6 +871,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->msr |= (MSR_KERNEL & MSR_LE);
return 0;
+failed:
+ user_write_access_end();
+
badframe:
signal_fault(tsk, regs, "handle_rt_signal32", rt_sf);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() to user_access_begin() logic
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 47 +++++++++++++++++++++------------
1 file changed, 30 insertions(+), 17 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 4ea83578ba9d..d03ba3d8eb68 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -58,8 +58,6 @@
#define mcontext mcontext32
#define ucontext ucontext32
-#define __save_altstack __compat_save_altstack
-
/*
* Userspace code may pass a ucontext which doesn't include VSX added
* at the end. We need to check for this case.
@@ -797,16 +795,36 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
/* Set up Signal Frame */
/* Put a Real Time Context onto stack */
rt_sf = get_sigframe(ksig, tsk, sizeof(*rt_sf), 1);
- if (!access_ok(rt_sf, sizeof(*rt_sf)))
+ if (!user_write_access_begin(rt_sf, sizeof(*rt_sf)))
goto badframe;
/* Put the siginfo & fill in most of the ucontext */
- if (copy_siginfo_to_user(&rt_sf->info, &ksig->info)
- || __put_user(0, &rt_sf->uc.uc_flags)
- || __save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1])
- || __put_user(to_user_ptr(&rt_sf->uc.uc_mcontext),
- &rt_sf->uc.uc_regs)
- || put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
+ unsafe_put_user(0, &rt_sf->uc.uc_flags, failed);
+#ifdef CONFIG_PPC64
+ unsafe_compat_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed);
+#else
+ unsafe_save_altstack(&rt_sf->uc.uc_stack, regs->gpr[1], failed);
+#endif
+ unsafe_put_user(to_user_ptr(&rt_sf->uc.uc_mcontext), &rt_sf->uc.uc_regs, failed);
+
+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
+ tm_frame = &rt_sf->uc_transact.uc_mcontext;
+ if (MSR_TM_ACTIVE(msr)) {
+ unsafe_put_user((unsigned long)&rt_sf->uc_transact,
+ &rt_sf->uc.uc_link, failed);
+ unsafe_put_user((unsigned long)tm_frame,
+ &rt_sf->uc_transact.uc_regs, failed);
+ }
+ else
+#endif
+ {
+ unsafe_put_user(0, &rt_sf->uc.uc_link, failed);
+ }
+ user_write_access_end();
+
+ if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
+ goto badframe;
+ if (copy_siginfo_to_user(&rt_sf->info, &ksig->info))
goto badframe;
/* Save user registers on the stack */
@@ -820,21 +838,13 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
}
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
- tm_frame = &rt_sf->uc_transact.uc_mcontext;
if (MSR_TM_ACTIVE(msr)) {
- if (__put_user((unsigned long)&rt_sf->uc_transact,
- &rt_sf->uc.uc_link) ||
- __put_user((unsigned long)tm_frame,
- &rt_sf->uc_transact.uc_regs))
- goto badframe;
if (save_tm_user_regs(regs, frame, tm_frame, sigret, msr))
goto badframe;
}
else
#endif
{
- if (__put_user(0, &rt_sf->uc.uc_link))
- goto badframe;
if (save_user_regs(regs, frame, tm_frame, sigret, 1))
goto badframe;
}
@@ -861,6 +871,9 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
regs->msr |= (MSR_KERNEL & MSR_LE);
return 0;
+failed:
+ user_write_access_end();
+
badframe:
signal_fault(tsk, regs, "handle_rt_signal32", rt_sf);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
Implement 'unsafe' version of put_compat_sigset()
For the bigendian, use unsafe_put_user() directly
to avoid intermediate copy through the stack.
For the littleendian, use a straight unsafe_copy_to_user().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dmitry V. Levin <ldv@altlinux.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/compat.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index c4255d8a4a8a..bbe5f9658ed1 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -442,6 +442,38 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
#endif
}
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define unsafe_put_compat_sigset(compat, set, label) do { \
+ compat_sigset_t __user *__c = compat; \
+ const sigset_t *__s = set; \
+ \
+ switch (_NSIG_WORDS) { \
+ case 4: \
+ unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
+ unsafe_put_user(__s->sig[3], __c->sig[6], label); \
+ fallthrough; \
+ case 3: \
+ unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
+ unsafe_put_user(__s->sig[2], __c->sig[4], label); \
+ fallthrough; \
+ case 2: \
+ unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
+ unsafe_put_user(__s->sig[1], __c->sig[2], label); \
+ fallthrough; \
+ case 1: \
+ unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
+ unsafe_put_user(__s->sig[0], __c->sig[0], label); \
+ } \
+} while (0)
+#else
+#define unsafe_put_compat_sigset(compat, set, label) do { \
+ compat_sigset_t __user *__c = compat; \
+ const sigset_t *__s = set; \
+ \
+ unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \
+} while (0)
+#endif
+
extern int compat_ptrace_request(struct task_struct *child,
compat_long_t request,
compat_ulong_t addr, compat_ulong_t data);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
Implement 'unsafe' version of put_compat_sigset()
For the bigendian, use unsafe_put_user() directly
to avoid intermediate copy through the stack.
For the littleendian, use a straight unsafe_copy_to_user().
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Dmitry V. Levin <ldv@altlinux.org>
Cc: Al Viro <viro@zeniv.linux.org.uk>
---
include/linux/compat.h | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/include/linux/compat.h b/include/linux/compat.h
index c4255d8a4a8a..bbe5f9658ed1 100644
--- a/include/linux/compat.h
+++ b/include/linux/compat.h
@@ -442,6 +442,38 @@ put_compat_sigset(compat_sigset_t __user *compat, const sigset_t *set,
#endif
}
+#ifdef CONFIG_CPU_BIG_ENDIAN
+#define unsafe_put_compat_sigset(compat, set, label) do { \
+ compat_sigset_t __user *__c = compat; \
+ const sigset_t *__s = set; \
+ \
+ switch (_NSIG_WORDS) { \
+ case 4: \
+ unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
+ unsafe_put_user(__s->sig[3], __c->sig[6], label); \
+ fallthrough; \
+ case 3: \
+ unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
+ unsafe_put_user(__s->sig[2], __c->sig[4], label); \
+ fallthrough; \
+ case 2: \
+ unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
+ unsafe_put_user(__s->sig[1], __c->sig[2], label); \
+ fallthrough; \
+ case 1: \
+ unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
+ unsafe_put_user(__s->sig[0], __c->sig[0], label); \
+ } \
+} while (0)
+#else
+#define unsafe_put_compat_sigset(compat, set, label) do { \
+ compat_sigset_t __user *__c = compat; \
+ const sigset_t *__s = set; \
+ \
+ unsafe_copy_to_user(__c, __s, sizeof(*__c), label); \
+} while (0)
+#endif
+
extern int compat_ptrace_request(struct task_struct *child,
compat_long_t request,
compat_ulong_t addr, compat_ulong_t data);
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t()
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
put_sigset_t() calls copy_to_user() for copying two words.
Because INLINE_COPY_TO_USER is not defined on powerpc,
copy_to_user() doesn't get optimised and falls back to
copy_tofrom_user() with the relevant glue. This is terribly
inefficient for copying two words.
By switching to unsafe_put_user(), we end up with something as
simple as:
3cc: 81 3d 00 00 lwz r9,0(r29)
3d0: 91 26 00 b4 stw r9,180(r6)
3d4: 81 3d 00 04 lwz r9,4(r29)
3d8: 91 26 00 b8 stw r9,184(r6)
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d03ba3d8eb68..6cbff0293ff4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -87,6 +87,8 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
return put_compat_sigset(uset, set, sizeof(*uset));
}
+#define unsafe_put_sigset_t unsafe_put_compat_sigset
+
static inline int get_sigset_t(sigset_t *set,
const compat_sigset_t __user *uset)
{
@@ -143,6 +145,13 @@ static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
return copy_to_user(uset, set, sizeof(*uset));
}
+#define unsafe_put_sigset_t(uset, set, label) do { \
+ sigset_t __user *__us = uset ; \
+ const sigset_t *__s = set; \
+ \
+ unsafe_copy_to_user(__us, __s, sizeof(*__us), label); \
+} while (0)
+
static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
{
return copy_from_user(set, uset, sizeof(*uset));
@@ -820,10 +829,11 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
{
unsafe_put_user(0, &rt_sf->uc.uc_link, failed);
}
+
+ unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
+
user_write_access_end();
- if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
- goto badframe;
if (copy_siginfo_to_user(&rt_sf->info, &ksig->info))
goto badframe;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t()
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
put_sigset_t() calls copy_to_user() for copying two words.
Because INLINE_COPY_TO_USER is not defined on powerpc,
copy_to_user() doesn't get optimised and falls back to
copy_tofrom_user() with the relevant glue. This is terribly
inefficient for copying two words.
By switching to unsafe_put_user(), we end up with something as
simple as:
3cc: 81 3d 00 00 lwz r9,0(r29)
3d0: 91 26 00 b4 stw r9,180(r6)
3d4: 81 3d 00 04 lwz r9,4(r29)
3d8: 91 26 00 b8 stw r9,184(r6)
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index d03ba3d8eb68..6cbff0293ff4 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -87,6 +87,8 @@ static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
return put_compat_sigset(uset, set, sizeof(*uset));
}
+#define unsafe_put_sigset_t unsafe_put_compat_sigset
+
static inline int get_sigset_t(sigset_t *set,
const compat_sigset_t __user *uset)
{
@@ -143,6 +145,13 @@ static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
return copy_to_user(uset, set, sizeof(*uset));
}
+#define unsafe_put_sigset_t(uset, set, label) do { \
+ sigset_t __user *__us = uset ; \
+ const sigset_t *__s = set; \
+ \
+ unsafe_copy_to_user(__us, __s, sizeof(*__us), label); \
+} while (0)
+
static inline int get_sigset_t(sigset_t *set, const sigset_t __user *uset)
{
return copy_from_user(set, uset, sizeof(*uset));
@@ -820,10 +829,11 @@ int handle_rt_signal32(struct ksignal *ksig, sigset_t *oldset,
{
unsafe_put_user(0, &rt_sf->uc.uc_link, failed);
}
+
+ unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
+
user_write_access_end();
- if (put_sigset_t(&rt_sf->uc.uc_sigmask, oldset))
- goto badframe;
if (copy_siginfo_to_user(&rt_sf->info, &ksig->info))
goto badframe;
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic
2020-08-12 12:05 ` Christophe Leroy
@ 2020-08-12 12:06 ` Christophe Leroy
-1 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linux-kernel, linuxppc-dev
As this was the last user of put_sigset_t(), remove it as well.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 6cbff0293ff4..399d823782cf 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -82,11 +82,6 @@
* Functions for flipping sigsets (thanks to brain dead generic
* implementation that makes things simple for little endian only)
*/
-static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
-{
- return put_compat_sigset(uset, set, sizeof(*uset));
-}
-
#define unsafe_put_sigset_t unsafe_put_compat_sigset
static inline int get_sigset_t(sigset_t *set,
@@ -140,11 +135,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
-static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
-{
- return copy_to_user(uset, set, sizeof(*uset));
-}
-
#define unsafe_put_sigset_t(uset, set, label) do { \
sigset_t __user *__us = uset ; \
const sigset_t *__s = set; \
@@ -1012,11 +1002,13 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
*/
mctx = (struct mcontext __user *)
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
- if (!access_ok(old_ctx, ctx_size)
- || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
- || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
- || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
+ if (save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region))
+ return -EFAULT;
+ if (!user_write_access_begin(old_ctx, ctx_size))
return -EFAULT;
+ unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed);
+ unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed);
+ user_write_access_end();
}
if (new_ctx == NULL)
return 0;
@@ -1040,6 +1032,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
set_thread_flag(TIF_RESTOREALL);
return 0;
+
+failed:
+ user_write_access_end();
+ return -EFAULT;
}
#ifdef CONFIG_PPC64
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic
@ 2020-08-12 12:06 ` Christophe Leroy
0 siblings, 0 replies; 42+ messages in thread
From: Christophe Leroy @ 2020-08-12 12:06 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, ldv, viro
Cc: linuxppc-dev, linux-kernel
As this was the last user of put_sigset_t(), remove it as well.
Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
arch/powerpc/kernel/signal_32.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/kernel/signal_32.c b/arch/powerpc/kernel/signal_32.c
index 6cbff0293ff4..399d823782cf 100644
--- a/arch/powerpc/kernel/signal_32.c
+++ b/arch/powerpc/kernel/signal_32.c
@@ -82,11 +82,6 @@
* Functions for flipping sigsets (thanks to brain dead generic
* implementation that makes things simple for little endian only)
*/
-static inline int put_sigset_t(compat_sigset_t __user *uset, sigset_t *set)
-{
- return put_compat_sigset(uset, set, sizeof(*uset));
-}
-
#define unsafe_put_sigset_t unsafe_put_compat_sigset
static inline int get_sigset_t(sigset_t *set,
@@ -140,11 +135,6 @@ static inline int restore_general_regs(struct pt_regs *regs,
#define GP_REGS_SIZE min(sizeof(elf_gregset_t), sizeof(struct pt_regs))
-static inline int put_sigset_t(sigset_t __user *uset, sigset_t *set)
-{
- return copy_to_user(uset, set, sizeof(*uset));
-}
-
#define unsafe_put_sigset_t(uset, set, label) do { \
sigset_t __user *__us = uset ; \
const sigset_t *__s = set; \
@@ -1012,11 +1002,13 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
*/
mctx = (struct mcontext __user *)
((unsigned long) &old_ctx->uc_mcontext & ~0xfUL);
- if (!access_ok(old_ctx, ctx_size)
- || save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region)
- || put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked)
- || __put_user(to_user_ptr(mctx), &old_ctx->uc_regs))
+ if (save_user_regs(regs, mctx, NULL, 0, ctx_has_vsx_region))
+ return -EFAULT;
+ if (!user_write_access_begin(old_ctx, ctx_size))
return -EFAULT;
+ unsafe_put_sigset_t(&old_ctx->uc_sigmask, ¤t->blocked, failed);
+ unsafe_put_user(to_user_ptr(mctx), &old_ctx->uc_regs, failed);
+ user_write_access_end();
}
if (new_ctx == NULL)
return 0;
@@ -1040,6 +1032,10 @@ SYSCALL_DEFINE3(swapcontext, struct ucontext __user *, old_ctx,
set_thread_flag(TIF_RESTOREALL);
return 0;
+
+failed:
+ user_write_access_end();
+ return -EFAULT;
}
#ifdef CONFIG_PPC64
--
2.25.0
^ permalink raw reply related [flat|nested] 42+ messages in thread
* Re: [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t()
2020-08-12 12:06 ` Christophe Leroy
(?)
@ 2020-08-12 14:01 ` kernel test robot
-1 siblings, 0 replies; 42+ messages in thread
From: kernel test robot @ 2020-08-12 14:01 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 89916 bytes --]
Hi Christophe,
[FYI, it's a private test report for your RFC patch.]
[auto build test WARNING on linus/master]
[also build test WARNING on next-20200812]
[cannot apply to powerpc/next v5.8]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-Switch-signal-32-to-using-user_access_begin-and-friends/20200812-200934
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git fb893de323e2d39f7a1f6df425703a2edbdf56ea
config: powerpc-allyesconfig (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
In file included from include/linux/uaccess.h:11,
from include/linux/sched/task.h:11,
from include/linux/sched/signal.h:9,
from include/linux/rcuwait.h:6,
from include/linux/percpu-rwsem.h:7,
from include/linux/fs.h:33,
from include/linux/huge_mm.h:8,
from include/linux/mm.h:675,
from arch/powerpc/kernel/signal_32.c:17:
arch/powerpc/kernel/signal_32.c: In function 'handle_rt_signal32':
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:452:3: note: in expansion of macro 'unsafe_put_user'
452 | unsafe_put_user(__s->sig[3] >> 32, __c->sig[7], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:453:3: note: in expansion of macro 'unsafe_put_user'
453 | unsafe_put_user(__s->sig[3], __c->sig[6], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:456:3: note: in expansion of macro 'unsafe_put_user'
456 | unsafe_put_user(__s->sig[2] >> 32, __c->sig[5], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:457:3: note: in expansion of macro 'unsafe_put_user'
457 | unsafe_put_user(__s->sig[2], __c->sig[4], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:460:3: note: in expansion of macro 'unsafe_put_user'
460 | unsafe_put_user(__s->sig[1] >> 32, __c->sig[3], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:461:3: note: in expansion of macro 'unsafe_put_user'
461 | unsafe_put_user(__s->sig[1], __c->sig[2], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:284:10: note: in expansion of macro '__put_user_asm2_goto'
284 | case 8: __put_user_asm2_goto(x, ptr, label); break; \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:464:3: note: in expansion of macro 'unsafe_put_user'
464 | unsafe_put_user(__s->sig[0] >> 32, __c->sig[1], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:291:13: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user'
465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
>> arch/powerpc/include/asm/uaccess.h:291:41: warning: initialization of 'int *' from 'compat_sigset_word' {aka 'unsigned int'} makes pointer from integer without a cast [-Wint-conversion]
291 | __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
| ^
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user'
465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:65: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:280:10: note: in definition of macro '__put_user_size_goto'
280 | switch (size) { \
| ^~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user'
465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user'
465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
| ^~~~~~~~~~~~~~~
include/linux/compat.h:465:3: note: in expansion of macro 'unsafe_put_user'
465 | unsafe_put_user(__s->sig[0], __c->sig[0], label); \
| ^~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:90:29: note: in expansion of macro 'unsafe_put_compat_sigset'
90 | #define unsafe_put_sigset_t unsafe_put_compat_sigset
| ^~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/kernel/signal_32.c:833:2: note: in expansion of macro 'unsafe_put_sigset_t'
833 | unsafe_put_sigset_t(&rt_sf->uc.uc_sigmask, oldset, failed);
| ^~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:38: error: invalid type argument of unary '*' (have 'compat_sigset_word' {aka 'unsigned int'})
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~
arch/powerpc/include/asm/uaccess.h:258:10: note: in definition of macro '__put_user_asm_goto'
258 | : "r" (x), "m" (*addr) \
| ^
arch/powerpc/include/asm/uaccess.h:295:2: note: in expansion of macro '__put_user_size_goto'
295 | __put_user_size_goto((x), __pu_addr, (size), label); \
| ^~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:98:2: note: in expansion of macro '__put_user_nocheck_goto'
98 | __put_user_nocheck_goto((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), label)
| ^~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/include/asm/uaccess.h:604:34: note: in expansion of macro '__put_user_goto'
604 | #define unsafe_put_user(x, p, e) __put_user_goto(x, p, e)
vim +291 arch/powerpc/include/asm/uaccess.h
334710b1496af8 Christophe Leroy 2020-04-17 288
334710b1496af8 Christophe Leroy 2020-04-17 289 #define __put_user_nocheck_goto(x, ptr, size, label) \
334710b1496af8 Christophe Leroy 2020-04-17 290 do { \
334710b1496af8 Christophe Leroy 2020-04-17 @291 __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
334710b1496af8 Christophe Leroy 2020-04-17 292 if (!is_kernel_addr((unsigned long)__pu_addr)) \
334710b1496af8 Christophe Leroy 2020-04-17 293 might_fault(); \
334710b1496af8 Christophe Leroy 2020-04-17 294 __chk_user_ptr(ptr); \
334710b1496af8 Christophe Leroy 2020-04-17 295 __put_user_size_goto((x), __pu_addr, (size), label); \
334710b1496af8 Christophe Leroy 2020-04-17 296 } while (0)
334710b1496af8 Christophe Leroy 2020-04-17 297
334710b1496af8 Christophe Leroy 2020-04-17 298
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all(a)lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 70328 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
* Re: [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg()
2020-08-12 12:05 ` Christophe Leroy
(?)
@ 2020-08-12 15:47 ` kernel test robot
-1 siblings, 0 replies; 42+ messages in thread
From: kernel test robot @ 2020-08-12 15:47 UTC (permalink / raw)
To: kbuild-all
[-- Attachment #1: Type: text/plain, Size: 20831 bytes --]
Hi Christophe,
[FYI, it's a private test report for your RFC patch.]
[auto build test ERROR on linus/master]
[also build test ERROR on v5.8 next-20200812]
[cannot apply to powerpc/next]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/0day-ci/linux/commits/Christophe-Leroy/powerpc-Switch-signal-32-to-using-user_access_begin-and-friends/20200812-200934
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git fb893de323e2d39f7a1f6df425703a2edbdf56ea
config: powerpc64-randconfig-r004-20200812 (attached as .config)
compiler: clang version 12.0.0 (https://github.com/llvm/llvm-project 30c1633386e7cfb01c0a54b31ccf4c3a3873e71b)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install powerpc64 cross compiling tool for clang build
# apt-get install binutils-powerpc64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=powerpc64
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
All errors (new ones prefixed by >>):
>> arch/powerpc/kernel/ptrace/ptrace32.c:86:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration]
ret = ptrace_get_reg(child, index, &tmp);
^
arch/powerpc/kernel/ptrace/ptrace32.c:141:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration]
ret = ptrace_get_reg(child, numReg, &tmp2);
^
>> arch/powerpc/kernel/ptrace/ptrace32.c:190:10: error: implicit declaration of function 'ptrace_put_reg' [-Werror,-Wimplicit-function-declaration]
ret = ptrace_put_reg(child, index, data);
^
arch/powerpc/kernel/ptrace/ptrace32.c:230:10: error: implicit declaration of function 'ptrace_get_reg' [-Werror,-Wimplicit-function-declaration]
ret = ptrace_get_reg(child, numReg, &freg);
^
arch/powerpc/kernel/ptrace/ptrace32.c:237:10: error: implicit declaration of function 'ptrace_put_reg' [-Werror,-Wimplicit-function-declaration]
ret = ptrace_put_reg(child, numReg, freg);
^
5 errors generated.
vim +/ptrace_get_reg +86 arch/powerpc/kernel/ptrace/ptrace32.c
9c75a31c3525a1 arch/powerpc/kernel/ptrace32.c Michael Neuling 2008-06-26 35
81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 36 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 37 compat_ulong_t caddr, compat_ulong_t cdata)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 38 {
81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 39 unsigned long addr = caddr;
81e695c026eeda arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-12-20 40 unsigned long data = cdata;
6b9c7ed8483775 arch/powerpc/kernel/ptrace32.c Christoph Hellwig 2006-01-08 41 int ret;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 42
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 43 switch (request) {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 44 /*
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 45 * Read 4 bytes of the other process' storage
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 46 * data is a pointer specifying where the user wants the
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 47 * 4 bytes copied into
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 48 * addr is a pointer in the user's storage that contains an 8 byte
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 49 * address in the other process of the 4 bytes that is to be read
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 50 * (this is run in a 32-bit process looking at a 64-bit process)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 51 * when I and D space are separate, these will need to be fixed.
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 52 */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 53 case PPC_PTRACE_PEEKTEXT_3264:
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 54 case PPC_PTRACE_PEEKDATA_3264: {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 55 u32 tmp;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 56 int copied;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 57 u32 __user * addrOthers;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 58
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 59 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 60
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 61 /* Get the addr in the other process that we want to read */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 62 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 63 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 64
84d77d3f06e7e8 arch/powerpc/kernel/ptrace32.c Eric W. Biederman 2016-11-22 65 copied = ptrace_access_vm(child, (u64)addrOthers, &tmp,
f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 66 sizeof(tmp), FOLL_FORCE);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 67 if (copied != sizeof(tmp))
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 68 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 69 ret = put_user(tmp, (u32 __user *)data);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 70 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 71 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 72
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 73 /* Read a register (specified by ADDR) out of the "user area" */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 74 case PTRACE_PEEKUSR: {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 75 int index;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 76 unsigned long tmp;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 77
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 78 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 79 /* convert to index and check */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 80 index = (unsigned long) addr >> 2;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 81 if ((addr & 3) || (index > PT_FPSCR32))
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 82 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 83
fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 84 CHECK_FULL_REGS(child->thread.regs);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 85 if (index < PT_FPR0) {
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 @86 ret = ptrace_get_reg(child, index, &tmp);
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 87 if (ret)
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 88 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 89 } else {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 90 flush_fp_to_thread(child);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 91 /*
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 92 * the user space code considers the floating point
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 93 * to be an array of unsigned int (32 bits) - the
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 94 * index passed in is based on this assumption.
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 95 */
de79f7b9f6f92e arch/powerpc/kernel/ptrace32.c Paul Mackerras 2013-09-10 96 tmp = ((unsigned int *)child->thread.fp_state.fpr)
9c75a31c3525a1 arch/powerpc/kernel/ptrace32.c Michael Neuling 2008-06-26 97 [FPRINDEX(index)];
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 98 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 99 ret = put_user((unsigned int)tmp, (u32 __user *)data);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 100 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 101 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 102
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 103 /*
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 104 * Read 4 bytes out of the other process' pt_regs area
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 105 * data is a pointer specifying where the user wants the
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 106 * 4 bytes copied into
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 107 * addr is the offset into the other process' pt_regs structure
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 108 * that is to be read
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 109 * (this is run in a 32-bit process looking at a 64-bit process)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 110 */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 111 case PPC_PTRACE_PEEKUSR_3264: {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 112 u32 index;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 113 u32 reg32bits;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 114 u64 tmp;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 115 u32 numReg;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 116 u32 part;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 117
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 118 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 119 /* Determine which register the user wants */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 120 index = (u64)addr >> 2;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 121 numReg = index / 2;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 122 /* Determine which part of the register the user wants */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 123 if (index % 2)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 124 part = 1; /* want the 2nd half of the register (right-most). */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 125 else
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 126 part = 0; /* want the 1st half of the register (left-most). */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 127
912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 128 /* Validate the input - check to see if address is on the wrong boundary
912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 129 * or beyond the end of the user area
912000e73ee8fc arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 130 */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 131 if ((addr & 3) || numReg > PT_FPSCR)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 132 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 133
fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 134 CHECK_FULL_REGS(child->thread.regs);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 135 if (numReg >= PT_FPR0) {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 136 flush_fp_to_thread(child);
bc826666e4252f arch/powerpc/kernel/ptrace32.c Michael Neuling 2009-04-05 137 /* get 64 bit FPR */
de79f7b9f6f92e arch/powerpc/kernel/ptrace32.c Paul Mackerras 2013-09-10 138 tmp = child->thread.fp_state.fpr[numReg - PT_FPR0][0];
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 139 } else { /* register within PT_REGS struct */
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 140 unsigned long tmp2;
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 141 ret = ptrace_get_reg(child, numReg, &tmp2);
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 142 if (ret)
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 143 break;
ee4a3916614829 arch/powerpc/kernel/ptrace32.c Alexey Kardashevskiy 2013-02-14 144 tmp = tmp2;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 145 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 146 reg32bits = ((u32*)&tmp)[part];
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 147 ret = put_user(reg32bits, (u32 __user *)data);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 148 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 149 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 150
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 151 /*
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 152 * Write 4 bytes into the other process' storage
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 153 * data is the 4 bytes that the user wants written
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 154 * addr is a pointer in the user's storage that contains an
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 155 * 8 byte address in the other process where the 4 bytes
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 156 * that is to be written
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 157 * (this is run in a 32-bit process looking at a 64-bit process)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 158 * when I and D space are separate, these will need to be fixed.
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 159 */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 160 case PPC_PTRACE_POKETEXT_3264:
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 161 case PPC_PTRACE_POKEDATA_3264: {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 162 u32 tmp = data;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 163 u32 __user * addrOthers;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 164
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 165 /* Get the addr in the other process that we want to write into */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 166 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 167 if (get_user(addrOthers, (u32 __user * __user *)addr) != 0)
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 168 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 169 ret = 0;
84d77d3f06e7e8 arch/powerpc/kernel/ptrace32.c Eric W. Biederman 2016-11-22 170 if (ptrace_access_vm(child, (u64)addrOthers, &tmp,
f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 171 sizeof(tmp),
f307ab6dcea03f arch/powerpc/kernel/ptrace32.c Lorenzo Stoakes 2016-10-13 172 FOLL_FORCE | FOLL_WRITE) == sizeof(tmp))
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 173 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 174 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 175 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 176 }
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 177
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 178 /* write the word at location addr in the USER area */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 179 case PTRACE_POKEUSR: {
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 180 unsigned long index;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 181
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 182 ret = -EIO;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 183 /* convert to index and check */
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 184 index = (unsigned long) addr >> 2;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 185 if ((addr & 3) || (index > PT_FPSCR32))
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 186 break;
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 187
fabca2c0a461bd arch/powerpc/kernel/ptrace32.c Roland McGrath 2007-09-25 188 CHECK_FULL_REGS(child->thread.regs);
^1da177e4c3f41 arch/ppc64/kernel/ptrace32.c Linus Torvalds 2005-04-16 189 if (index < PT_FPR0) {
865418d8e78b9c arch/powerpc/kernel/ptrace32.c Benjamin Herrenschmidt 2007-06-04 @190 ret = ptrace_put_reg(child, index, data);
---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
[-- Attachment #2: config.gz --]
[-- Type: application/gzip, Size: 27511 bytes --]
^ permalink raw reply [flat|nested] 42+ messages in thread
end of thread, other threads:[~2020-08-12 15:47 UTC | newest]
Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-12 12:05 [RFC PATCH v1 00/19] powerpc: Switch signal 32 to using user_access_begin() and friends Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 01/19] powerpc/signal: Move inline functions in signal.h Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 02/19] powerpc/ptrace: Move declaration of ptrace_get_reg() and ptrace_set_reg() Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 15:47 ` kernel test robot
2020-08-12 12:05 ` [RFC PATCH v1 03/19] powerpc/ptrace: Consolidate reg index calculation Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 04/19] powerpc/ptrace: Create ptrace_get_fpr() and ptrace_put_fpr() Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 05/19] powerpc/signal: Don't manage floating point regs when no FPU Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 06/19] powerpc/32s: Allow deselecting CONFIG_PPC_FPU on mpc832x Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 07/19] powerpc/signal: Move access_ok() out of get_sigframe() Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:05 ` [RFC PATCH v1 08/19] powerpc/signal: Remove get_clean_sp() Christophe Leroy
2020-08-12 12:05 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 09/19] powerpc/signal: Call get_tm_stackpointer() from get_sigframe() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 10/19] powerpc/signal: Refactor bad frame logging Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 11/19] powerpc/signal32: Simplify logging in handle_rt_signal32() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 12/19] powerpc/signal32: Regroup copies in save_user_regs() and save_tm_user_regs() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 13/19] powerpc/signal32: Create 'unsafe' versions of copy_[ck][fpr/vsx]_to_user() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 14/19] powerpc/signal32: Switch save_user_regs() and save_tm_user_regs() to user_access_begin() logic Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 15/19] powerpc/signal32: Switch handle_signal32() " Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 16/19] powerpc/signal32: Switch handle_rt_signal32() " Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 17/19] signal: Add unsafe_put_compat_sigset() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 12:06 ` [RFC PATCH v1 18/19] powerpc/signal32: Add and use unsafe_put_sigset_t() Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
2020-08-12 14:01 ` kernel test robot
2020-08-12 12:06 ` [RFC PATCH v1 19/19] powerpc/signal32: Switch swap_context() to user_access_begin() logic Christophe Leroy
2020-08-12 12:06 ` Christophe Leroy
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.