* [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 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.