* [Qemu-devel] [PATCH 0/6] linux-user improvements @ 2012-09-15 20:24 Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 1/6] linux-user: Perform more checks on iovec lists Richard Henderson ` (5 more replies) 0 siblings, 6 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio These patches are available at git://repo.or.cz/qemu/rth.git axp-next and fix several problems detected by the glibc testsuite. r~ Richard Henderson (6): linux-user: Perform more checks on iovec lists linux-user: Implement gethostname alpha-linux-user: Fix sigaltstack structure definition alpha-linux-user: Fix sigaction target-alpha: Fix cpu_alpha_init linux-user: Fix siginfo handling linux-user/alpha/target_signal.h | 7 +- linux-user/qemu.h | 3 + linux-user/signal.c | 81 ++++++++++-------- linux-user/syscall.c | 177 +++++++++++++++++++++++++-------------- linux-user/syscall_defs.h | 2 +- target-alpha/translate.c | 7 +- 6 files changed, 178 insertions(+), 99 deletions(-) -- 1.7.11.4 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 1/6] linux-user: Perform more checks on iovec lists 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 2/6] linux-user: Implement gethostname Richard Henderson ` (4 subsequent siblings) 5 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Validate count between 0 and IOV_MAX. Limit total length of operation in the same way the kernel does. Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/syscall.c | 162 ++++++++++++++++++++++++++++++++------------------- 1 file changed, 102 insertions(+), 60 deletions(-) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 6257a04..ceca04c 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -1744,55 +1744,96 @@ static abi_long do_getsockopt(int sockfd, int level, int optname, return ret; } -/* FIXME - * lock_iovec()/unlock_iovec() have a return code of 0 for success where - * other lock functions have a return code of 0 for failure. - */ -static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, - int count, int copy) +static struct iovec *lock_iovec(int type, abi_ulong target_addr, + int count, int copy) { struct target_iovec *target_vec; - abi_ulong base; + struct iovec *vec; + abi_ulong total_len, max_len; int i; - target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); - if (!target_vec) - return -TARGET_EFAULT; - for(i = 0;i < count; i++) { - base = tswapal(target_vec[i].iov_base); - vec[i].iov_len = tswapal(target_vec[i].iov_len); - if (vec[i].iov_len != 0) { - vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); - /* Don't check lock_user return value. We must call writev even - if a element has invalid base address. */ + if (count == 0) { + errno = 0; + return NULL; + } + if (count > IOV_MAX) { + errno = EINVAL; + return NULL; + } + + vec = calloc(count, sizeof(struct iovec)); + if (vec == NULL) { + errno = ENOMEM; + return NULL; + } + + target_vec = lock_user(VERIFY_READ, target_addr, + count * sizeof(struct target_iovec), 1); + if (target_vec == NULL) { + errno = EFAULT; + goto fail2; + } + + /* ??? If host page size > target page size, this will result in a + value larger than what we can actually support. */ + max_len = 0x7fffffff & TARGET_PAGE_MASK; + total_len = 0; + + for (i = 0; i < count; i++) { + abi_ulong base = tswapal(target_vec[i].iov_base); + abi_long len = tswapal(target_vec[i].iov_len); + + if (len < 0) { + errno = EINVAL; + goto fail; + } else if (len == 0) { + /* Zero length pointer is ignored. */ + vec[i].iov_base = 0; } else { - /* zero length pointer is ignored */ - vec[i].iov_base = NULL; + vec[i].iov_base = lock_user(type, base, len, copy); + if (!vec[i].iov_base) { + errno = EFAULT; + goto fail; + } + if (len > max_len - total_len) { + len = max_len - total_len; + } } + vec[i].iov_len = len; + total_len += len; } - unlock_user (target_vec, target_addr, 0); - return 0; + + unlock_user(target_vec, target_addr, 0); + return vec; + + fail: + free(vec); + fail2: + unlock_user(target_vec, target_addr, 0); + return NULL; } -static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, - int count, int copy) +static void unlock_iovec(struct iovec *vec, abi_ulong target_addr, + int count, int copy) { struct target_iovec *target_vec; - abi_ulong base; int i; - target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); - if (!target_vec) - return -TARGET_EFAULT; - for(i = 0;i < count; i++) { - if (target_vec[i].iov_base) { - base = tswapal(target_vec[i].iov_base); + target_vec = lock_user(VERIFY_READ, target_addr, + count * sizeof(struct target_iovec), 1); + if (target_vec) { + for (i = 0; i < count; i++) { + abi_ulong base = tswapal(target_vec[i].iov_base); + abi_long len = tswapal(target_vec[i].iov_base); + if (len < 0) { + break; + } unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); } + unlock_user(target_vec, target_addr, 0); } - unlock_user (target_vec, target_addr, 0); - return 0; + free(vec); } /* do_socket() Must return target values and target errnos. */ @@ -1888,8 +1929,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, ret = target_to_host_sockaddr(msg.msg_name, tswapal(msgp->msg_name), msg.msg_namelen); if (ret) { - unlock_user_struct(msgp, target_msg, send ? 0 : 1); - return ret; + goto out2; } } else { msg.msg_name = NULL; @@ -1900,9 +1940,13 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, msg.msg_flags = tswap32(msgp->msg_flags); count = tswapal(msgp->msg_iovlen); - vec = alloca(count * sizeof(struct iovec)); target_vec = tswapal(msgp->msg_iov); - lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, vec, target_vec, count, send); + vec = lock_iovec(send ? VERIFY_READ : VERIFY_WRITE, + target_vec, count, send); + if (vec == NULL) { + ret = -host_to_target_errno(errno); + goto out2; + } msg.msg_iovlen = count; msg.msg_iov = vec; @@ -1932,6 +1976,7 @@ static abi_long do_sendrecvmsg(int fd, abi_ulong target_msg, out: unlock_iovec(vec, target_vec, count, !send); +out2: unlock_user_struct(msgp, target_msg, send ? 0 : 1); return ret; } @@ -7186,26 +7231,24 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; case TARGET_NR_readv: { - int count = arg3; - struct iovec *vec; - - vec = alloca(count * sizeof(struct iovec)); - if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) - goto efault; - ret = get_errno(readv(arg1, vec, count)); - unlock_iovec(vec, arg2, count, 1); + struct iovec *vec = lock_iovec(VERIFY_WRITE, arg2, arg3, 0); + if (vec != NULL) { + ret = get_errno(readv(arg1, vec, arg3)); + unlock_iovec(vec, arg2, arg3, 1); + } else { + ret = -host_to_target_errno(errno); + } } break; case TARGET_NR_writev: { - int count = arg3; - struct iovec *vec; - - vec = alloca(count * sizeof(struct iovec)); - if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) - goto efault; - ret = get_errno(writev(arg1, vec, count)); - unlock_iovec(vec, arg2, count, 0); + struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); + if (vec != NULL) { + ret = get_errno(writev(arg1, vec, arg3)); + unlock_iovec(vec, arg2, arg3, 0); + } else { + ret = -host_to_target_errno(errno); + } } break; case TARGET_NR_getsid: @@ -8630,14 +8673,13 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, #ifdef TARGET_NR_vmsplice case TARGET_NR_vmsplice: { - int count = arg3; - struct iovec *vec; - - vec = alloca(count * sizeof(struct iovec)); - if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) - goto efault; - ret = get_errno(vmsplice(arg1, vec, count, arg4)); - unlock_iovec(vec, arg2, count, 0); + struct iovec *vec = lock_iovec(VERIFY_READ, arg2, arg3, 1); + if (vec != NULL) { + ret = get_errno(vmsplice(arg1, vec, arg3, arg4)); + unlock_iovec(vec, arg2, arg3, 0); + } else { + ret = -host_to_target_errno(errno); + } } break; #endif -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 2/6] linux-user: Implement gethostname 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 1/6] linux-user: Perform more checks on iovec lists Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 3/6] alpha-linux-user: Fix sigaltstack structure definition Richard Henderson ` (3 subsequent siblings) 5 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/syscall.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/linux-user/syscall.c b/linux-user/syscall.c index ceca04c..925e579 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -8866,6 +8866,19 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1, break; } #endif +#ifdef TARGET_NR_gethostname + case TARGET_NR_gethostname: + { + char *name = lock_user(VERIFY_WRITE, arg1, arg2, 0); + if (name) { + ret = get_errno(gethostname(name, arg2)); + unlock_user(name, arg1, arg2); + } else { + ret = -TARGET_EFAULT; + } + break; + } +#endif default: unimplemented: gemu_log("qemu: Unsupported syscall: %d\n", num); -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 3/6] alpha-linux-user: Fix sigaltstack structure definition 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 1/6] linux-user: Perform more checks on iovec lists Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 2/6] linux-user: Implement gethostname Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction Richard Henderson ` (2 subsequent siblings) 5 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/alpha/target_signal.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/linux-user/alpha/target_signal.h b/linux-user/alpha/target_signal.h index 94f15f6..d3822da 100644 --- a/linux-user/alpha/target_signal.h +++ b/linux-user/alpha/target_signal.h @@ -6,9 +6,10 @@ /* this struct defines a stack used during syscall handling */ typedef struct target_sigaltstack { - abi_ulong ss_sp; - abi_long ss_flags; - abi_ulong ss_size; + abi_ulong ss_sp; + int32_t ss_flags; + int32_t dummy; + abi_ulong ss_size; } target_stack_t; -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson ` (2 preceding siblings ...) 2012-09-15 20:24 ` [Qemu-devel] [PATCH 3/6] alpha-linux-user: Fix sigaltstack structure definition Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-16 12:58 ` Andreas Färber 2012-09-15 20:24 ` [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 5 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Unconditional bswap replaced by __get_user/__put_user. Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/signal.c | 22 ++++++++-------------- linux-user/syscall_defs.h | 2 +- 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/linux-user/signal.c b/linux-user/signal.c index 7869147..bf2dfb8 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -586,28 +586,22 @@ int do_sigaction(int sig, const struct target_sigaction *act, sig, act, oact); #endif if (oact) { - oact->_sa_handler = tswapal(k->_sa_handler); -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) - oact->sa_flags = bswap32(k->sa_flags); -#else - oact->sa_flags = tswapal(k->sa_flags); -#endif + __put_user(k->_sa_handler, &oact->_sa_handler); + __put_user(k->sa_flags, &oact->sa_flags); #if !defined(TARGET_MIPS) - oact->sa_restorer = tswapal(k->sa_restorer); + __put_user(k->sa_restorer, &oact->sa_restorer); #endif + /* Not swapped. */ oact->sa_mask = k->sa_mask; } if (act) { /* FIXME: This is not threadsafe. */ - k->_sa_handler = tswapal(act->_sa_handler); -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) - k->sa_flags = bswap32(act->sa_flags); -#else - k->sa_flags = tswapal(act->sa_flags); -#endif + __get_user(k->_sa_handler, &act->_sa_handler); + __get_user(k->sa_flags, &act->sa_flags); #if !defined(TARGET_MIPS) - k->sa_restorer = tswapal(act->sa_restorer); + __get_user(k->sa_restorer, &act->sa_restorer); #endif + /* To be swapped in target_to_host_sigset. */ k->sa_mask = act->sa_mask; /* we update the host linux signal state */ diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index a98cbf7..8ca70b9 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -540,7 +540,7 @@ int do_sigaction(int sig, const struct target_sigaction *act, struct target_old_sigaction { abi_ulong _sa_handler; abi_ulong sa_mask; - abi_ulong sa_flags; + int32_t sa_flags; }; struct target_rt_sigaction { -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction 2012-09-15 20:24 ` [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction Richard Henderson @ 2012-09-16 12:58 ` Andreas Färber 2012-09-16 13:21 ` Peter Maydell 2012-09-16 16:54 ` Richard Henderson 0 siblings, 2 replies; 17+ messages in thread From: Andreas Färber @ 2012-09-16 12:58 UTC (permalink / raw) To: Richard Henderson; +Cc: Riku Voipio, qemu-devel, Aurelien Jarno Am 15.09.2012 22:24, schrieb Richard Henderson: > Unconditional bswap replaced by __get_user/__put_user. > > Signed-off-by: Richard Henderson <rth@twiddle.net> Does that still take care of swapping with the correct size? The issue for mips was that some oddballs are 32-bit, others long. Please make sure that mipsn32/mipsn64 (disabled by default due to the unresolved signal warnings) still compile, too. Andreas > --- > linux-user/signal.c | 22 ++++++++-------------- > linux-user/syscall_defs.h | 2 +- > 2 files changed, 9 insertions(+), 15 deletions(-) > > diff --git a/linux-user/signal.c b/linux-user/signal.c > index 7869147..bf2dfb8 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -586,28 +586,22 @@ int do_sigaction(int sig, const struct target_sigaction *act, > sig, act, oact); > #endif > if (oact) { > - oact->_sa_handler = tswapal(k->_sa_handler); > -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) > - oact->sa_flags = bswap32(k->sa_flags); > -#else > - oact->sa_flags = tswapal(k->sa_flags); > -#endif > + __put_user(k->_sa_handler, &oact->_sa_handler); > + __put_user(k->sa_flags, &oact->sa_flags); > #if !defined(TARGET_MIPS) > - oact->sa_restorer = tswapal(k->sa_restorer); > + __put_user(k->sa_restorer, &oact->sa_restorer); > #endif > + /* Not swapped. */ > oact->sa_mask = k->sa_mask; > } > if (act) { > /* FIXME: This is not threadsafe. */ > - k->_sa_handler = tswapal(act->_sa_handler); > -#if defined(TARGET_MIPS) || defined (TARGET_ALPHA) > - k->sa_flags = bswap32(act->sa_flags); > -#else > - k->sa_flags = tswapal(act->sa_flags); > -#endif > + __get_user(k->_sa_handler, &act->_sa_handler); > + __get_user(k->sa_flags, &act->sa_flags); > #if !defined(TARGET_MIPS) > - k->sa_restorer = tswapal(act->sa_restorer); > + __get_user(k->sa_restorer, &act->sa_restorer); > #endif > + /* To be swapped in target_to_host_sigset. */ > k->sa_mask = act->sa_mask; > > /* we update the host linux signal state */ > diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h > index a98cbf7..8ca70b9 100644 > --- a/linux-user/syscall_defs.h > +++ b/linux-user/syscall_defs.h > @@ -540,7 +540,7 @@ int do_sigaction(int sig, const struct target_sigaction *act, > struct target_old_sigaction { > abi_ulong _sa_handler; > abi_ulong sa_mask; > - abi_ulong sa_flags; > + int32_t sa_flags; > }; > > struct target_rt_sigaction { > -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction 2012-09-16 12:58 ` Andreas Färber @ 2012-09-16 13:21 ` Peter Maydell 2012-09-16 16:54 ` Richard Henderson 1 sibling, 0 replies; 17+ messages in thread From: Peter Maydell @ 2012-09-16 13:21 UTC (permalink / raw) To: Andreas Färber Cc: Riku Voipio, qemu-devel, Aurelien Jarno, Richard Henderson On 16 September 2012 13:58, Andreas Färber <afaerber@suse.de> wrote: > Am 15.09.2012 22:24, schrieb Richard Henderson: >> Unconditional bswap replaced by __get_user/__put_user. >> >> Signed-off-by: Richard Henderson <rth@twiddle.net> > > Does that still take care of swapping with the correct size? Yes; they do target-swapping based on the type of pointer you pass them. -- PMM ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction 2012-09-16 12:58 ` Andreas Färber 2012-09-16 13:21 ` Peter Maydell @ 2012-09-16 16:54 ` Richard Henderson 1 sibling, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-16 16:54 UTC (permalink / raw) To: Andreas Färber; +Cc: Riku Voipio, qemu-devel, Aurelien Jarno On 2012-09-16 05:58, Andreas Färber wrote: > Am 15.09.2012 22:24, schrieb Richard Henderson: >> Unconditional bswap replaced by __get_user/__put_user. >> >> Signed-off-by: Richard Henderson <rth@twiddle.net> > > Does that still take care of swapping with the correct size? Yes, and automatically too. > The issue for mips was that some oddballs are 32-bit, others long. > Please make sure that mipsn32/mipsn64 (disabled by default due to the > unresolved signal warnings) still compile, too. Alpha is one of the odd balls. r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson ` (3 preceding siblings ...) 2012-09-15 20:24 ` [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-16 13:01 ` Andreas Färber 2012-09-15 20:24 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 5 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Signed-off-by: Richard Henderson <rth@twiddle.net> --- target-alpha/translate.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/target-alpha/translate.c b/target-alpha/translate.c index 12de6a3..f998f75 100644 --- a/target-alpha/translate.c +++ b/target-alpha/translate.c @@ -3525,6 +3525,7 @@ static const struct cpu_def_t cpu_defs[] = { CPUAlphaState * cpu_alpha_init (const char *cpu_model) { + static bool inited; AlphaCPU *cpu; CPUAlphaState *env; int implver, amask, i, max; @@ -3532,7 +3533,10 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) cpu = ALPHA_CPU(object_new(TYPE_ALPHA_CPU)); env = &cpu->env; - alpha_translate_init(); + if (!inited) { + inited = true; + alpha_translate_init(); + } /* Default to ev67; no reason not to emulate insns by default. */ implver = IMPLVER_21264; @@ -3549,6 +3553,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) } env->implver = implver; env->amask = amask; + env->cpu_model_str = cpu_model; qemu_init_vcpu(env); return env; -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init 2012-09-15 20:24 ` [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init Richard Henderson @ 2012-09-16 13:01 ` Andreas Färber 2012-09-16 16:56 ` Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Andreas Färber @ 2012-09-16 13:01 UTC (permalink / raw) To: Richard Henderson; +Cc: Riku Voipio, qemu-devel Am 15.09.2012 22:24, schrieb Richard Henderson: > Signed-off-by: Richard Henderson <rth@twiddle.net> This is lacking a proper description. I'd be very ashamed if we lost something so obvious during the QOM conversion. So what's the symptoms here? Andreas > --- > target-alpha/translate.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/target-alpha/translate.c b/target-alpha/translate.c > index 12de6a3..f998f75 100644 > --- a/target-alpha/translate.c > +++ b/target-alpha/translate.c > @@ -3525,6 +3525,7 @@ static const struct cpu_def_t cpu_defs[] = { > > CPUAlphaState * cpu_alpha_init (const char *cpu_model) > { > + static bool inited; > AlphaCPU *cpu; > CPUAlphaState *env; > int implver, amask, i, max; > @@ -3532,7 +3533,10 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) > cpu = ALPHA_CPU(object_new(TYPE_ALPHA_CPU)); > env = &cpu->env; > > - alpha_translate_init(); > + if (!inited) { > + inited = true; > + alpha_translate_init(); > + } > > /* Default to ev67; no reason not to emulate insns by default. */ > implver = IMPLVER_21264; > @@ -3549,6 +3553,7 @@ CPUAlphaState * cpu_alpha_init (const char *cpu_model) > } > env->implver = implver; > env->amask = amask; > + env->cpu_model_str = cpu_model; > > qemu_init_vcpu(env); > return env; -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init 2012-09-16 13:01 ` Andreas Färber @ 2012-09-16 16:56 ` Richard Henderson 2012-09-16 18:00 ` Andreas Färber 0 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-09-16 16:56 UTC (permalink / raw) To: Andreas Färber; +Cc: Riku Voipio, qemu-devel On 2012-09-16 06:01, Andreas Färber wrote: > This is lacking a proper description. I'd be very ashamed if we lost > something so obvious during the QOM conversion. So what's the symptoms here? The most important thing here is saving cpu_model_str. The symptom being a SEGV on clone, when cpu_model_str is null. r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init 2012-09-16 16:56 ` Richard Henderson @ 2012-09-16 18:00 ` Andreas Färber 2012-09-16 18:34 ` Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Andreas Färber @ 2012-09-16 18:00 UTC (permalink / raw) To: Richard Henderson; +Cc: Riku Voipio, qemu-devel Am 16.09.2012 18:56, schrieb Richard Henderson: > On 2012-09-16 06:01, Andreas Färber wrote: >> This is lacking a proper description. I'd be very ashamed if we lost >> something so obvious during the QOM conversion. So what's the symptoms here? > > The most important thing here is saving cpu_model_str. > The symptom being a SEGV on clone, when cpu_model_str is null. Ack on that. My understanding is it's not a regression but a bugfix. As for the reentrancy of the translation initialization, I would prefer that being handled in initfn, but we can first introduce it here and move it later. So, if you suggest a wording for the commit message I can apply this as part of my next CPU pull (assuming that'll be earlier than linux-user). I also have an include path fix cpu-qom.h -> cpu.h queued, and cpu_alpha_init() is not yet returning AlphaCPU. Andreas -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init 2012-09-16 18:00 ` Andreas Färber @ 2012-09-16 18:34 ` Richard Henderson 0 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-16 18:34 UTC (permalink / raw) To: Andreas Färber; +Cc: Riku Voipio, qemu-devel On 2012-09-16 11:00, Andreas Färber wrote: > As for the reentrancy of the translation initialization, I would prefer > that being handled in initfn, but we can first introduce it here and > move it later. Sure. I was monkey copying the arm cpu_init for that. > So, if you suggest a wording for the commit message I can apply this as > part of my next CPU pull (assuming that'll be earlier than linux-user). target-alpha: Initialize env->cpu_model_str Save the cpu_model_str so that we have a non-null value when creating a new cpu during clone. Signed-off-by: Richard Henderson <rth@twiddle.net> r~ ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson ` (4 preceding siblings ...) 2012-09-15 20:24 ` [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init Richard Henderson @ 2012-09-15 20:24 ` Richard Henderson 2012-09-16 13:08 ` Andreas Färber 5 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-09-15 20:24 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Compare signal numbers in the proper domain. Convert all of the fields for SIGIO and SIGCHLD. Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/qemu.h | 3 +++ linux-user/signal.c | 59 +++++++++++++++++++++++++++++++++++----------------- linux-user/syscall.c | 2 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 69b27d7..8f871eb 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -219,6 +219,9 @@ unsigned long init_guest_space(unsigned long host_start, #include "qemu-log.h" +/* syscall.c */ +int host_to_target_waitstatus(int status); + /* strace.c */ void print_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, diff --git a/linux-user/signal.c b/linux-user/signal.c index bf2dfb8..9842ba6 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -202,46 +202,67 @@ void target_to_host_old_sigset(sigset_t *sigset, static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) { - int sig; - sig = host_to_target_signal(info->si_signo); + int sig = host_to_target_signal(info->si_signo); tinfo->si_signo = sig; tinfo->si_errno = 0; tinfo->si_code = info->si_code; - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - /* should never come here, but who knows. The information for - the target is irrelevant */ + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + /* Should never come here, but who knows. The information for + the target is irrelevant. */ tinfo->_sifields._sigfault._addr = 0; - } else if (sig == SIGIO) { + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band = info->si_band; tinfo->_sifields._sigpoll._fd = info->si_fd; + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid = info->si_pid; + tinfo->_sifields._sigchld._uid = info->si_uid; + tinfo->_sifields._sigchld._status + = host_to_target_waitstatus(info->si_status); + tinfo->_sifields._sigchld._utime = info->si_utime; + tinfo->_sifields._sigchld._stime = info->si_stime; } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = info->si_pid; tinfo->_sifields._rt._uid = info->si_uid; /* XXX: potential problem if 64 bit */ - tinfo->_sifields._rt._sigval.sival_ptr = - (abi_ulong)(unsigned long)info->si_value.sival_ptr; + tinfo->_sifields._rt._sigval.sival_ptr + = (abi_ulong)(unsigned long)info->si_value.sival_ptr; } } static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) { - int sig; - sig = info->si_signo; + int sig = info->si_signo; tinfo->si_signo = tswap32(sig); tinfo->si_errno = tswap32(info->si_errno); tinfo->si_code = tswap32(info->si_code); - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - tinfo->_sifields._sigfault._addr = - tswapal(info->_sifields._sigfault._addr); - } else if (sig == SIGIO) { - tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + tinfo->_sifields._sigfault._addr + = tswapal(info->_sifields._sigfault._addr); + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band + = tswap32(info->_sifields._sigpoll._band); + tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid + = tswap32(info->_sifields._sigchld._pid); + tinfo->_sifields._sigchld._uid + = tswap32(info->_sifields._sigchld._uid); + tinfo->_sifields._sigchld._status + = tswap32(info->_sifields._sigchld._status); + tinfo->_sifields._sigchld._utime + = tswapal(info->_sifields._sigchld._utime); + tinfo->_sifields._sigchld._stime + = tswapal(info->_sifields._sigchld._stime); } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); - tinfo->_sifields._rt._sigval.sival_ptr = - tswapal(info->_sifields._rt._sigval.sival_ptr); + tinfo->_sifields._rt._sigval.sival_ptr + = tswapal(info->_sifields._rt._sigval.sival_ptr); } } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 925e579..3676c72 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4920,7 +4920,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, /* Map host to target signal numbers for the wait family of syscalls. Assume all other status bits are the same. */ -static int host_to_target_waitstatus(int status) +int host_to_target_waitstatus(int status) { if (WIFSIGNALED(status)) { return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling 2012-09-15 20:24 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson @ 2012-09-16 13:08 ` Andreas Färber 0 siblings, 0 replies; 17+ messages in thread From: Andreas Färber @ 2012-09-16 13:08 UTC (permalink / raw) To: Richard Henderson; +Cc: Riku Voipio, qemu-devel Am 15.09.2012 22:24, schrieb Richard Henderson: > Compare signal numbers in the proper domain. > Convert all of the fields for SIGIO and SIGCHLD. > > Signed-off-by: Richard Henderson <rth@twiddle.net> > --- > linux-user/qemu.h | 3 +++ > linux-user/signal.c | 59 +++++++++++++++++++++++++++++++++++----------------- > linux-user/syscall.c | 2 +- > 3 files changed, 44 insertions(+), 20 deletions(-) > > diff --git a/linux-user/qemu.h b/linux-user/qemu.h > index 69b27d7..8f871eb 100644 > --- a/linux-user/qemu.h > +++ b/linux-user/qemu.h > @@ -219,6 +219,9 @@ unsigned long init_guest_space(unsigned long host_start, > > #include "qemu-log.h" > > +/* syscall.c */ > +int host_to_target_waitstatus(int status); > + > /* strace.c */ > void print_syscall(int num, > abi_long arg1, abi_long arg2, abi_long arg3, > diff --git a/linux-user/signal.c b/linux-user/signal.c > index bf2dfb8..9842ba6 100644 > --- a/linux-user/signal.c > +++ b/linux-user/signal.c > @@ -202,46 +202,67 @@ void target_to_host_old_sigset(sigset_t *sigset, > static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, > const siginfo_t *info) > { > - int sig; > - sig = host_to_target_signal(info->si_signo); > + int sig = host_to_target_signal(info->si_signo); > tinfo->si_signo = sig; > tinfo->si_errno = 0; > tinfo->si_code = info->si_code; > - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || > - sig == SIGBUS || sig == SIGTRAP) { > - /* should never come here, but who knows. The information for > - the target is irrelevant */ > + > + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV > + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { > + /* Should never come here, but who knows. The information for > + the target is irrelevant. */ > tinfo->_sifields._sigfault._addr = 0; > - } else if (sig == SIGIO) { > + } else if (sig == TARGET_SIGIO) { > + tinfo->_sifields._sigpoll._band = info->si_band; > tinfo->_sifields._sigpoll._fd = info->si_fd; > + } else if (sig == TARGET_SIGCHLD) { > + tinfo->_sifields._sigchld._pid = info->si_pid; > + tinfo->_sifields._sigchld._uid = info->si_uid; > + tinfo->_sifields._sigchld._status > + = host_to_target_waitstatus(info->si_status); > + tinfo->_sifields._sigchld._utime = info->si_utime; > + tinfo->_sifields._sigchld._stime = info->si_stime; > } else if (sig >= TARGET_SIGRTMIN) { > tinfo->_sifields._rt._pid = info->si_pid; > tinfo->_sifields._rt._uid = info->si_uid; > /* XXX: potential problem if 64 bit */ > - tinfo->_sifields._rt._sigval.sival_ptr = > - (abi_ulong)(unsigned long)info->si_value.sival_ptr; > + tinfo->_sifields._rt._sigval.sival_ptr > + = (abi_ulong)(unsigned long)info->si_value.sival_ptr; I don't spot any functional change here ... > } > } > > static void tswap_siginfo(target_siginfo_t *tinfo, > const target_siginfo_t *info) > { > - int sig; > - sig = info->si_signo; > + int sig = info->si_signo; > tinfo->si_signo = tswap32(sig); > tinfo->si_errno = tswap32(info->si_errno); > tinfo->si_code = tswap32(info->si_code); > - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || > - sig == SIGBUS || sig == SIGTRAP) { > - tinfo->_sifields._sigfault._addr = > - tswapal(info->_sifields._sigfault._addr); > - } else if (sig == SIGIO) { > - tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); > + > + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV > + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { > + tinfo->_sifields._sigfault._addr > + = tswapal(info->_sifields._sigfault._addr); > + } else if (sig == TARGET_SIGIO) { > + tinfo->_sifields._sigpoll._band > + = tswap32(info->_sifields._sigpoll._band); > + tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); > + } else if (sig == TARGET_SIGCHLD) { > + tinfo->_sifields._sigchld._pid > + = tswap32(info->_sifields._sigchld._pid); > + tinfo->_sifields._sigchld._uid > + = tswap32(info->_sifields._sigchld._uid); > + tinfo->_sifields._sigchld._status > + = tswap32(info->_sifields._sigchld._status); > + tinfo->_sifields._sigchld._utime > + = tswapal(info->_sifields._sigchld._utime); > + tinfo->_sifields._sigchld._stime > + = tswapal(info->_sifields._sigchld._stime); > } else if (sig >= TARGET_SIGRTMIN) { > tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); > tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); > - tinfo->_sifields._rt._sigval.sival_ptr = > - tswapal(info->_sifields._rt._sigval.sival_ptr); > + tinfo->_sifields._rt._sigval.sival_ptr > + = tswapal(info->_sifields._rt._sigval.sival_ptr); ... or here. Does Coding Style mandate this? Would be nice to separate from functional changes then or to leave out. Otherwise no functional issue spotted, using TARGET_SIG* after conversion certainly makes sense. :) Andreas > } > } > > diff --git a/linux-user/syscall.c b/linux-user/syscall.c > index 925e579..3676c72 100644 > --- a/linux-user/syscall.c > +++ b/linux-user/syscall.c > @@ -4920,7 +4920,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, > > /* Map host to target signal numbers for the wait family of syscalls. > Assume all other status bits are the same. */ > -static int host_to_target_waitstatus(int status) > +int host_to_target_waitstatus(int status) > { > if (WIFSIGNALED(status)) { > return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); > -- SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v2 0/6] linux-user improvements @ 2012-09-21 14:17 Richard Henderson 2012-09-21 14:17 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-09-21 14:17 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Patch set available at git://repo.or.cz/qemu/rth.git axp-next Changes v1-v2: * Fix cpu_alpha_init patch only stores cpu_model. The inited thing is already done inside alpha_translate_init. r~ Richard Henderson (6): linux-user: Perform more checks on iovec lists linux-user: Implement gethostname alpha-linux-user: Fix sigaltstack structure definition alpha-linux-user: Fix sigaction target-alpha: Fix cpu_alpha_init linux-user: Fix siginfo handling linux-user/alpha/target_signal.h | 7 +- linux-user/qemu.h | 3 + linux-user/signal.c | 81 ++++++++++-------- linux-user/syscall.c | 177 +++++++++++++++++++++++++-------------- linux-user/syscall_defs.h | 2 +- target-alpha/translate.c | 1 + 6 files changed, 173 insertions(+), 98 deletions(-) -- 1.7.11.4 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling 2012-09-21 14:17 [Qemu-devel] [PATCH v2 0/6] linux-user improvements Richard Henderson @ 2012-09-21 14:17 ` Richard Henderson 0 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-09-21 14:17 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Compare signal numbers in the proper domain. Convert all of the fields for SIGIO and SIGCHLD. Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/qemu.h | 3 +++ linux-user/signal.c | 59 +++++++++++++++++++++++++++++++++++----------------- linux-user/syscall.c | 2 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 69b27d7..8f871eb 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -219,6 +219,9 @@ unsigned long init_guest_space(unsigned long host_start, #include "qemu-log.h" +/* syscall.c */ +int host_to_target_waitstatus(int status); + /* strace.c */ void print_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, diff --git a/linux-user/signal.c b/linux-user/signal.c index bf2dfb8..9842ba6 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -202,46 +202,67 @@ void target_to_host_old_sigset(sigset_t *sigset, static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) { - int sig; - sig = host_to_target_signal(info->si_signo); + int sig = host_to_target_signal(info->si_signo); tinfo->si_signo = sig; tinfo->si_errno = 0; tinfo->si_code = info->si_code; - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - /* should never come here, but who knows. The information for - the target is irrelevant */ + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + /* Should never come here, but who knows. The information for + the target is irrelevant. */ tinfo->_sifields._sigfault._addr = 0; - } else if (sig == SIGIO) { + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band = info->si_band; tinfo->_sifields._sigpoll._fd = info->si_fd; + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid = info->si_pid; + tinfo->_sifields._sigchld._uid = info->si_uid; + tinfo->_sifields._sigchld._status + = host_to_target_waitstatus(info->si_status); + tinfo->_sifields._sigchld._utime = info->si_utime; + tinfo->_sifields._sigchld._stime = info->si_stime; } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = info->si_pid; tinfo->_sifields._rt._uid = info->si_uid; /* XXX: potential problem if 64 bit */ - tinfo->_sifields._rt._sigval.sival_ptr = - (abi_ulong)(unsigned long)info->si_value.sival_ptr; + tinfo->_sifields._rt._sigval.sival_ptr + = (abi_ulong)(unsigned long)info->si_value.sival_ptr; } } static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) { - int sig; - sig = info->si_signo; + int sig = info->si_signo; tinfo->si_signo = tswap32(sig); tinfo->si_errno = tswap32(info->si_errno); tinfo->si_code = tswap32(info->si_code); - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - tinfo->_sifields._sigfault._addr = - tswapal(info->_sifields._sigfault._addr); - } else if (sig == SIGIO) { - tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + tinfo->_sifields._sigfault._addr + = tswapal(info->_sifields._sigfault._addr); + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band + = tswap32(info->_sifields._sigpoll._band); + tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid + = tswap32(info->_sifields._sigchld._pid); + tinfo->_sifields._sigchld._uid + = tswap32(info->_sifields._sigchld._uid); + tinfo->_sifields._sigchld._status + = tswap32(info->_sifields._sigchld._status); + tinfo->_sifields._sigchld._utime + = tswapal(info->_sifields._sigchld._utime); + tinfo->_sifields._sigchld._stime + = tswapal(info->_sifields._sigchld._stime); } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); - tinfo->_sifields._rt._sigval.sival_ptr = - tswapal(info->_sifields._rt._sigval.sival_ptr); + tinfo->_sifields._rt._sigval.sival_ptr + = tswapal(info->_sifields._rt._sigval.sival_ptr); } } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 925e579..3676c72 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4920,7 +4920,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, /* Map host to target signal numbers for the wait family of syscalls. Assume all other status bits are the same. */ -static int host_to_target_waitstatus(int status) +int host_to_target_waitstatus(int status) { if (WIFSIGNALED(status)) { return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH v3 0/6] linux-user improvements @ 2012-10-11 19:22 Richard Henderson 2012-10-11 19:22 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 0 siblings, 1 reply; 17+ messages in thread From: Richard Henderson @ 2012-10-11 19:22 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Changes v2-v3: * Add patch 4, rewriting __get_user. Patch 5 triggers warnings about "assignment of read-only variable" without it. * Rebase vs master, which includes the cpu_alpha_init fix. Patch set available at git://repo.or.cz/qemu/rth.git axp-next r~ Richard Henderson (6): linux-user: Perform more checks on iovec lists linux-user: Implement gethostname alpha-linux-user: Fix sigaltstack structure definition linux-user: Rewrite __get_user/__put_user with __builtin_choose_expr alpha-linux-user: Fix sigaction linux-user: Fix siginfo handling linux-user/alpha/target_signal.h | 7 +- linux-user/qemu.h | 53 +++++------- linux-user/signal.c | 81 ++++++++++-------- linux-user/syscall.c | 177 +++++++++++++++++++++++++-------------- linux-user/syscall_defs.h | 2 +- 5 files changed, 192 insertions(+), 128 deletions(-) -- 1.7.11.4 ^ permalink raw reply [flat|nested] 17+ messages in thread
* [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling 2012-10-11 19:22 [Qemu-devel] [PATCH v3 0/6] linux-user improvements Richard Henderson @ 2012-10-11 19:22 ` Richard Henderson 0 siblings, 0 replies; 17+ messages in thread From: Richard Henderson @ 2012-10-11 19:22 UTC (permalink / raw) To: qemu-devel; +Cc: Riku Voipio Compare signal numbers in the proper domain. Convert all of the fields for SIGIO and SIGCHLD. Signed-off-by: Richard Henderson <rth@twiddle.net> --- linux-user/qemu.h | 3 +++ linux-user/signal.c | 59 +++++++++++++++++++++++++++++++++++----------------- linux-user/syscall.c | 2 +- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/linux-user/qemu.h b/linux-user/qemu.h index 39b2c9c..35c16d1 100644 --- a/linux-user/qemu.h +++ b/linux-user/qemu.h @@ -219,6 +219,9 @@ unsigned long init_guest_space(unsigned long host_start, #include "qemu-log.h" +/* syscall.c */ +int host_to_target_waitstatus(int status); + /* strace.c */ void print_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, diff --git a/linux-user/signal.c b/linux-user/signal.c index 1969877..407619a 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -202,46 +202,67 @@ void target_to_host_old_sigset(sigset_t *sigset, static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, const siginfo_t *info) { - int sig; - sig = host_to_target_signal(info->si_signo); + int sig = host_to_target_signal(info->si_signo); tinfo->si_signo = sig; tinfo->si_errno = 0; tinfo->si_code = info->si_code; - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - /* should never come here, but who knows. The information for - the target is irrelevant */ + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + /* Should never come here, but who knows. The information for + the target is irrelevant. */ tinfo->_sifields._sigfault._addr = 0; - } else if (sig == SIGIO) { + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band = info->si_band; tinfo->_sifields._sigpoll._fd = info->si_fd; + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid = info->si_pid; + tinfo->_sifields._sigchld._uid = info->si_uid; + tinfo->_sifields._sigchld._status + = host_to_target_waitstatus(info->si_status); + tinfo->_sifields._sigchld._utime = info->si_utime; + tinfo->_sifields._sigchld._stime = info->si_stime; } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = info->si_pid; tinfo->_sifields._rt._uid = info->si_uid; /* XXX: potential problem if 64 bit */ - tinfo->_sifields._rt._sigval.sival_ptr = - (abi_ulong)(unsigned long)info->si_value.sival_ptr; + tinfo->_sifields._rt._sigval.sival_ptr + = (abi_ulong)(unsigned long)info->si_value.sival_ptr; } } static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) { - int sig; - sig = info->si_signo; + int sig = info->si_signo; tinfo->si_signo = tswap32(sig); tinfo->si_errno = tswap32(info->si_errno); tinfo->si_code = tswap32(info->si_code); - if (sig == SIGILL || sig == SIGFPE || sig == SIGSEGV || - sig == SIGBUS || sig == SIGTRAP) { - tinfo->_sifields._sigfault._addr = - tswapal(info->_sifields._sigfault._addr); - } else if (sig == SIGIO) { - tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + + if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV + || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) { + tinfo->_sifields._sigfault._addr + = tswapal(info->_sifields._sigfault._addr); + } else if (sig == TARGET_SIGIO) { + tinfo->_sifields._sigpoll._band + = tswap32(info->_sifields._sigpoll._band); + tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd); + } else if (sig == TARGET_SIGCHLD) { + tinfo->_sifields._sigchld._pid + = tswap32(info->_sifields._sigchld._pid); + tinfo->_sifields._sigchld._uid + = tswap32(info->_sifields._sigchld._uid); + tinfo->_sifields._sigchld._status + = tswap32(info->_sifields._sigchld._status); + tinfo->_sifields._sigchld._utime + = tswapal(info->_sifields._sigchld._utime); + tinfo->_sifields._sigchld._stime + = tswapal(info->_sifields._sigchld._stime); } else if (sig >= TARGET_SIGRTMIN) { tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid); tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid); - tinfo->_sifields._rt._sigval.sival_ptr = - tswapal(info->_sifields._rt._sigval.sival_ptr); + tinfo->_sifields._rt._sigval.sival_ptr + = tswapal(info->_sifields._rt._sigval.sival_ptr); } } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index 462d11b..612683f 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -4918,7 +4918,7 @@ static int do_futex(target_ulong uaddr, int op, int val, target_ulong timeout, /* Map host to target signal numbers for the wait family of syscalls. Assume all other status bits are the same. */ -static int host_to_target_waitstatus(int status) +int host_to_target_waitstatus(int status) { if (WIFSIGNALED(status)) { return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); -- 1.7.11.4 ^ permalink raw reply related [flat|nested] 17+ messages in thread
end of thread, other threads:[~2012-10-11 19:22 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-09-15 20:24 [Qemu-devel] [PATCH 0/6] linux-user improvements Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 1/6] linux-user: Perform more checks on iovec lists Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 2/6] linux-user: Implement gethostname Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 3/6] alpha-linux-user: Fix sigaltstack structure definition Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 4/6] alpha-linux-user: Fix sigaction Richard Henderson 2012-09-16 12:58 ` Andreas Färber 2012-09-16 13:21 ` Peter Maydell 2012-09-16 16:54 ` Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 5/6] target-alpha: Fix cpu_alpha_init Richard Henderson 2012-09-16 13:01 ` Andreas Färber 2012-09-16 16:56 ` Richard Henderson 2012-09-16 18:00 ` Andreas Färber 2012-09-16 18:34 ` Richard Henderson 2012-09-15 20:24 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 2012-09-16 13:08 ` Andreas Färber -- strict thread matches above, loose matches on Subject: below -- 2012-09-21 14:17 [Qemu-devel] [PATCH v2 0/6] linux-user improvements Richard Henderson 2012-09-21 14:17 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson 2012-10-11 19:22 [Qemu-devel] [PATCH v3 0/6] linux-user improvements Richard Henderson 2012-10-11 19:22 ` [Qemu-devel] [PATCH 6/6] linux-user: Fix siginfo handling Richard Henderson
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).