From 78bfef72fbf8705f002c5c57cf3f1d3b8e83399e Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Mon, 6 Nov 2017 18:33:26 +0000 Subject: linux-user: Handle rt_sigaction correctly for SPARC MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SPARC is like Alpha in its handling of the rt_sigaction syscall: it takes an extra parameter 'restorer' which needs to be copied into the sa_restorer field of the sigaction struct. The order of the arguments differs slightly between SPARC and Alpha but the implementation is otherwise the same. (Compare the rt_sigaction() functions in arch/sparc/kernel/sys_sparc_64.c and arch/alpha/kernel/signal.c.) Note that this change is somewhat moot until SPARC acquires support for actually delivering RT signals. Reviewed-by: Laurent Vivier Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Peter Maydell Signed-off-by: Riku Voipio --- linux-user/syscall.c | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'linux-user') diff --git a/linux-user/syscall.c b/linux-user/syscall.c index f31b853bb7..11c9116c4a 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8579,8 +8579,16 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, case TARGET_NR_rt_sigaction: { #if defined(TARGET_ALPHA) - struct target_sigaction act, oact, *pact = 0; + /* For Alpha and SPARC this is a 5 argument syscall, with + * a 'restorer' parameter which must be copied into the + * sa_restorer field of the sigaction struct. + * For Alpha that 'restorer' is arg5; for SPARC it is arg4, + * and arg5 is the sigsetsize. + * Alpha also has a separate rt_sigaction struct that it uses + * here; SPARC uses the usual sigaction struct. + */ struct target_rt_sigaction *rt_act; + struct target_sigaction act, oact, *pact = 0; if (arg4 != sizeof(target_sigset_t)) { ret = -TARGET_EINVAL; @@ -8606,18 +8614,29 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, unlock_user_struct(rt_act, arg3, 1); } #else +#ifdef TARGET_SPARC + target_ulong restorer = arg4; + target_ulong sigsetsize = arg5; +#else + target_ulong sigsetsize = arg4; +#endif struct target_sigaction *act; struct target_sigaction *oact; - if (arg4 != sizeof(target_sigset_t)) { + if (sigsetsize != sizeof(target_sigset_t)) { ret = -TARGET_EINVAL; break; } if (arg2) { - if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) + if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) { goto efault; - } else + } +#ifdef TARGET_SPARC + act->sa_restorer = restorer; +#endif + } else { act = NULL; + } if (arg3) { if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) { ret = -TARGET_EFAULT; -- cgit v1.2.3