qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ 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; 15+ 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] 15+ messages in thread

end of thread, other threads:[~2012-09-16 18:34 UTC | newest]

Thread overview: 15+ 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

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).