Fix the following get_syscall_info test assertion on mips O32: # get_syscall_info.c:218:get_syscall_info:Expected exp_args[5] (3134521044) == info.entry.args[4] (4911432) # get_syscall_info.c:219:get_syscall_info:wait #1: entry stop mismatch Fix the following get_syscall_info test assertion on mips64 O32 and mips64 N32: # get_syscall_info.c:209:get_syscall_info:Expected exp_args[2] (3134324433) == info.entry.args[1] (18446744072548908753) # get_syscall_info.c:210:get_syscall_info:wait #1: entry stop mismatch This makes ptrace/get_syscall_info selftest pass on mips O32, mips64 O32, and mips64 N32. Signed-off-by: Dmitry V. Levin <ldv@xxxxxxxxx> --- Note that I'm not a MIPS expert, so I cannot tell why the get_user() approach doesn't work for O32. Also, during experiments I discovered that regs->pad0 approach works for O32, but why it works remains a mystery. arch/mips/include/asm/syscall.h | 34 ++++++++++----------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/arch/mips/include/asm/syscall.h b/arch/mips/include/asm/syscall.h index ebdf4d910af2..2f85f2d8f754 100644 --- a/arch/mips/include/asm/syscall.h +++ b/arch/mips/include/asm/syscall.h @@ -57,37 +57,23 @@ static inline void mips_syscall_update_nr(struct task_struct *task, static inline void mips_get_syscall_arg(unsigned long *arg, struct task_struct *task, struct pt_regs *regs, unsigned int n) { - unsigned long usp __maybe_unused = regs->regs[29]; - +#ifdef CONFIG_32BIT switch (n) { case 0: case 1: case 2: case 3: *arg = regs->regs[4 + n]; - - return; - -#ifdef CONFIG_32BIT - case 4: case 5: case 6: case 7: - get_user(*arg, (int *)usp + n); return; -#endif - -#ifdef CONFIG_64BIT case 4: case 5: case 6: case 7: -#ifdef CONFIG_MIPS32_O32 - if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) - get_user(*arg, (int *)usp + n); - else -#endif - *arg = regs->regs[4 + n]; - + *arg = regs->pad0[n]; return; -#endif - - default: - BUG(); } - - unreachable(); +#else + *arg = regs->regs[4 + n]; + if ((IS_ENABLED(CONFIG_MIPS32_O32) && + test_tsk_thread_flag(task, TIF_32BIT_REGS)) || + (IS_ENABLED(CONFIG_MIPS32_N32) && + test_tsk_thread_flag(task, TIF_32BIT_ADDR))) + *arg = (unsigned int)*arg; +#endif } static inline long syscall_get_error(struct task_struct *task, -- ldv